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_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_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 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 _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_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 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_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_beamline_with_engineering_correction_containing_a_mode_update_correction_WHEN_update_mode_THEN_correct_readback_updated_fired(self): 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) mock_axis.trigger_rbv_change() bl = Beamline(components=[comp], beamline_parameters=[param], drivers=[driver], modes=[self.mode1, self.mode2]) bl.active_mode = self.mode1.name assert_that(self.correction_update.correction, is_(self.mode1_offset)) bl.active_mode = self.mode2.name assert_that(self.correction_update.correction, is_(self.mode2_offset))
def test_GIVEN_beam_line_where_autosave_and_engineering_correction_on_displacement_WHEN_init_THEN_beamline_is_at_given_place(self, param_float_autosave): expected_setpoint = 1.0 multiple = 2.0 param_float_autosave.read_parameter.return_value = expected_setpoint offset = expected_setpoint / multiple comp = Component("comp", PositionAndAngle(0.0, 0, 90)) param = AxisParameter("param", comp, ChangeAxis.POSITION, autosave=True) axis = create_mock_axis("MOT:MTR0101", offset + expected_setpoint, 1) driver = IocDriver(comp, ChangeAxis.POSITION, axis, engineering_correction=UserFunctionCorrection(lambda sp: sp / multiple)) nr_mode = BeamlineMode("NR", [param.name], {}) bl = Beamline([comp], [param], [driver], [nr_mode]) bl.active_mode = nr_mode.name result = comp.beam_path_set_point.axis[ChangeAxis.POSITION].get_displacement() assert_that(result, is_(close_to(expected_setpoint, 1e-6)))
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 beamline_s1_s3_theta_detector(spacing, initilise_mode_nr=True): """ Create beamline with Slits 1 and 3 a theta and a detector Args: spacing: spacing between components Returns: beamline, axes """ ConfigHelper.reset() nr = add_mode("NR") disabled = add_mode("DISABLED", is_disabled=True) # s1 s1 = add_component( Component("s1_comp", PositionAndAngle(0.0, 1 * spacing, 90))) add_parameter(AxisParameter("s1", s1, ChangeAxis.POSITION), modes=[nr]) s1_axis = create_mock_axis("MOT:MTR0101", 0, 1) add_driver(IocDriver(s1, ChangeAxis.POSITION, s1_axis)) # theta theta = add_component( ThetaComponent("ThetaComp_comp", PositionAndAngle(0.0, 2 * spacing, 90))) add_parameter(AxisParameter("theta", theta, ChangeAxis.ANGLE), modes=[nr, disabled]) # s3 s3 = add_component( Component("s3_comp", PositionAndAngle(0.0, 3 * spacing, 90))) add_parameter(AxisParameter("s3", s3, ChangeAxis.POSITION), modes=[nr]) s3_axis = create_mock_axis("MOT:MTR0102", 0, 1) add_driver(IocDriver(s3, ChangeAxis.POSITION, s3_axis)) # detector detector = add_component( TiltingComponent("Detector_comp", PositionAndAngle(0.0, 4 * spacing, 90))) theta.add_angle_to(detector) add_parameter(AxisParameter("det", detector, ChangeAxis.POSITION), modes=[nr, disabled]) add_parameter(AxisParameter("det_angle", detector, ChangeAxis.ANGLE), modes=[nr, disabled]) det_axis = create_mock_axis("MOT:MTR0104", 0, 1) add_driver(IocDriver(detector, ChangeAxis.POSITION, det_axis)) det_angle_axis = create_mock_axis("MOT:MTR0105", 0, 1) add_driver(IocDriver(detector, ChangeAxis.ANGLE, det_angle_axis)) axes = { "s1_axis": s1_axis, "s3_axis": s3_axis, "det_axis": det_axis, "det_angle_axis": det_angle_axis } add_beam_start(PositionAndAngle(0.0, 0.0, 0.0)) bl = get_configured_beamline() if initilise_mode_nr: bl.active_mode = nr return bl, axes
def beamline_sm_theta_bench(sm_angle, theta_angle, driver_bench_offset, autosave_bench_not_theta=False, natural_angle=0.0): ConfigHelper.reset() test = add_mode("TEST") add_beam_start(PositionAndAngle(0, 0, 0)) perp_to_floor_angle = 90.0 + natural_angle sm = add_component( ReflectingComponent("SM", PositionAndAngle(0, 0, perp_to_floor_angle))) 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, perp_to_floor_angle))) add_parameter( AxisParameter("theta", theta, ChangeAxis.ANGLE, autosave=not autosave_bench_not_theta)) bench = add_component( get_standard_bench(with_z_position=10, with_angle=0, perp_to_floor_angle=perp_to_floor_angle)) add_parameter( AxisParameter("bench_angle", bench, ChangeAxis.ANGLE, autosave=autosave_bench_not_theta)) add_parameter(AxisParameter("bench_offset", bench, ChangeAxis.POSITION)) bench_angle = radians(driver_bench_offset + theta_angle * 2 + sm_angle * 2) bench_jack_front = create_mock_axis( "MOT:MTR0102", tan(bench_angle) * PIVOT_TO_J1 - PIVOT_TO_BEAM * (1 - cos(bench_angle)), 1) bench_jack_rear = create_mock_axis( "MOT:MTR0103", tan(bench_angle) * PIVOT_TO_J2 - PIVOT_TO_BEAM * (1 - cos(bench_angle)), 1) add_driver(IocDriver(bench, ChangeAxis.JACK_REAR, bench_jack_rear)) add_driver(IocDriver(bench, ChangeAxis.JACK_FRONT, bench_jack_front)) bench_jack_rear.trigger_rbv_change() bench_jack_front.trigger_rbv_change() theta.add_angle_of(bench) return get_configured_beamline(), { "bench_jack_rear": bench_jack_rear, "bench_jack_front": bench_jack_front, "sm_angle": sm_axis }
def beamline_sm_theta_detector(sm_angle, theta, det_offset=0, autosave_theta_not_offset=True, beam_angle=0.0, sm_angle_engineering_correction=False): """ Create beamline with supermirror, theta and a tilting detector. Args: sm_angle (float): The initialisation value for supermirror angle theta (float): The initialisation value for theta det_offset (float): The initialisation value for detector offset autosave_theta_not_offset (bool): true to autosave theta and not the offset, false otherwise beam_angle (float): angle of the beam, worked out as the angle the components run along + 90 Returns: beamline, axes """ beam_start = PositionAndAngle(0.0, 0.0, 0.0) perp_to_floor_angle_in_mantid = 90 + beam_angle # COMPONENTS z_sm_to_sample = 1 z_sample_to_det = 2 sm_comp = ReflectingComponent( "sm_comp", PositionAndAngle(0.0, 0, perp_to_floor_angle_in_mantid)) detector_comp = TiltingComponent( "detector_comp", PositionAndAngle(0.0, z_sm_to_sample + z_sample_to_det, perp_to_floor_angle_in_mantid)) theta_comp = ThetaComponent( "theta_comp", PositionAndAngle(0.0, z_sm_to_sample, perp_to_floor_angle_in_mantid)) theta_comp.add_angle_to(detector_comp) comps = [sm_comp, theta_comp, detector_comp] # BEAMLINE PARAMETERS sm_angle_param = AxisParameter("sm_angle", sm_comp, ChangeAxis.ANGLE) theta_param = AxisParameter("theta", theta_comp, ChangeAxis.ANGLE, autosave=autosave_theta_not_offset) detector_position_param = AxisParameter( "det_pos", detector_comp, ChangeAxis.POSITION, autosave=not autosave_theta_not_offset) detector_angle_param = AxisParameter("det_angle", detector_comp, ChangeAxis.ANGLE) params = [ sm_angle_param, theta_param, detector_position_param, detector_angle_param ] # DRIVERS # engineering correction if sm_angle_engineering_correction: grid_data_provider = GridDataFileReader("linear_theta") grid_data_provider.variables = ["Theta"] grid_data_provider.points = np.array([[ -90, ], [ 0.0, ], [ 90.0, ]]) grid_data_provider.corrections = np.array([-45, 0.0, 45]) grid_data_provider.read = lambda: None correction = InterpolateGridDataCorrectionFromProvider( grid_data_provider, theta_param) size_of_correction = theta / 2.0 else: correction = None size_of_correction = 0 # setup motors beam_angle_after_sample = theta * 2 + sm_angle * 2 supermirror_segment = (z_sm_to_sample, sm_angle) theta_segment = (z_sample_to_det, theta) reflection_offset = DataMother._calc_reflection_offset( beam_angle, [supermirror_segment, theta_segment]) sm_axis = create_mock_axis("MOT:MTR0101", sm_angle + size_of_correction, 1) det_axis = create_mock_axis("MOT:MTR0104", reflection_offset + det_offset, 1) det_angle_axis = create_mock_axis( "MOT:MTR0105", beam_start.angle + beam_angle_after_sample, 1) axes = { "sm_axis": sm_axis, "det_axis": det_axis, "det_angle_axis": det_angle_axis } drives = [ IocDriver(sm_comp, ChangeAxis.ANGLE, sm_axis, engineering_correction=correction), IocDriver(detector_comp, ChangeAxis.POSITION, det_axis), IocDriver(detector_comp, ChangeAxis.ANGLE, det_angle_axis) ] # MODES nr_inits = {} nr_mode = BeamlineMode("NR", [param.name for param in params], nr_inits) modes = [nr_mode] beam_start = PositionAndAngle(0.0, 0.0, 0.0) bl = Beamline(comps, params, drives, modes, beam_start) bl.active_mode = nr_mode.name return bl, axes