def configure_buffers(self, c): """Configure the data buffers.""" samplesPerRecord = self.samples_per_record(c) numberOfRecords = self.number_of_records(c) if 'channelIDs' not in c: self.select_all_channels(c) numberOfChannels = len(c['channelIDs']) # Reinitialize buffers only when the size of the buffers # actually should be changed. if 'reshapedRecordsBuffer' in c and \ np.shape(c['reshapedRecordsBuffer']) == \ (numberOfRecords, numberOfChannels, samplesPerRecord): return preTriggerSamples = c['preTriggerSamples'] bytesPerSample = c['bytesPerSample'] bytesPerRecord = c['bytesPerRecord'] recordsPerBuffer = c['recordsPerBuffer'] numberOfBuffers = c['numberOfBuffers'] bytesPerBuffer = bytesPerRecord * recordsPerBuffer * numberOfChannels # Allocate DMA buffers. sampleType = ctypes.c_uint8 if bytesPerSample > 1: sampleType = ctypes.c_uint16 c['buffers'] = [] for i in range(numberOfBuffers): c['buffers'].append(ats.DMABuffer(sampleType, bytesPerBuffer)) # Current implementation is NPT Mode = No Pre Trigger Samples. self.set_record_size(c, preTriggerSamples, samplesPerRecord) # Must allocate these first, otherwise takes up too much time # during the acquisition. samples = numberOfChannels * numberOfRecords * samplesPerRecord if bytesPerSample == 1: c['recordsBuffer'] = np.empty(samples, dtype=np.uint8) elif bytesPerSample == 2: c['recordsBuffer'] = np.empty(samples, dtype=np.uint16) else: c['recordsBuffer'] = np.empty(samples, dtype=np.uint32) c['reshapedRecordsBuffer'] = np.empty( (numberOfRecords, numberOfChannels, samplesPerRecord), dtype=np.float32) c['iqBuffers'] = np.empty((numberOfRecords, 2), dtype=np.float32)
def AcquireData(boards): # TODO: Select the total acquisition length in seconds acquisitionLength_sec = 1. # TODO: Select the number of samples in each DMA buffer samplesPerBuffer = 204800 # TODO: Select the active channels. channels = ats.CHANNEL_A channelCount = 0 for c in ats.channels: channelCount += (c & channels == c) # TODO: Should data be saved to file? saveData = False dataFile = None if saveData: dataFile = open(os.path.join(os.path.dirname(__file__), "data.bin"), 'wb') # Make sure that boards[0] is the system's master if boards[0].boardId != 1: raise ValueError("The first board passed should be the master.") for board in boards: if board.systemId != boards[0].systemId: raise ValueError("All the boards should be of the same system.") # Compute the number of bytes per record and per buffer memorySize_samples, bitsPerSample = boards[0].getChannelInfo() bytesPerSample = (bitsPerSample.value + 7) // 8 bytesPerBuffer = bytesPerSample * samplesPerBuffer * channelCount # Calculate the number of buffers in the acquisition samplesPerAcquisition = int(samplesPerSec * acquisitionLength_sec + 0.5) buffersPerAcquisition = ((samplesPerAcquisition + samplesPerBuffer - 1) // samplesPerBuffer) # TODO: Select number of DMA buffers to allocate bufferCount = 4 buffers = [] for b in range(len(boards)): # Allocate DMA buffers sample_type = ctypes.c_uint8 if bytesPerSample > 1: sample_type = ctypes.c_uint16 buffers.append([]) for i in range(bufferCount): buffers[b].append( ats.DMABuffer(board.handle, sample_type, bytesPerBuffer)) boards[b].beforeAsyncRead( channels, 0, # Must be 0 samplesPerBuffer, 1, # Must be 1 0x7FFFFFFF, # Ignored ats.ADMA_EXTERNAL_STARTCAPTURE | ats.ADMA_CONTINUOUS_MODE | ats.ADMA_FIFO_ONLY_STREAMING) # Post DMA buffers to board for buffer in buffers[b]: boards[b].postAsyncBuffer(buffer.addr, buffer.size_bytes) start = time.clock() # Keep track of when acquisition started try: boards[0].startCapture() # Start the acquisition buffersPerAcquisitionAllBoards = len(boards) * buffersPerAcquisition print("Capturing {} buffers. Press <enter> to abort".format( buffersPerAcquisitionAllBoards)) buffersCompletedPerBoard = 0 buffersCompletedAllBoards = 0 bytesTransferredAllBoards = 0 while (buffersCompletedPerBoard < buffersPerAcquisition and not ats.enter_pressed()): for b in range(len(boards)): # Wait for the buffer at the head of the list of available # buffers to be filled by the board. buffer = buffers[b][buffersCompletedPerBoard % len(buffers[b])] boards[b].waitAsyncBufferComplete(buffer.addr, timeout_ms=5000) buffersCompletedAllBoards += 1 bytesTransferredAllBoards += buffer.size_bytes # TODO: Process sample data in this buffer. Data is available # as a NumPy array at buffer.buffer # NOTE: # # While you are processing this buffer, the board is already # filling the next available buffer(s). # # You MUST finish processing this buffer and post it back to the # board before the board fills all of its available DMA buffers # and on-board memory. # # Samples are arranged in the buffer as follows: # S0A, S0B, ..., S1A, S1B, ... # with SXY the sample number X of channel Y. # # A 12-bit sample code is stored in the most significant bits of # each 16-bit sample value. # # Sample codes are unsigned by default. As a result: # - 0x0000 represents a negative full scale signal. # - 0x8000 represents a ~0V signal. # - 0xFFFF represents a positive full scale signal. # Optionaly save data to file if dataFile: buffer.buffer.tofile(dataFile) # Add the buffer to the end of the list of available buffers. boards[b].postAsyncBuffer(buffer.addr, buffer.size_bytes) buffersCompletedPerBoard += 1 finally: board.abortAsyncRead() # Compute the total transfer time, and display performance information. transferTime_sec = time.clock() - start print("Capture completed in %f sec" % transferTime_sec) buffersPerSec = 0 bytesPerSec = 0 if transferTime_sec > 0: buffersPerSec = buffersCompletedAllBoards / transferTime_sec bytesPerSec = bytesTransferredAllBoards / transferTime_sec print("Captured %d buffers (%f buffers per sec)" % (buffersCompletedAllBoards, buffersPerSec)) print("Transferred %d bytes (%f bytes per sec)" % (bytesTransferredAllBoards, bytesPerSec))
def AcquireData(boards, acquireData): # No pre-trigger samples in NPT mode preTriggerSamples = 0 # TODO: Select the number of samples per record. postTriggerSamples = 2048 # TODO: Select the number of records per DMA buffer. recordsPerBuffer = 10 # TODO: Select the number of buffers per acquisition. buffersPerAcquisition = 10 # TODO: Select the active channels. channels = ats.CHANNEL_A | ats.CHANNEL_B channelCount = 0 for c in ats.channels: channelCount += (c & channels == c) # TODO: Should data be saved to file? saveData = false dataFile = None if saveData: dataFile = open(os.path.join(os.path.dirname(__file__), "data.bin"), 'w') # Make sure that boards[0] is the system's master if boards[0].boardId != 1: raise ValueError("The first board passed should be the master.") for board in boards: if board.systemId != boards[0].systemId: raise ValueError("All the boards should be of the same system.") # Compute the number of bytes per record and per buffer memorySize_samples, bitsPerSample = boards[0].getChannelInfo() bytesPerSample = (bitsPerSample.value + 7) // 8 samplesPerRecord = preTriggerSamples + postTriggerSamples bytesPerRecord = bytesPerSample * samplesPerRecord bytesPerBuffer = bytesPerRecord * recordsPerBuffer * channelCount # TODO: Select number of DMA buffers to allocate bufferCount = 4 buffers = [] for b in range(len(boards)): # Allocate DMA buffers buffers.append([]) for i in range(bufferCount): buffers[b].append(ats.DMABuffer(bytesPerSample, bytesPerBuffer)) # Set the record size boards[b].setRecordSize(preTriggerSamples, postTriggerSamples) recordsPerAcquisition = recordsPerBuffer * buffersPerAcquisition # Configure the board to make an NPT AutoDMA acquisition boards[b].beforeAsyncRead( channels, -preTriggerSamples, samplesPerRecord, recordsPerBuffer, recordsPerAcquisition, ats.ADMA_EXTERNAL_STARTCAPTURE | ats.ADMA_NPT) # Post DMA buffers to board for buffer in buffers[b]: boards[b].postAsyncBuffer(buffer.addr, buffer.size_bytes) start = time.clock() # Keep track of when acquisition started boards[0].startCapture() # Start the acquisition buffersPerAcquisitionAllBoards = len(boards) * buffersPerAcquisition print(("Capturing %d buffers. Press any key to abort" % buffersPerAcquisitionAllBoards)) buffersCompletedPerBoard = 0 buffersCompletedAllBoards = 0 bytesTransferredAllBoards = 0 while buffersCompletedPerBoard < buffersPerAcquisition and not waitBar.hasUserCancelled( ): for b in range(len(boards)): # Wait for the buffer at the head of the list of available # buffers to be filled by the board. buffer = buffers[b][buffersCompletedPerBoard % len(buffers[b])] boards[b].waitAsyncBufferComplete(buffer.addr, timeout_ms=5000) buffersCompletedAllBoards += 1 bytesTransferredAllBoards += buffer.size_bytes # TODO: Process sample data in this buffer. Data is available # as a NumPy array at buffer.buffer # NOTE: # # While you are processing this buffer, the board is already # filling the next available buffer(s). # # You MUST finish processing this buffer and post it back to the # board before the board fills all of its available DMA buffers # and on-board memory. # # Samples are arranged in the buffer as follows: S0A, S0B, ..., S1A, S1B, ... # with SXY the sample number X of channel Y. # # A 12-bit sample code is stored in the most significant bits of # in each 16-bit sample value. # # Sample codes are unsigned by default. As a result: # - a sample code of 0x0000 represents a negative full scale input signal. # - a sample code of 0x8000 represents a ~0V signal. # - a sample code of 0xFFFF represents a positive full scale input signal. # Optionaly save data to file if dataFile: buffer.buffer.tofile(dataFile) # Add the buffer to the end of the list of available buffers. boards[b].postAsyncBuffer(buffer.addr, buffer.size_bytes) buffersCompletedPerBoard += 1 # Update progress bar waitBar.setProgress(buffersCompletedPerBoard / buffersPerAcquisition) # Compute the total transfer time, and display performance information. transferTime_sec = time.clock() - start print(("Capture completed in %f sec" % transferTime_sec)) buffersPerSec = 0 bytesPerSec = 0 recordsPerSec = 0 if transferTime_sec > 0: buffersPerSec = buffersCompletedAllBoards / transferTime_sec bytesPerSec = bytesTransferredAllBoards / transferTime_sec recordsPerSec = recordsPerBuffer * buffersCompletedAllBoards / transferTime_sec print(("Captured %d buffers (%f buffers per sec)" % (buffersCompletedAllBoards, buffersPerSec))) print(("Captured %d records (%f records per sec)" % (recordsPerBuffer * buffersCompletedAllBoards, recordsPerSec))) print(("Transferred %d bytes (%f bytes per sec)" % (bytesTransferredAllBoards, bytesPerSec))) # Abort transfer. board.abortAsyncRead()
def AcquireData(board, acquireData): # TODO: Select the total acquisition length in seconds acquisitionLength_sec = 1. # TODO: Select the number of samples in each DMA buffer samplesPerBuffer = 204800 # TODO: Select the active channels. channels = ats.CHANNEL_A | ats.CHANNEL_B channelCount = 0 for c in ats.channels: channelCount += (c & channels == c) # TODO: Should data be saved to file? saveData = false dataFile = None if saveData: dataFile = open(os.path.join(os.path.dirname(__file__), "data.bin"), 'w') # Compute the number of bytes per record and per buffer memorySize_samples, bitsPerSample = board.getChannelInfo() bytesPerSample = (bitsPerSample.value + 7) // 8 bytesPerBuffer = bytesPerSample * samplesPerBuffer * channelCount # Calculate the number of buffers in the acquisition samplesPerAcquisition = int(samplesPerSec * acquisitionLength_sec + 0.5) buffersPerAcquisition = (samplesPerAcquisition + samplesPerBuffer - 1) // samplesPerBuffer # TODO: Select number of DMA buffers to allocate bufferCount = 4 # Allocate DMA buffers buffers = [] for i in range(bufferCount): buffers.append(ats.DMABuffer(bytesPerSample, bytesPerBuffer)) board.beforeAsyncRead( channels, 0, # Must be 0 samplesPerBuffer, 1, # Must be 1 0x7FFFFFFF, # Ignored ats.ADMA_EXTERNAL_STARTCAPTURE | ats.ADMA_TRIGGERED_STREAMING) # Post DMA buffers to board for buffer in buffers: board.postAsyncBuffer(buffer.addr, buffer.size_bytes) start = time.clock() # Keep track of when acquisition started board.startCapture() # Start the acquisition print(("Capturing %d buffers. Press any key to abort" % buffersPerAcquisition)) buffersCompleted = 0 bytesTransferred = 0 while buffersCompleted < buffersPerAcquisition and not waitBar.hasUserCancelled( ): # Wait for the buffer at the head of the list of available # buffers to be filled by the board. buffer = buffers[buffersCompleted % len(buffers)] board.waitAsyncBufferComplete(buffer.addr, timeout_ms=5000) buffersCompleted += 1 bytesTransferred += buffer.size_bytes # TODO: Process sample data in this buffer. Data is available # as a NumPy array at buffer.buffer # NOTE: # # While you are processing this buffer, the board is already # filling the next available buffer(s). # # You MUST finish processing this buffer and post it back to the # board before the board fills all of its available DMA buffers # and on-board memory. # # Samples are arranged in the buffer as follows: S0A, S0B, ..., S1A, S1B, ... # with SXY the sample number X of channel Y. # # # Sample codes are unsigned by default. As a result: # - a sample code of 0x0000 represents a negative full scale input signal. # - a sample code of 0x8000 represents a ~0V signal. # - a sample code of 0xFFFF represents a positive full scale input signal. # Optionaly save data to file if dataFile: buffer.buffer.tofile(dataFile) # Update progress bar waitBar.setProgress(buffersCompleted / buffersPerAcquisition) # Add the buffer to the end of the list of available buffers. board.postAsyncBuffer(buffer.addr, buffer.size_bytes) # Compute the total transfer time, and display performance information. transferTime_sec = time.clock() - start print(("Capture completed in %f sec" % transferTime_sec)) buffersPerSec = 0 bytesPerSec = 0 if transferTime_sec > 0: buffersPerSec = buffersCompleted / transferTime_sec bytesPerSec = bytesTransferred / transferTime_sec print(("Captured %d buffers (%f buffers per sec)" % (buffersCompleted, buffersPerSec))) print(("Transferred %d bytes (%f bytes per sec)" % (bytesTransferred, bytesPerSec))) # Abort transfer. board.abortAsyncRead()
def prepare_acquisition(self, board, parameters): """ Prepare the DMA buffers for the board. Return a list of buffers """ samplesPerSec = parameters['samplerate'] * 1e6 # No pre-trigger samples in NPT mode preTriggerSamples = 0 postTriggerSamples = parameters['samplesPerRecord'] # Select the number of records per DMA buffer. recordsPerBuffer = parameters['records_per_buffer'] # Select the number of buffers per acquisition. buffersPerAcquisition = parameters['buffers_per_acquisition'] # get the info about the FFT module if parameters['mode'] == 'FFT': dsp_array = board.dspGetModules() fft_module = dsp_array[0] dsp_info = fft_module.dspGetInfo() # define the channel mask according to the working mode of the digitizer if parameters['mode'] == 'FFT': # Only channel A is used when on-FPGA FFT is active channels = ats.CHANNEL_A channelCount = 1 elif parameters['mode'] == 'CHANNEL_AB': # For two active channels channels = ats.CHANNEL_A | ats.CHANNEL_B channelCount = 2 elif parameters['mode'] == 'CHANNEL_A': # If channel A only is active channels = ats.CHANNEL_A channelCount = 1 elif parameters['mode'] == 'CHANNEL_B': # If channel B only is active channels = ats.CHANNEL_B channelCount = 1 else: raise ValueError('mode of the digitizer must be "CHANNEL_AB" or \ "CHANNEL_A" or "CHANNEL_B" or "FFT"') # Compute the number of samples per record samplesPerRecord = preTriggerSamples + postTriggerSamples #Configure the FFT module if parameters['mode'] == 'FFT': fftLength_samples = 1 while fftLength_samples < samplesPerRecord: fftLength_samples *= 2 # Sets the real part of the FFT windowing fft_window_real = ats.dspGenerateWindowFunction( windowType, samplesPerRecord, fftLength_samples - samplesPerRecord) # According to the documentation, the imaginary part of the FFT windowing should be filled with zeros fft_window_imag = ats.dspGenerateWindowFunction( windowType, 0, fftLength_samples - samplesPerRecord) # Configures the FFT window fft_module.fftSetWindowFunction( samplesPerRecord, ctypes.c_void_p(fft_window_real.ctypes.data), ctypes.c_void_p(fft_window_imag.ctypes.data)) # Compute the number of bytes per record and per buffer # For now the output of the output of the on-FPGA FFT is set to 'FFT_OUTPUT_FORMAT_U16_AMP2', # thus the number of bytes per sample is 2 bytesPerSample = 2 # Computes the number of bytes per record according to the settings of the on-FPGA FFT bytesPerRecord = fft_module.fftSetup( channels, samplesPerRecord, fftLength_samples, ats.FFT_OUTPUT_FORMAT_U16_AMP2, ats.FFT_FOOTER_NONE, 0) bytesPerBuffer = bytesPerRecord * recordsPerBuffer # change made by Remy the 2018/06/21 parameters['samplesPerRecord'] = int(bytesPerRecord / bytesPerSample) # before it was: # parameters['samplesPerRecord'] = bytesPerRecord/bytesPerSample else: # Compute the number of bytes per record and per buffer memorySize_samples, bitsPerSample = board.getChannelInfo() bytesPerSample = (bitsPerSample.value + 7) // 8 bytesPerRecord = bytesPerSample * samplesPerRecord bytesPerBuffer = bytesPerRecord * recordsPerBuffer * channelCount # change made by Remy the 2018/06/21 parameters['samplesPerRecord'] = int(bytesPerRecord / bytesPerSample) # before it was: # parameters['samplesPerRecord'] = bytesPerRecord/bytesPerSample # Select number of DMA buffers to allocate bufferCount = parameters['nb_buffer_allocated'] # Modified per Etienne. # Alazar gave bytesPerSample > 8 but this condition seemed strange to # me considering the previous code bytesPerSample = (bitsPerSample.value + 7) // 8 # Allocate DMA buffers sample_type = ctypes.c_uint8 if bytesPerSample > 1: sample_type = ctypes.c_uint16 buffers = [] for i in range(bufferCount): buffers.append(ats.DMABuffer(sample_type, bytesPerBuffer)) board.setRecordSize(preTriggerSamples, postTriggerSamples) # Prepate the board to work in the asynchroneous mode of acquisition recordsPerAcquisition = recordsPerBuffer * buffersPerAcquisition if parameters['mode'] == 'FFT': admaFlags = ats.ADMA_EXTERNAL_STARTCAPTURE | ats.ADMA_NPT | ats.ADMA_DSP board.beforeAsyncRead(channels, 0, bytesPerRecord, recordsPerBuffer, 0x7FFFFFFF, admaFlags) elif parameters['mode'] == 'CHANNEL_AB': board.beforeAsyncRead(channels, -preTriggerSamples, samplesPerRecord, recordsPerBuffer, recordsPerAcquisition, ats.ADMA_EXTERNAL_STARTCAPTURE \ | ats.ADMA_NPT | ats.ADMA_FIFO_ONLY_STREAMING) elif parameters['mode'] == 'CHANNEL_A': board.beforeAsyncRead(channels, -preTriggerSamples, samplesPerRecord, recordsPerBuffer, recordsPerAcquisition, ats.ADMA_EXTERNAL_STARTCAPTURE \ | ats.ADMA_NPT | ats.ADMA_FIFO_ONLY_STREAMING) elif parameters['mode'] == 'CHANNEL_B': board.beforeAsyncRead(channels, -preTriggerSamples, samplesPerRecord, recordsPerBuffer, recordsPerAcquisition, ats.ADMA_EXTERNAL_STARTCAPTURE \ | ats.ADMA_NPT | ats.ADMA_FIFO_ONLY_STREAMING) # Put the buffers previously created in the list of available buffers for buff in buffers: board.postAsyncBuffer(buff.addr, buff.size_bytes) return buffers
def AcquireData(board, waitBar): # TODO: Select the number of pre-trigger samples preTriggerSamples = 1024 # TODO: Select the number of samples per record. postTriggerSamples = 1024 # TODO: Select the number of records in the acquisition. recordsPerCapture = 100 # TODO: Select the amount of time to wait for the acquisition to # complete to on-board memory. acquisition_timeout_sec = 10 # TODO: Select the active channels. channels = ats.CHANNEL_A | ats.CHANNEL_B channelCount = 0 for c in ats.channels: channelCount += (c & channels == c) # TODO: Should data be saved to file? saveData = false dataFile = None if saveData: dataFile = open(os.path.join(os.path.dirname(__file__), "data.bin"), 'w') # Compute the number of bytes per record and per buffer memorySize_samples, bitsPerSample = board.getChannelInfo() bytesPerSample = (bitsPerSample.value + 7) // 8 samplesPerRecord = preTriggerSamples + postTriggerSamples bytesPerRecord = bytesPerSample * samplesPerRecord # Calculate the size of a record buffer in bytes. Note that the # buffer must be at least 16 bytes larger than the transfer size. bytesPerBuffer = bytesPerSample * (samplesPerRecord + 0) # Set the record size board.setRecordSize(preTriggerSamples, postTriggerSamples) # Configure the number of records in the acquisition board.setRecordCount(recordsPerCapture) start = time.clock() # Keep track of when acquisition started board.startCapture() # Start the acquisition print(("Capturing %d record. Press any key to abort" % recordsPerCapture)) buffersCompleted = 0 bytesTransferred = 0 while not waitBar.hasUserCancelled(): if not board.busy(): # Acquisition is done break if time.clock() - start > acquisition_timeout_sec: board.abortCapture() raise Exception("Error: Capture timeout. Verify trigger") time.sleep(10e-3) captureTime_sec = time.clock() - start recordsPerSec = 0 if captureTime_sec > 0: recordsPerSec = recordsPerCapture / captureTime_sec print(("Captured %d records in %f rec (%f records/sec)" % (recordsPerCapture, captureTime_sec, recordsPerSec))) buffer = ats.DMABuffer(bytesPerSample, bytesPerBuffer) # Transfer the records from on-board memory to our buffer print(("Transferring %d records..." % recordsPerCapture)) for record in range(recordsPerCapture): for channel in range(channelCount): channelId = ats.channels[channel] if channelId & channels == 0: continue board.read( channelId, # Channel identifier buffer.addr, # Memory address of buffer bytesPerSample, # Bytes per sample record + 1, # Record (1-indexed) -preTriggerSamples, # Pre-trigger samples samplesPerRecord) # Samples per record bytesTransferred += bytesPerRecord # Records are arranged in the buffer as follows: # R0A, R1A, R2A ... RnA, R0B, R1B, R2B ... # # A 12-bit sample code is stored in the most significant bits of # in each 16-bit sample value. # # Sample codes are unsigned by default. As a result: # - a sample code of 0x0000 represents a negative full scale input signal. # - a sample code of 0x8000 represents a ~0V signal. # - a sample code of 0xFFFF represents a positive full scale input signal. # Optionaly save data to file if dataFile: buffer.buffer[:samplesPerRecord].tofile(dataFile) if waitBar.hasUserCancelled(): break waitBar.setProgress(record / recordsPerCapture) # Compute the total transfer time, and display performance information. transferTime_sec = time.clock() - start bytesPerSec = 0 if transferTime_sec > 0: bytesPerSec = bytesTransferred / transferTime_sec print(("Transferred %d bytes (%f bytes per sec)" % (bytesTransferred, bytesPerSec)))
def AcquireData(board): # TODO: Select the number of pre-trigger samples preTriggerSamples = 1024 # TODO: Select the number of samples per record. postTriggerSamples = 1024 # TODO: Select the number of records per DMA buffer. recordsPerBuffer = 10 # TODO: Select the number of buffers per acquisition. buffersPerAcquisition = 10 # TODO: Select the active channels. channels = ats.CHANNEL_A | ats.CHANNEL_B channelCount = 0 for c in ats.channels: channelCount += (c & channels == c) # TODO: Should data be saved to file? saveData = False dataFile = None if saveData: dataFile = open(os.path.join(os.path.dirname(__file__), "data.bin"), 'wb') # Compute the number of bytes per record and per buffer memorySize_samples, bitsPerSample = board.getChannelInfo() bytesPerSample = (bitsPerSample.value + 7) // 8 samplesPerRecord = preTriggerSamples + postTriggerSamples bytesPerRecord = bytesPerSample * samplesPerRecord bytesPerBuffer = bytesPerRecord * recordsPerBuffer * channelCount # TODO: Select number of DMA buffers to allocate bufferCount = 4 # Allocate DMA buffers sample_type = ctypes.c_uint8 if bytesPerSample > 1: sample_type = ctypes.c_uint16 buffers = [] for i in range(bufferCount): buffers.append(ats.DMABuffer(board.handle, sample_type, bytesPerBuffer)) # Set the record size board.setRecordSize(preTriggerSamples, postTriggerSamples) recordsPerAcquisition = recordsPerBuffer * buffersPerAcquisition # Configure the board to make an NPT AutoDMA acquisition board.beforeAsyncRead(channels, -preTriggerSamples, samplesPerRecord, recordsPerBuffer, recordsPerAcquisition, ats.ADMA_EXTERNAL_STARTCAPTURE | ats.ADMA_TRADITIONAL_MODE) # Post DMA buffers to board for buffer in buffers: board.postAsyncBuffer(buffer.addr, buffer.size_bytes) start = time.clock() # Keep track of when acquisition started try: board.startCapture() # Start the acquisition print("Capturing %d buffers. Press <enter> to abort" % buffersPerAcquisition) buffersCompleted = 0 bytesTransferred = 0 while (buffersCompleted < buffersPerAcquisition and not ats.enter_pressed()): # Wait for the buffer at the head of the list of available # buffers to be filled by the board. buffer = buffers[buffersCompleted % len(buffers)] board.waitAsyncBufferComplete(buffer.addr, timeout_ms=5000) buffersCompleted += 1 bytesTransferred += buffer.size_bytes # TODO: Process sample data in this buffer. Data is available # as a NumPy array at buffer.buffer # NOTE: # # While you are processing this buffer, the board is already # filling the next available buffer(s). # # You MUST finish processing this buffer and post it back to the # board before the board fills all of its available DMA buffers # and on-board memory. # # Samples are arranged in the buffer as follows: # S0A, S0B, ..., S1A, S1B, ... # with SXY the sample number X of channel Y. # # # Sample codes are unsigned by default. As a result: # - 0x0000 represents a negative full scale input signal. # - 0x8000 represents a ~0V signal. # - 0xFFFF represents a positive full scale input signal. # Optionaly save data to file if dataFile: buffer.buffer.tofile(dataFile) # Add the buffer to the end of the list of available buffers. board.postAsyncBuffer(buffer.addr, buffer.size_bytes) finally: board.abortAsyncRead() # Compute the total transfer time, and display performance information. transferTime_sec = time.clock() - start print("Capture completed in %f sec" % transferTime_sec) buffersPerSec = 0 bytesPerSec = 0 recordsPerSec = 0 if transferTime_sec > 0: buffersPerSec = buffersCompleted / transferTime_sec bytesPerSec = bytesTransferred / transferTime_sec recordsPerSec = recordsPerBuffer * buffersCompleted / transferTime_sec print("Captured %d buffers (%f buffers per sec)" % (buffersCompleted, buffersPerSec)) print("Captured %d records (%f records per sec)" % (recordsPerBuffer * buffersCompleted, recordsPerSec)) print("Transferred %d bytes (%f bytes per sec)" % (bytesTransferred, bytesPerSec))
def acquire_data(daq_params, alazar_params, board, verbose=True): rec_avg_all = [] rec_readout = [] # No pre-trigger samples in NPT mode preTriggerSamples = 0 # Select the number of samples per record. post_trigger_samples = alazar_params.post_trigger_samples # Select the number0 of records per DMA buffer. records_per_buffer = alazar_params.records_per_buffer #2**10 # up to 2**14 # Select the number of buffers per acquisition. buffers_per_acquisition = alazar_params.buffers_per_acquisition records_per_acquisition = records_per_buffer * buffers_per_acquisition # Select the active channels. channels = ats.CHANNEL_A | ats.CHANNEL_B channelCount = 0 for c in ats.channels: channelCount += (c & channels == c) # Should data be saved to file? saveData = False dataFile = None if saveData: dataFile = open(os.path.join(os.path.dirname(__file__), "data.bin"), 'wb') # Compute the number of bytes per record and per buffer memorySize_samples, bitsPerSample = board.getChannelInfo() bytesPerSample = (bitsPerSample.value + 7) // 8 samplesPerRecord = preTriggerSamples + post_trigger_samples bytesPerRecord = bytesPerSample * samplesPerRecord bytesPerBuffer = bytesPerRecord * records_per_buffer * channelCount # Select number of DMA buffers to allocate buffer_count = alazar_params.buffer_count # Allocate DMA buffers sample_type = ctypes.c_uint8 if bytesPerSample > 1: sample_type = ctypes.c_uint16 buffers = [] for i in range(buffer_count): buffers.append(ats.DMABuffer(board.handle, sample_type, bytesPerBuffer)) # Set the record size board.setRecordSize(preTriggerSamples, post_trigger_samples) # Configure the board to make an NPT AutoDMA acquisition board.beforeAsyncRead(channels, -preTriggerSamples, samplesPerRecord, records_per_buffer, records_per_acquisition, ats.ADMA_EXTERNAL_STARTCAPTURE | ats.ADMA_NPT) index_avg_start = daq_params.readout_start index_avg_end = daq_params.readout_start + daq_params.readout_duration - 1 index_ch = [None]*2 index_ch[0] = np.arange(0,post_trigger_samples*records_per_buffer) # channel A index_ch[1] = post_trigger_samples*records_per_buffer + np.arange(0,post_trigger_samples*records_per_buffer) # channel B rec_all_raw = [None]*2 rec_avg_all = [None]*2 rec_readout = [[]]*2 # Post DMA buffers to board for buffer in buffers: board.postAsyncBuffer(buffer.addr, buffer.size_bytes) start = time.clock() # Keep track of when acquisition started # start SRS DG535 triggers dg535_control.set_state(1) try: board.startCapture() # Start the acquisition if verbose: print("Capturing %d buffers. Press <enter> to abort" % buffers_per_acquisition) buffersCompleted = 0 bytesTransferred = 0 while (buffersCompleted < buffers_per_acquisition and not ats.enter_pressed()): # Wait for the buffer at the head of the list of available # buffers to be filled by the board. buffer = buffers[buffersCompleted % len(buffers)] board.waitAsyncBufferComplete(buffer.addr, timeout_ms=5000) buffersCompleted += 1 bytesTransferred += buffer.size_bytes # for idx, idx_ch in enumerate(index_ch): rec_all_raw[idx] = np.reshape(buffer.buffer[idx_ch], (records_per_buffer, post_trigger_samples)) # rec_all = rotate_iq(daq_params.iq_angle_deg, rec_all_raw) # for idx in [0, 1]: rec_avg_all[idx] = np.mean(rec_all[idx], axis=0) # is this just the avg of the last loop? rec_readout[idx] = np.concatenate((rec_readout[idx], np.mean(rec_all[idx][:,index_avg_start:index_avg_end], axis=1))) # NOTE: # # While you are processing this buffer, the board is already # filling the next available buffer(s). # # You MUST finish processing this buffer and post it back to the # board before the board fills all of its available DMA buffers # and on-board memory. # # Samples are arranged in the buffer as follows: # S0A, S0B, ..., S1A, S1B, ... # with SXY the sample number X of channel Y. # # Sample code are stored as 8-bit values. # # Sample codes are unsigned by default. As a result: # - 0x00 represents a negative full scale input signal. # - 0x80 represents a ~0V signal. # - 0xFF represents a positive full scale input signal. # Optionaly save data to file if dataFile: buffer.buffer.tofile(dataFile) # Add the buffer to the end of the list of available buffers. board.postAsyncBuffer(buffer.addr, buffer.size_bytes) finally: board.abortAsyncRead() # stop SRS DG535 triggers dg535_control.set_state(0) # Compute the total transfer time, and display performance information. if verbose: transferTime_sec = time.clock() - start print("Capture completed in %f sec" % transferTime_sec) buffersPerSec = 0 bytesPerSec = 0 recordsPerSec = 0 if transferTime_sec > 0: buffersPerSec = buffersCompleted / transferTime_sec bytesPerSec = bytesTransferred / transferTime_sec recordsPerSec = records_per_buffer * buffersCompleted / transferTime_sec print("Captured %d buffers (%f buffers per sec)" % (buffersCompleted, buffersPerSec)) print("Captured %d records (%f records per sec)" % (records_per_buffer * buffersCompleted, recordsPerSec)) print("Transferred %d bytes (%f bytes per sec)" % (bytesTransferred, bytesPerSec)) return (rec_avg_all, rec_readout)
def AcquireData(board, fft_module, recordLength_samples): # TODO: Specify the number of records per DMA buffer recordsPerBuffer = 10 # TODO: Specify the total number of buffers to capture buffersPerAcquisition = 10 # TODO: Select the active channels. channels = ats.CHANNEL_A channelCount = 0 for c in ats.channels: channelCount += (c & channels == c) # TODO: Select the FFT output format outputFormat = ats.FFT_OUTPUT_FORMAT_U16_LOG # TODO: Select the presence of NPT footers footer = ats.FFT_FOOTER_NONE # Compute the number of bytes per record and per buffer memorySize_samples, bitsPerSample = board.getChannelInfo() # TODO: Should data be saved to file? saveData = False dataFile = None if saveData: dataFile = open(os.path.join(os.path.dirname(__file__), "data.bin"), 'wb') # Configure the FFT fftLength_samples = 1 while fftLength_samples < recordLength_samples: fftLength_samples *= 2 bytesPerOutputRecord = fft_module.fftSetup(channels, recordLength_samples, fftLength_samples, outputFormat, footer, 0) bytesPerBuffer = bytesPerOutputRecord * recordsPerBuffer # TODO: Select number of DMA buffers to allocate bufferCount = 4 # Allocate DMA buffers if ((outputFormat == ats.FFT_OUTPUT_FORMAT_U8_LOG) or (outputFormat == ats.FFT_OUTPUT_FORMAT_U8_AMP2)): sample_type = ctypes.c_uint8 elif ((outputFormat == ats.FFT_OUTPUT_FORMAT_U16_LOG) or (outputFormat == ats.FFT_OUTPUT_FORMAT_U16_AMP2)): sample_type = ctypes.c_uint16 elif (outputFormat == ats.FFT_OUTPUT_FORMAT_U32): sample_type = ctypes.c_uint32 elif ((outputFormat == ats.FFT_OUTPUT_FORMAT_REAL_S32) or (outputFormat == ats.FFT_OUTPUT_FORMAT_IMAG_S32)): sample_type = ctypes.c_int32 else: sample_type = ctypes.c_float buffers = [] for i in range(bufferCount): buffers.append(ats.DMABuffer(board.handle, sample_type, bytesPerBuffer)) # Configure the board to make an NPT AutoDMA acquisition board.beforeAsyncRead( channels, 0, bytesPerOutputRecord, recordsPerBuffer, 0x7FFFFFFF, ats.ADMA_EXTERNAL_STARTCAPTURE | ats.ADMA_NPT | ats.ADMA_DSP) # Post DMA buffers to board for buffer in buffers: board.postAsyncBuffer(buffer.addr, buffer.size_bytes) start = time.clock() # Keep track of when acquisition started try: board.startCapture() # Start the acquisition print("Capturing %d buffers. Press <enter> to abort" % buffersPerAcquisition) buffersCompleted = 0 bytesTransferred = 0 while (buffersCompleted < buffersPerAcquisition and not ats.enter_pressed()): # Wait for the buffer at the head of the list of available # buffers to be filled by the board. timeout_ms = 5000 buffer = buffers[buffersCompleted % len(buffers)] board.dspGetBuffer(buffer.addr, timeout_ms) buffersCompleted += 1 bytesTransferred += buffer.size_bytes # TODO: Process sample data in this buffer. Data is available # as a NumPy array at buffer.buffer # NOTE: # # While you are processing this buffer, the board is already # filling the next available buffer(s). # # You MUST finish processing this buffer and post it back to the # board before the board fills all of its available DMA buffers # and on-board memory. # # Samples are arranged in the buffer as follows: # S0A, S0B, ..., S1A, S1B, ... # with SXY the sample number X of channel Y. # # A 12-bit sample code is stored in the most significant bits of # each 16-bit sample value. # # Sample codes are unsigned by default. As a result: # - 0x0000 represents a negative full scale input signal. # - 0x8000 represents a ~0V signal. # - 0xFFFF represents a positive full scale input signal. # Optionaly save data to file if dataFile: buffer.buffer.tofile(dataFile) # Add the buffer to the end of the list of available buffers. board.postAsyncBuffer(buffer.addr, buffer.size_bytes) finally: board.dspAbortCapture() if dataFile: dataFile.close() # Compute the total transfer time, and display performance information. transferTime_sec = time.clock() - start print("Capture completed in %f sec" % transferTime_sec) buffersPerSec = 0 bytesPerSec = 0 recordsPerSec = 0 if transferTime_sec > 0: buffersPerSec = buffersCompleted / transferTime_sec bytesPerSec = bytesTransferred / transferTime_sec recordsPerSec = recordsPerBuffer * buffersCompleted / transferTime_sec print("Captured %d buffers (%f buffers per sec)" % (buffersCompleted, buffersPerSec)) print("Captured %d records (%f records per sec)" % (recordsPerBuffer * buffersCompleted, recordsPerSec)) print("Transferred %d bytes (%f bytes per sec)" % (bytesTransferred, bytesPerSec))
def AcquireData_OCT_RT(board, preTriggerSamples, postTriggerSamples, recordsPerBuffer, buffersPerAcquisition,channel_sel): # TODO: Select the active channels. if channel_sel == "B": channels = ats.CHANNEL_B elif channel_sel =="A": channels = ats.CHANNEL_A channelCount = 0 for c in ats.channels: channelCount += (c & channels == c) # Compute the number of bytes per record and per buffer memorySize_samples, bitsPerSample = board.getChannelInfo() bytesPerSample = (bitsPerSample.value + 7) // 8 samplesPerRecord = preTriggerSamples + postTriggerSamples bytesPerRecord = bytesPerSample * samplesPerRecord bytesPerBuffer = bytesPerRecord * recordsPerBuffer * channelCount # TODO: Select number of DMA buffers to allocate bufferCount = 4 # Allocate DMA buffers sample_type = ctypes.c_uint8 if bytesPerSample > 1: sample_type = ctypes.c_uint16 buffers = [] for i in range(bufferCount): buffers.append(ats.DMABuffer(board.handle, sample_type, bytesPerBuffer)) # Set the record size board.setRecordSize(preTriggerSamples, postTriggerSamples) recordsPerAcquisition = recordsPerBuffer * buffersPerAcquisition # Configure the board to make an NPT AutoDMA acquisition board.beforeAsyncRead(channels, -preTriggerSamples, samplesPerRecord, recordsPerBuffer, recordsPerAcquisition, ats.ADMA_EXTERNAL_STARTCAPTURE | ats.ADMA_TRADITIONAL_MODE) # Post DMA buffers to board for buffer in buffers: board.postAsyncBuffer(buffer.addr, buffer.size_bytes) # start = time.perf_counter() # Keep track of when acquisition started try: board.startCapture() # Start the acquisition print("Capturing %d buffers. Press <enter> to abort" % buffersPerAcquisition) buffersCompleted = 0 bytesTransferred = 0 while (buffersCompleted < buffersPerAcquisition and not ats.enter_pressed()): # Wait for the buffer at the head of the list of available # buffers to be filled by the board. buffer = buffers[buffersCompleted % len(buffers)] board.waitAsyncBufferComplete(buffer.addr, timeout_ms=5000) buffersCompleted += 1 bytesTransferred += buffer.size_bytes # TODO: Process sample data in this buffer. Data is available # as a NumPy array at buffer.buffer # NOTE: # # While you are processing this buffer, the board is already # filling the next available buffer(s). # # You MUST finish processing this buffer and post it back to the # board before the board fills all of its available DMA buffers # and on-board memory. # # Samples are arranged in the buffer as follows: # S0A, S0B, ..., S1A, S1B, ... # with SXY the sample number X of channel Y. # # A 12-bit sample code is stored in the most significant bits of # each 16-bit sample value. # # Sample codes are unsigned by default. As a result: # - 0x0000 represents a negative full scale input signal. # - 0x8000 represents a ~0V signal. # - 0xFFFF represents a positive full scale input signal. # Optionaly save data to file # print(buffer.buffer) # if dataFile: # buffer.buffer.tofile(dataFile) n = 0 sampleValue = [] for i in range(0, len(buffer.buffer)): val = bin(buffer.buffer[i] >> 4) val = int(val, 2) sampleValue.append(val) sampleValue = np.array(sampleValue) reshapedSampleValue = sampleValue.reshape(recordsPerBuffer*channelCount, -1) data_ampl = reshapedSampleValue data_ampl_avg = np.mean(data_ampl, axis = 0) data_ampl_avg = np.transpose(data_ampl_avg) return data_ampl_avg # Add the buffer to the end of the list of available buffers. board.postAsyncBuffer(buffer.addr, buffer.size_bytes) finally: board.abortAsyncRead()