def _array(size_or_vals, dtype=None): from pyclibrary import build_array import ctypes if size_or_vals is None: return None try: _ = iter(size_or_vals) except TypeError: # Not iterable, so assume it's the size and create an empty array size = size_or_vals return build_array(_bf, dtype, size=size) else: # Iterable, so convert it to a ctypes array vals = size_or_vals if len(vals) == 0: return None if dtype is None: # Try to deduce type if isinstance(vals[0], int): dtype = ctypes.c_int elif isinstance(vals[0], float): dtype = ctypes.c_double elif isinstance(vals[0], basestring): dtype = ctypes.c_char_p elif isinstance(vals[0], _bf.BFarray): # Note: PyCLibrary does this automatically for scalar args, # but we must do it manually here for arrays. dtype = ctypes.POINTER(_bf.BFarray) vals = [ctypes.pointer(val) for val in vals] #else: # dtype = type(vals[0]) else: raise TypeError("Cannot deduce C type from ", type(vals[0])) return build_array(_bf, dtype, size=len(vals), vals=vals)
def list_boards(self): """List the detectd board. """ arr = build_array(self.library, self.library.InfoListEntry, 50) assert self.library.ControlUnit_ListDevices(self.id, arr, 50) return arr
def get_traces(self, duration, delay, records_per_capture): """Acquire the average signal on both channels. Parameters ---------- duration : float Time during which to acquire the data (in seconds) delay : float Time to wait after a trigger before starting next measure (in seconds). records_per_capture : int Number of records to acquire (per channel) """ # Set trigger delay n = int(round(delay/2e-9)) assert 0 < n < 62, 'Delay must be at most 61 cycles (%d)' % n self._dll.SetExternalTriggerDelay(self._cu_id, self._id, n) # Number of samples per record. samples_per_sec = 500e6 samples_per_record = int(samples_per_sec*duration) self._dll.MultiRecordSetup(self._cu_id, self._id, records_per_capture, samples_per_record) # Alloc memory for both channels (using numpy arrays) so that we get # records one by one and average them in numpy arrays (float) ch1_buff = np.empty(samples_per_record, dtype=np.int16) ch2_buff = np.empty(samples_per_record, dtype=np.int16) buffers = build_array('void *', 2, [cast_to(self._dll, 'void *', ch1_buff.ctypes.data), cast_to(self._dll, 'void *', ch2_buff.ctypes.data)]) ch1_avg = np.zeros(samples_per_record) ch2_avg = np.zeros(samples_per_record) while not self._dll.ArmTrigger(self._cu_id, self._id): time.sleep(0.0001) retrieved_records = 0 cu = self._cu_id id_ = self._id t = 1.*samples_per_sec/samples_per_record/10 bytes_per_sample = self._dll.GetNofBytesPerSample(cu, id_)[0] while retrieved_records < records_per_capture: # Wait for a record to be acquired. while not self._dll.GetAcquired(cu, id_): time.sleep(t) self._dll.GetData(buffers, samples_per_record, bytes_per_sample, 0, 1, 0x3, 0, samples_per_record, 0x00) ch1_avg += ch1_buff ch2_avg += ch2_buff self._dll.MultiRecordClose(self._cu_id, self._id) ch1_avg /= records_per_capture ch2_avg /= records_per_capture # Get the offset in volt for each channel (range is 1 V) ch1_offset = float(self._dll.GetAdjustableBias(cu, id_, 1)[-1])/2**15*1 ch2_offset = float(self._dll.GetAdjustableBies(cu, id_, 2)[-1])/2**15*1 # Get the real values in volt ch1_avg -= 2**15 ch1_avg /= 65535 ch1_avg += ch1_offset ch2_avg -= 2**15 ch2_avg /= 65535 ch2_avg += ch2_offset return ch1_avg, ch2_avg