def run_command(device, ao_subdevice, output_buffer): """Write output_buffer using ao_subdevice Blocks until the output is complete. """ ao_subdevice.command() writer = _utility.Writer( ao_subdevice, output_buffer, preload=ao_subdevice.get_buffer_size()/output_buffer.itemsize, block_while_running=True) writer.start() device.do_insn(_utility.inttrig_insn(ao_subdevice)) writer.join()
def measure(self, hasAborted=lambda:False): """ Initiates the scan after first checking the command and does not block, returns the starting timestamp """ self._verifyCommand() sleep(0.01) self.subdevice.command() length = len(self.channels) dtype = self.subdevice.get_dtype() converters = [c.get_converter() for c in self.channels] self.data = np.zeros((self.samples, length), dtype=np.float32) # Trigger AI self.subdevice.device.do_insn(inttrig_insn(self.subdevice)) # Measurement loop count = 0 size = int(self.data.itemsize/2)*length previous_bin_slice = b'' while not hasAborted() and self.samples > count: bin_slice = previous_bin_slice while len(bin_slice) < size: bin_slice += self.subdevice.device.file.read(size) previous_bin_slice = bin_slice[size:] bin_slice = bin_slice[:size] slice = np.fromstring( bin_slice, dtype=dtype, count=length ) if len(slice) != length: # Reading finished break # Convert to physical values for i, c in enumerate(converters): self.data[count,i] = c.to_physical(slice[i]) self.emit_progress(100.*count/self.samples) self.emit_data(self.data[count]) count += 1 # Cancel measurement if it is still running (abort event) if self.subdevice.get_flags().running: self.subdevice.cancel()
def _run_ramp(self, callback = None, block = False): if self._ao.get_flags().busy: print "Cannot run ramp, device is busy." self._ao.cancel() print "Canceled the command." b_size = self._ao.get_buffer_size() self._ao.command() self._ramp_data.tofile(self._ao.device.file) self._ao.device.file.flush() self._ao.device.do_insn(Util.inttrig_insn(self._ao)) if callback is not None or block is True: c = 0 while self._ao.get_buffer_contents() > 0: # c+=1 time.sleep(0) # if (c > 10000): # print # c = 0 self._ao.cancel() if callback is not None: print "Calling "+str(callback)+"." callback()
def _detectSurface(self, returnPos=False, returnData=True, updateFrequency=True, currPos=None, target=None, threshold=None): '''This function atually runs the approach and reads the data It has six optional options: returnPos (boolean, defaults False): Indicates whether the position of the piezo when the approach is stopped is returned. returnData (boolean, defaults True): Indicates whether the data signal recorded during the approach is returned. updateFrequency (boolean, defaults False): Indicates whether the readFrequency should be updated befor the approach. currPos (int16, defaults None): The current position of the piezo (in bits). If none, the function will determine the position. target (int16, defaults None): The target position of the approach curve. If none, it is determined as the maximum deflection of the piezo. If returnPos and returnData both are set to True, the first four bytes of the data will indicate the start position of the approach (currPos) in nm, followed by the position at the end of the approach (4 bytes) in nm, and the data. ''' # Update the read frequency, if requested if updateFrequency: self.readFrequency = self.getReadFrequency() npoints = np.floor(self.readFrequency / (1e3 * self.getConfig('Filter'))) if npoints < 1: npoints = 1 # If currPos is not provided, read it if currPos is None: currPos = self.piezo.current_pos() print "Current position has been read." # If target is not provided, get it if target is None: target = self.piezo.getApproachTarget() # Distance of the approach (in bits) dist = float(target.get_oBits() - currPos.get_oBits()) # The speed of the approach is given in nm/ms. We need it in bits/s. # s = self.piezo.converter.getConvertedNumber(0, UNIT.nm) e = self.piezo.converter.getConvertedNumber(10000, UNIT.nm) per_nm = float(e.get_oBits() - s.get_oBits()) / 10000.0 speed_in_bits_per_s = float(per_nm) * self.getConfig('FallRate') * 1e3 # Now a problem occurs. We might have to write more bits than fit in the buffer, # but we need to read the input channel as fast as possible. Reading the input # channel in a while loop to seems to block other threads, hence writing the # data to the buffer in a second thread does not help. We omit every second value # if the apporach data is too large. # Buffer size in uint16 b_size = self.piezo._ao.get_buffer_size() / np.dtype( np.uint16).itemsize # Check whether the data range is too large: if abs(dist) > b_size: f = np.sign(dist) * 2 else: f = np.sign(dist) speed_in_bits_per_s /= np.abs(f) # Compute the ramp data start = int(currPos.get_oBits()) + int(np.sign(f)) ende = int(target.get_oBits()) print "Ramp info:" print "=====================" print "From " + str(start) + " (in bits: " + str( currPos.get_oBits()) + ")" print "To " + str(target) + " (in bits: " + str( target.get_oBits()) + ")" print "=====================" ramp_data = np.array(xrange(start, ende, int(f)), np.uint16) if ramp_data[-1] != int( target.get_oBits()) and len(ramp_data) < b_size: np.append(ramp_data, int(target.get_oBits())) print str(ramp_data) # Prepare the command self._prepareApproachCommand(len(ramp_data), speed_in_bits_per_s) # Compute the threshold if threshold is None: i_zero = self.signal.read_n(10) signal = int(np.mean(i_zero)) threshold = self.getThresholdInBits(signal) print('Threshold is ' + str(threshold)) # Compute maximum number of points to be read max_points = int(2 * round( abs(dist) * float(self.readFrequency) / float(speed_in_bits_per_s)) / npoints) data = np.zeros(max_points, np.uint16) # Issue the command self.piezo._ao.command() # Write data to the buffer: ramp_data.tofile(self.piezo._ao.device.file) self.piezo._ao.device.file.flush() c = 0 # Run the loop # Booster down if self.boost and c < max_points: self.booster.home() time.sleep(0.001) n = 0 q = 0 start = time.time() while c < max_points: if c < 1: self.piezo._ao.device.do_insn(Util.inttrig_insn( self.piezo._ao)) signal = np.mean(self.signal.read_n(npoints)) data[c] = np.floor(signal) c += 1 if signal <= threshold: n = n + 1 q = q + 1 else: n = 0 if n > 2: break # Boost up print('q is ' + str(q)) if self.boost and c < max_points: self.booster.up() # Stop the piezo from approaching self.piezo.stop() # Read position if returnPos: pos = self.piezo.current_pos() if c == max_points: print "Max number of data points reached." else: print "Threshold detected." if self.retract: print "retacting to home." self.piezo.home() end = time.time() print "approach-time was: " + str(end - start) if returnData: ret = data[:c] else: ret = np.array([], np.uint16) if returnPos: st = int(self.piezo.deflection(currPos).get_nm()) en = int(self.piezo.deflection(pos).get_nm()) ret = np.concatenate(([ int(st / (2**16)), int(st % (2**16)), int(en / (2**16)), int(en % (2**16)) ], ret)) else: st = None en = None appData = { 'data': ret, 'threshold_detected': c < max_points, 'start_pos': st, 'end_pos': en } return appData
def start(self): if not self.is_started: self.device.do_insn(_utility.inttrig_insn(self.ao_subdevice)) self.is_started = True else: raise Exception("playback already started")
def start(self): if not self.is_started: self.device.do_insn(_utility.inttrig_insn(self.ao_subdevice)) self.is_started = True else: raise Exception("playback already started")