def beamline_theta_detector(out_of_beam_pos_z, inital_pos_z, out_of_beam_pos_ang, initial_pos_ang): ConfigHelper.reset() theta_comp = add_component( ThetaComponent("theta", PositionAndAngle(0, 0, 90))) theta = add_parameter( AxisParameter("theta", theta_comp, ChangeAxis.ANGLE)) detector_comp = TiltingComponent("detector", PositionAndAngle(0, 1, 90)) axis_det_z = create_mock_axis("det_z", inital_pos_z, 1) add_driver( IocDriver( detector_comp, ChangeAxis.POSITION, axis_det_z, out_of_beam_positions=[OutOfBeamPosition(out_of_beam_pos_z)])) axis_det_ang = create_mock_axis("det_ang", initial_pos_ang, 1) add_driver( IocDriver(detector_comp, ChangeAxis.ANGLE, axis_det_ang, out_of_beam_positions=[ OutOfBeamPosition(out_of_beam_pos_ang) ])) det_in = add_parameter(InBeamParameter("det_in", detector_comp)) theta_comp.add_angle_to(detector_comp) get_configured_beamline() return det_in, theta
def test_GIVEN_movement_and_beam_at_the_same_angle_WHEN_get_intercept_THEN_raises_calc_error( self): angle = 12.3 movement = LinearMovementCalc(PositionAndAngle(1, 1, angle)) beam = PositionAndAngle(0, 0, angle) assert_that( calling(movement.calculate_interception).with_args(beam), raises(ValueError))
def test_GIVEN_movement_perpendicular_to_z_at_beam_angle_0_WHEN_get_intercept_THEN_position_is_initial_position( self): y = 0 z = 10 movement = LinearMovementCalc(PositionAndAngle(y, z, 90)) beam = PositionAndAngle(0, 0, 0) result = movement.calculate_interception(beam) assert_that(result, is_(position(Position(y, z))))
def test_GIVEN_movement_45_to_z_at_beam_angle_along_z_WHEN_get_intercept_THEN_position_is_initial_position( self, angle): y = 0 z = 10 movement = LinearMovementCalc(PositionAndAngle(y, z, 45)) beam = PositionAndAngle(0, 0, angle) result = movement.calculate_interception(beam) assert_that(result, is_(position(Position(y, z))))
def test_GIVEN_set_point_value_set_WHEN_there_is_a_value_observer_THEN_observer_triggered_with_new_value( self, expected_value): movement = LinearMovementCalc(PositionAndAngle(0, 0, 90)) beam = PositionAndAngle(0, 0, 0) self._value = None movement.set_displacement(expected_value) result = movement.get_distance_relative_to_beam(beam) assert_that(result, is_(expected_value))
def test_GIVEN_movement_and_beam_at_the_opposite_angles_within_tolerance_WHEN_get_intercept_THEN_raises_calc_error( self): angle = 12.3 + 180.0 tolerance = ANGULAR_TOLERANCE movement = LinearMovementCalc( PositionAndAngle(1, 1, angle + tolerance * 0.99)) beam = PositionAndAngle(0, 0, angle) assert_that( calling(movement.calculate_interception).with_args(beam), raises(ValueError))
def test_GIVEN_movement_anti_perpendicular_to_z_at_beam_angle_10_WHEN_get_intercept_THEN_position_is_z_as_initial_y_as_right_angle_triangle( self): y = 0 z = 10 beam_angle = 10 movement = LinearMovementCalc(PositionAndAngle(y, z, -90)) beam = PositionAndAngle(0, 0, beam_angle) expected_y = z * tan(radians(beam_angle)) result = movement.calculate_interception(beam) assert_that(result, is_(position(Position(expected_y, z))))
def test_GIVEN_movement_0_to_z_and_beam_angle_45_WHEN_get_intercept_THEN_position_is_on_movement_axis( self): y = 20 z = 10 movement = LinearMovementCalc(PositionAndAngle(y, z, 0)) beam = PositionAndAngle(0, 0, 45) expected_y = y expected_z = y result = movement.calculate_interception(beam) assert_that(result, is_(position(Position(expected_y, expected_z))))
def test_GIVEN_movement_along_z_WHEN_set_position_relative_to_beam_to_10_THEN_position_is_at_10_along_intercept( self): movement = LinearMovementCalc(PositionAndAngle(0, 10, 0)) beam_intercept = Position(0, 10) beam = PositionAndAngle(0, 10, 270) dist = 10 movement.set_distance_relative_to_beam(beam, dist) result = movement.position_in_mantid_coordinates() assert_that( result, is_(position(Position(beam_intercept.y, beam_intercept.z + dist))))
def beamline_s1_gap_theta_s3_gap_detector(spacing): """ Create beamline with Slits 1 and 3 a theta and a detector Args: spacing: spacing between components Returns: beamline, axes """ # DRIVERS s1_gap_axis = create_mock_axis("MOT:MTR0101", 0, 1) s3_gap_axis = create_mock_axis("MOT:MTR0103", 0, 1) axes = {"s1_gap_axis": s1_gap_axis} drives = [] # COMPONENTS theta = ThetaComponent("ThetaComp_comp", PositionAndAngle(0.0, 2 * spacing, 90)) detector = TiltingComponent("Detector_comp", PositionAndAngle(0.0, 4 * spacing, 90)) theta.add_angle_to(detector) comps = [theta] # BEAMLINE PARAMETERS s1_gap = create_parameter_with_initial_value(0, SlitGapParameter, "s1_gap", s1_gap_axis) theta_ang = create_parameter_with_initial_value( 0, AxisParameter, "theta", theta, ChangeAxis.ANGLE) s3_gap = create_parameter_with_initial_value(0, SlitGapParameter, "s3_gap", s3_gap_axis) detector_position = create_parameter_with_initial_value( 0, AxisParameter, "det", detector, ChangeAxis.POSITION) detector_angle = create_parameter_with_initial_value( 0, AxisParameter, "det_angle", detector, ChangeAxis.ANGLE) params = [s1_gap, theta_ang, s3_gap, detector_position, detector_angle] # MODES nr_inits = {} nr_mode = [ BeamlineMode("NR", [param.name for param in params], nr_inits) ] beam_start = PositionAndAngle(0.0, 0.0, 0.0) bl = Beamline(comps, params, drives, nr_mode, beam_start) # Initialise motor positions to get rbv call backs set s1_gap_axis.sp = 0 s3_gap_axis.sp = 0 return bl, axes
def test_GIVEN_movement_45_to_z_at_beam_along_z_WHEN_z_of_movement_axis_changes_THEN_position_is_new_z( self): y = 0 z = 7 z_offset = 9 movement = LinearMovementCalc(PositionAndAngle(y, z, 45)) beam = PositionAndAngle(y, 0, 0) result = movement.calculate_interception(beam) assert_that(result, is_(position(Position(y, z)))) movement.offset_position_at_zero(Position(0, z_offset)) result = movement.calculate_interception(beam) assert_that(result, is_(position(Position(y, z + z_offset))))
def test_GIVEN_movement_20_to_z_and_beam_angle_45_WHEN_get_intercept_THEN_position_is_on_movement_axis( self): beam = PositionAndAngle(0, 0, 45) expected_y = 4 expected_z = 4 move_angle = 20 move_z = 2 move_y = expected_y - (expected_z - move_z) * tan(radians(move_angle)) movement = LinearMovementCalc( PositionAndAngle(move_y, move_z, move_angle)) result = movement.calculate_interception(beam) assert_that(result, is_(position(Position(expected_y, expected_z))))
def beamline_sm_theta_ang_det(sm_angle, theta_angle, driver_comp_offset, autosave_bench_not_theta=False): ConfigHelper.reset() test = add_mode("TEST") add_beam_start(PositionAndAngle(0, 0, 0)) sm = add_component( ReflectingComponent("SM", PositionAndAngle(0, 0, 90))) add_parameter(AxisParameter("sm_angle", sm, ChangeAxis.ANGLE)) sm_axis = create_mock_axis("MOT:MTR0101", sm_angle, sm_angle) add_driver(IocDriver(sm, ChangeAxis.ANGLE, sm_axis)) sm_axis.trigger_rbv_change() theta = add_component( ThetaComponent("THETA", PositionAndAngle(0, 10, 90))) add_parameter( AxisParameter("theta", theta, ChangeAxis.ANGLE, autosave=not autosave_bench_not_theta)) DIST = 10 bench = add_component( TiltingComponent("comp", PositionAndAngle(0, DIST, 90))) add_parameter( AxisParameter("comp_angle", bench, ChangeAxis.ANGLE, autosave=autosave_bench_not_theta)) comp_angle = driver_comp_offset + theta_angle * 2 + sm_angle * 2 comp_height = create_mock_axis("MOT:MTR0102", tan(radians(comp_angle)) * DIST, 1) comp_ang = create_mock_axis("MOT:MTR0103", comp_angle, 1) add_driver(IocDriver(bench, ChangeAxis.HEIGHT, comp_height)) add_driver(IocDriver(bench, ChangeAxis.ANGLE, comp_ang)) comp_ang.trigger_rbv_change() comp_height.trigger_rbv_change() theta.add_angle_of(bench) return get_configured_beamline(), { "comp_ang": comp_ang, "comp_height": comp_height, "sm_angle": sm_axis }
def test_GIVEN_ioc_driver_with_engineering_correction_containing_a_mode_update_correction_WHEN_update_mode_THEN_correct_readback_updated_fired(self): mode1_mode1_offset = 11 mode1_mode2_offset = 12 mode2_mode1_offset = 210 mode2_mode2_offset = 220 mode1_mode_selection = ModeSelectCorrection(self.default_correction, {self.mode1.name: (ConstantCorrection(mode1_mode1_offset)), self.mode2.name: (ConstantCorrection(mode1_mode2_offset))}) mode2_mode_selection = ModeSelectCorrection(self.default_correction, {self.mode1.name: (ConstantCorrection(mode2_mode1_offset)), self.mode2.name: (ConstantCorrection(mode2_mode2_offset))}) mode_selection_correction = ModeSelectCorrection(self.default_correction, {self.mode1.name: mode1_mode_selection, self.mode2.name: mode2_mode_selection}) mode_selection_correction.set_observe_mode_change_on(self.mock_beamline) mode_selection_correction.add_listener(CorrectionRecalculate, self.get_update) mode_selection_correction.add_listener(CorrectionUpdate, self.get_correction_update) mock_axis = create_mock_axis("mock", 0, 1) driver = IocDriver(Component("comp", PositionAndAngle(0, 0, 0)), ChangeAxis.POSITION, mock_axis, engineering_correction=mode_selection_correction) mock_axis.trigger_rbv_change() driver.set_observe_mode_change_on(self.mock_beamline) mock_listener = Mock() driver.add_listener(CorrectionUpdate, mock_listener) self.mock_beamline.trigger_listeners(ActiveModeUpdate(self.mode1)) args = mock_listener.call_args[0] assert_that(args[0].correction, is_(mode1_mode1_offset))
def test_GIVEN_movement_perp_to_z_at_beam_angle_45_WHEN_z_of_movement_axis_changes_THEN_position_is_as_expected( self): y = 0 z = 7 z_offset = 9 movement = LinearMovementCalc(PositionAndAngle(y, z, 90)) beam = PositionAndAngle(0, 0, 45) result = movement.calculate_interception(beam) assert_that(result, is_(position(Position(z, z)))) movement.offset_position_at_zero(Position(0, z_offset)) result = movement.calculate_interception(beam) assert_that(result, is_(position(Position(z + z_offset, z + z_offset))))
def _setup_driver_axis_and_correction(self, correction): comp = Component("comp", PositionAndAngle(0.0, 0.0, 0.0)) mock_axis = create_mock_axis("MOT:MTR0101", 0, 1) engineering_correction = ConstantCorrection(correction) driver = IocDriver(comp, ChangeAxis.POSITION, mock_axis, engineering_correction=engineering_correction) comp.beam_path_set_point.axis[ChangeAxis.POSITION].is_changed = lambda: True # simulate that the component has requested a change return driver, mock_axis, comp, engineering_correction
def _setup_driver_axis_and_correction(self, correction): comp = Component("comp", PositionAndAngle(0.0, 0.0, 90.0)) mock_axis = create_mock_axis("MOT:MTR0101", 0, 1) driver = IocDriver(comp, ChangeAxis.POSITION, mock_axis, out_of_beam_positions=[OUT_OF_BEAM_POSITION], engineering_correction=ConstantCorrection(correction)) comp.beam_path_set_point.axis[ChangeAxis.POSITION].is_changed = lambda: True # simulate that the component has requested a change comp.beam_path_set_point.in_beam_manager.parking_index = 0 # The parking index is normally set initialised either through autosave or through initialise on the motor return driver, mock_axis, comp
def test_GIVEN_theta_rbv_beam_path_calc_WHEN_add_CHI_axis_and_set_displacement_THEN_error(self): theta_sp = BeamPathCalcThetaRBV("theta", None, None) comp = Component("comp", PositionAndAngle(0, 0, 0)) theta_sp.add_angle_to(comp.beam_path_rbv, comp.beam_path_set_point, [ChangeAxis.CHI]) assert_that(calling(comp.beam_path_rbv.axis[ChangeAxis.CHI].set_displacement).with_args( CorrectedReadbackUpdate(10, None, None)), raises(RuntimeError))
def test_GIVEN_movement_at_30_to_z_beam_intercept_is_at_zero_WHEN_set_position_relative_to_beam_to_10_THEN_position_is_at_10_along_intercept( self, add_angle): # here the beam intercept is above and to the right of the zero point movement = LinearMovementCalc(PositionAndAngle(0, 10, 30 + add_angle)) beam = PositionAndAngle(0, 0, 0) beam_intercept = Position(0, 10) dist = 10 movement.set_distance_relative_to_beam(beam, dist) result = movement.position_in_mantid_coordinates() assert_that( result, is_( position( Position(beam_intercept.y + dist / 2.0, beam_intercept.z + dist * sqrt(3) / 2.0))))
def test_GIVEN_theta_sp_beam_path_calc_WHEN_add_CHI_axis_and_update_THEN_error(self): theta_sp = BeamPathCalcThetaSP("theta", None) comp = Component("comp", PositionAndAngle(0, 0, 0)) theta_sp.add_angle_to(comp.beam_path_rbv, [ChangeAxis.CHI]) assert_that(calling(comp.beam_path_rbv.axis[ChangeAxis.CHI].init_displacement_from_motor).with_args(10), raises(RuntimeError))
def test_GIVEN_ioc_driver_which_has_not_moved_with_engineering_correction_WHEN_update_mode_THEN_readback_not_fired(self): driver = IocDriver(Component("comp", PositionAndAngle(0, 0, 0)), ChangeAxis.POSITION, create_mock_axis("mock", 0, 1), engineering_correction=self.mode_selection_correction) driver.set_observe_mode_change_on(self.mock_beamline) mock_listener = Mock() driver.add_listener(CorrectionUpdate, mock_listener) self.mock_beamline.trigger_listeners(ActiveModeUpdate(self.mode1)) mock_listener.assert_not_called()
def test_GIVEN_engineering_correction_offset_of_1_on_angle_driver_WHEN_initialise_THEN_rbv_set_correctly(self): correction = 1 comp = TiltingComponent("comp", PositionAndAngle(0.0, 0.0, 0.0)) mock_axis = create_mock_axis("MOT:MTR0101", 0, 1) driver = IocDriver(comp, ChangeAxis.ANGLE, mock_axis, engineering_correction=ConstantCorrection(correction)) driver.initialise() result = comp.beam_path_set_point.axis[ChangeAxis.ANGLE].get_displacement() assert_that(result, is_(-1 * correction))
def test_GIVEN_beamline_with_engineering_correction_containing_a_mode_update_correction_WHEN_init_THEN_set_point_includes_correction(self, autosave): autosave.read_parameter = Mock(return_value=self.mode1.name) comp = Component("comp", PositionAndAngle(0, 0, 90)) param = AxisParameter("comp", comp, ChangeAxis.POSITION) mock_axis = create_mock_axis("mock", 0, 1) driver = IocDriver(comp, ChangeAxis.POSITION, mock_axis, engineering_correction=self.mode_selection_correction) bl = Beamline(components=[comp], beamline_parameters=[param], drivers=[driver], modes=[self.mode1, self.mode2]) assert_that(param.sp, is_(-self.mode1_offset)) # readback is -11 so sp must be set to this
def beamline_with_one_mode_init_param_in_mode_and_at_off_init( init_sm_angle, off_init, param_name): super_mirror = ReflectingComponent( "super mirror", PositionAndAngle(z=10, y=0, angle=90)) smangle = AxisParameter(param_name, super_mirror, ChangeAxis.ANGLE) beamline_mode = BeamlineMode("mode name", [smangle.name], {smangle.name: init_sm_angle}) beamline = Beamline([super_mirror], [smangle], [], [beamline_mode]) beamline.active_mode = beamline_mode.name smangle.sp = off_init return Beamline([super_mirror], [smangle], [], [beamline_mode])
def test_GIVEN_displacement_WHEN_calculating_position_in_mantid_coordinates_THEN_coordinates_at_given_displacement_are_returned( self): y = 0 z = 10 angle = 90 movement = LinearMovementCalc(PositionAndAngle(y, z, angle)) displacement = 5 result = movement.position_in_mantid_coordinates(displacement) assert_that(result, is_(position(Position(displacement, z))))
def test_GIVEN_engineering_correction_offset_of_1_on_angle_driver_WHEN_driver_told_to_go_to_0_THEN_pv_sent_to_1(self): expected_correction = 1 comp = TiltingComponent("comp", PositionAndAngle(0.0, 0.0, 0.0)) mock_axis = create_mock_axis("MOT:MTR0101", 0, 1) driver = IocDriver(comp, ChangeAxis.ANGLE, mock_axis, engineering_correction=ConstantCorrection(expected_correction)) comp.beam_path_set_point.axis[ChangeAxis.ANGLE].is_changed = lambda: True # simulate that the component has requested a change driver.perform_move(1) result = mock_axis.sp assert_that(result, is_(close_to(expected_correction, FLOAT_TOLERANCE)))
def test_GIVEN_ioc_driver_with_engineering_correction_WHEN_update_mode_THEN_setpoint_updated_fired(self): mock_axis = create_mock_axis("mock", 0, 1) component = Component("comp", PositionAndAngle(0, 0, 0)) driver = IocDriver(component, ChangeAxis.POSITION, mock_axis, engineering_correction=self.mode_selection_correction) component.beam_path_set_point.axis[ChangeAxis.POSITION].set_displacement(CorrectedReadbackUpdate(0, None, None)) mock_axis.sp = self.default_offset driver.set_observe_mode_change_on(self.mock_beamline) assert_that(driver.at_target_setpoint(), is_(True), "Should be at the target setpoint before mode is changed") self.mock_beamline.trigger_listeners(ActiveModeUpdate(self.mode1)) result = driver.at_target_setpoint() assert_that(result, is_(False), "Should NOT be at the target setpoint after mode is changed, because of new correction")
def test_GIVEN_interp_with_1D_points_based_on_setpoint_of_beamline_parameter_WHEN_column_name_not_beamline_name_THEN_error_in_initialise(self): grid_data_provider = GridDataFileReader("Test") grid_data_provider.variables = ["Theta"] grid_data_provider.points = np.array([[1.0, ], [2.0, ], [3.0, ]]) grid_data_provider.corrections = np.array([1.234, 4.0, 6.0]) grid_data_provider.read = lambda: None comp = Component("param_comp", setup=PositionAndAngle(0, 0, 90)) beamline_parameter = AxisParameter("not theta", comp, ChangeAxis.POSITION) assert_that( calling(InterpolateGridDataCorrectionFromProvider).with_args(grid_data_provider, beamline_parameter), raises(ValueError))
def get_outgoing_beam(self): """ Returns: the outgoing beam based on the last set incoming beam and any interaction with the component """ if not self.is_in_beam or not self._is_reflecting: return self._incoming_beam target_position = self.calculate_beam_interception() angle_between_beam_and_component = (self._angular_displacement - self._incoming_beam.angle) angle = angle_between_beam_and_component * 2 + self._incoming_beam.angle outgoing_beam = PositionAndAngle(target_position.y, target_position.z, angle) return outgoing_beam
def test_GIVEN_interp_with_1D_points_based_on_setpoint_of_driver_which_has_not_been_initialised_WHEN_request_a_point_THEN_correction_0_returned(self): grid_data_provider = GridDataFileReader("Test") grid_data_provider.variables = ["DRIVER"] grid_data_provider.points = np.array([[1.0, ], [2.0, ], [3.0, ]]) grid_data_provider.corrections = np.array([1.234, 4.0, 6.0]) grid_data_provider.read = lambda: None comp = Component("param_comp", setup=PositionAndAngle(0, 0, 90)) interp = InterpolateGridDataCorrectionFromProvider(grid_data_provider) interp.grid_data_provider = grid_data_provider result = interp.init_from_axis(0) assert_that(result, is_(close_to(0, FLOAT_TOLERANCE)))