def find_beam_trajectory(self, start_point=None, scan_direction_x=1, scan_direction_z=1, z_samples=5, measure_power=False): """Find trajectory of single beam. The optional arguments are: scan_direction_x (1): Integers +1 (-1) indicate to scan in the positive (negative) x direction. scan_direction_z (1): Integers +1 (-1) indicate to scan in the positive (negative) z direction. z_samples (5): Number of points to sample the beam. measure_power (False): Include power with beam data. """ beam = Beam() # Find the beam at the first z extreme. if start_point is None: start_point = Vector([ self.axes[0].limits.direction(-scan_direction_x), self.axes[1].limits.middle(), self.axes[2].limits.direction(-scan_direction_z)]) delta_z = -scan_direction_z * self.axes[2].limits.length() / z_samples sample_positions = list(arange( self.axes[2].limits.direction(scan_direction_z), self.axes[2].limits.direction(-scan_direction_z), delta_z)) sample_positions.reverse() intercept = self.find_beam_center(start_point, scan_direction_x) if intercept is None: print "Trajectory cannot be established." return None # Calculate rough trajectory of the beam. beam.add_sample(intercept) self.change_grouping(1, fast=True) small_step = intercept + (scan_direction_z * array([0, 0, 10])) if abs(delta_z) > 10: self.position(small_step, wait=True) else: self.position(intercept + ( scan_direction_z * array([0, 0, abs(delta_z)])), wait=True) intercept = self.center_beam() while intercept is None: small_step = small_step - (scan_direction_z * array([0, 0, 2])) self.position(small_step, wait=True) intercept = self.center_beam() beam.add_sample(intercept) if sample_positions[0] == intercept[2]: sample_positions.pop(0) try: for z_sample in sample_positions: self.position(beam.position(z_sample), wait=True) intercept = self.center_beam() if intercept is not None: beam.add_sample(intercept) else: # Cross this bridge when we get there. pass except TrackerError: if len(beam.samples) < 2: raise beam.power = (0, 0) if measure_power: beam_angle = sys_math.degrees(sys_math.asin(beam.azimuth().value)) stage_angle = self.devices['r_stage'].position() self.position(beam.intercept, wait=True) self.rotate(stage_angle - beam_angle, wait=True) self.center_beam() ccd_power = self.devices['profiler'].average_power() beam.distortions = self.devices['profiler'].profile() self.devices['driver'].shutter_state(0, 0) self.devices['driver'].shutter_state(1, 0) sleep(0.1) monitor_powers = [] for _ in range(10): monitor_powers.append(self.devices['monitor'].read()) beam.power = (ccd_power, mean(monitor_powers)) self.rotate(stage_angle, wait=True) self.position(intercept, wait=True) return beam
def find_beam_center(self, start_point=None, scan_direction_x=1): """Scans in X for a single beam and centers it on the CCD. The optional arguments are: scan_direction_x (1): Integers +1 (-1) indicate to scan in the positive (negative) x direction. """ if start_point is None: start_point = [ self.axes[0].limits.lower, self.axes[1].limits.lower, self.axes[2].limits.lower] x_axis = self.axes[0] beam_position = self.get_beam_position() if beam_position is not None: # Beam is already in view. if beam_position[2] != start_point[2]: # Capture trajectory and move to correct z position. beam = Beam() beam.add_sample(self.center_beam()) delta_z_sign = ((start_point[2] - beam_position[2]) / abs(start_point[2] - beam_position[2])) self.change_grouping(1, fast=True) self.position(beam_position + delta_z_sign * array([0, 0, 10]), wait=True) beam.add_sample(self.center_beam()) beam_position = self.position( beam.position(start_point[2]), wait=True) else: # Beam not in view. Move camera into full starting point. self.change_grouping(1, fast=True) self.position(start_point, wait=True) self.change_grouping(1, fast=False) number_of_scans = 0 while beam_position is None: # Scan for beam crossing. x_axis.position(self.axes[0].limits.direction(scan_direction_x)) beam_position = self._scan_until_beam_visible(x_axis) if number_of_scans * 3.0 > self.axes[1].limits.length(): print "Beam cannot be found. Check beam height and power." return None number_of_scans += 1 scan_direction_x = -scan_direction_x if beam_position is None: if self.axes[1].position() == self.axes[1].limits.upper: self.axes[1].position(0, wait=True) else: self.axes[1].position(self.axes[1].position() + 3.0, wait=True) # Move back to beam position. self.change_grouping(1, fast=True) self.position(beam_position, wait=True) # The beam should now be in view. self.change_grouping(3, fast=True) beam_position = self.center_beam() if beam_position is None: # If it's not in view do a short scan to refind it. self.change_grouping(1, fast=False) self.position( self.position() + [ self._z_cosine * scan_direction_x * 18.0, 0, 0], wait=False) beam_position = self._scan_until_beam_visible(x_axis) if beam_position is None: self.position( self.position() + [ self._z_cosine * scan_direction_x * -36.0, 0, 0], wait=False) beam_position = self._scan_until_beam_visible(x_axis) beam_position = self.center_beam() # Return position or None, whatever it may be. return beam_position