def _eulerToQuat(self, alpha, beta, gamma, convention): """ Convert Euler angles to a quaternion """ getV3D = {'X': V3D(1, 0, 0), 'Y': V3D(0, 1, 0), 'Z': V3D(0, 0, 1)} return (Quat(alpha, getV3D[convention[0]]) * Quat(beta, getV3D[convention[1]]) * Quat(gamma, getV3D[convention[2]]))
def eulerToQuat(alpha, beta, gamma, convention): """ Convert Euler angles to a quaternion """ from mantid.kernel import Quat, V3D getV3D = {'X': V3D(1, 0, 0), 'Y': V3D(0, 1, 0), 'Z': V3D(0, 0, 1)} return (Quat(alpha, getV3D[convention[0]]) * Quat(beta, getV3D[convention[1]]) * Quat(gamma, getV3D[convention[2]]))
def test_that_SANS2D_can_move(self): # Arrange file_name = "SANS2D00028784" lab_z_translation_correction = 123. workspace = load_workspace(file_name) state = SANSMoveTest._get_simple_state(sample_scatter=file_name, lab_z_translation_correction=lab_z_translation_correction) beam_coordinates = [0.1076, -0.0835] # Act # The component input is not relevant for SANS2D's initial move. All detectors are moved component = None move_alg = self._run_move(state, workspace=workspace, move_type="InitialMove", beam_coordinates=beam_coordinates, component=component) # Assert for initial move for low angle bank # These values are on the workspace and in the sample logs, component_to_investigate = DetectorType.to_string(DetectorType.LAB) initial_z_position = 23.281 rear_det_z = 11.9989755859 offset = 4. total_x = 0. total_y = 0. total_z = initial_z_position + rear_det_z - offset + lab_z_translation_correction expected_position = V3D(total_x - beam_coordinates[0], total_y - beam_coordinates[1], total_z) expected_rotation = Quat(1., 0., 0., 0.) self.compare_expected_position(expected_position, expected_rotation, component_to_investigate, state.move, workspace) # Assert for initial move for high angle bank # These values are on the workspace and in the sample logs component_to_investigate = DetectorType.to_string(DetectorType.HAB) initial_x_position = 1.1 x_correction = -0.187987540973 initial_z_position = 23.281 z_correction = 1.00575649188 total_x = initial_x_position + x_correction total_y = 0. total_z = initial_z_position + z_correction expected_position = V3D(total_x - beam_coordinates[0], total_y - beam_coordinates[1], total_z) expected_rotation = Quat(0.9968998362876025, 0., 0.07868110579898738, 0.) self.compare_expected_position(expected_position, expected_rotation, component_to_investigate, state.move, workspace) # Act + Assert for elementary move component_elementary_move = "rear-detector" component_elementary_move_key = DetectorType.to_string(DetectorType.LAB) beam_coordinates_elementary_move = [120, 135] self.check_that_elementary_displacement_with_only_translation_is_correct(workspace, move_alg, state.move, beam_coordinates_elementary_move, component_elementary_move, component_elementary_move_key) # # Act + Assert for setting to zero position for all self.check_that_sets_to_zero(workspace, move_alg, state.move, comp_name=None)
def test_that_ZOOM_can_perform_move(self): beam_coordinates = [45, 25] component = "main-detector-bank" component_key = DetectorType.LAB.value workspace = load_empty_instrument("ZOOM") move_info = _get_state_move_obj(SANSInstrument.ZOOM) # Initial move move_component(component_name=component, workspace=workspace, move_info=move_info, move_type=MoveTypes.INITIAL_MOVE, beam_coordinates=beam_coordinates) initial_z_position = 20.77408 expected_position = V3D(-beam_coordinates[0], -beam_coordinates[1], initial_z_position) expected_rotation = Quat(1., 0., 0., 0.) compare_expected_position(self, expected_position, expected_rotation, component_key, move_info, workspace) # Elementary Move component_elementary_move = "LAB" component_elementary_move_key = DetectorType.LAB.value beam_coordinates_elementary_move = [120, 135] check_elementry_displacement_with_translation( self, workspace, move_info, beam_coordinates_elementary_move, component_elementary_move, component_elementary_move_key) # Reset to zero check_that_sets_to_zero(self, workspace, move_info=move_info)
def test_that_missing_beam_centre_is_taken_from_move_state(self): lab_z_translation_correction = 123. workspace = self._prepare_sans2d_empty_ws() move_info = _get_state_move_obj( instrument=SANSInstrument.SANS2D, z_translation=lab_z_translation_correction) # These values should be used instead of an explicitly specified beam centre move_info.detectors[DetectorType.HAB.value].sample_centre_pos1 = 26. move_info.detectors[DetectorType.HAB.value].sample_centre_pos2 = 98. # The component input is not relevant for SANS2D's initial move. All detectors are moved component = "front-detector" move_component(component_name=component, move_info=move_info, workspace=workspace, move_type=MoveTypes.INITIAL_MOVE) # These values are on the workspace and in the sample logs component_to_investigate = DetectorType.HAB.value initial_x_position = 1.1 x_correction = -0.187987540973 initial_z_position = 23.281 z_correction = 1.00575649188 total_x = initial_x_position + x_correction total_y = 0. total_z = initial_z_position + z_correction expected_position = V3D(total_x - 26., total_y - 98., total_z) expected_rotation = Quat(0.9968998362876025, 0., 0.07868110579898738, 0.) compare_expected_position(self, expected_position, expected_rotation, component_to_investigate, move_info, workspace)
def test_that_missing_beam_centre_is_taken_from_move_state(self): # Arrange file_name = "SANS2D00028784" lab_z_translation_correction = 123. workspace = load_workspace(file_name) state = SANSMoveTest._get_simple_state(sample_scatter=file_name, lab_z_translation_correction=lab_z_translation_correction) # These values should be used instead of an explicitly specified beam centre state.move.detectors[DetectorType.to_string(DetectorType.HAB)].sample_centre_pos1 = 26. state.move.detectors[DetectorType.to_string(DetectorType.HAB)].sample_centre_pos2 = 98. # Act # The component input is not relevant for SANS2D's initial move. All detectors are moved component = "front-detector" self._run_move(state, workspace=workspace, move_type="InitialMove", component=component) # Assert for initial move for high angle bank # These values are on the workspace and in the sample logs component_to_investigate = DetectorType.to_string(DetectorType.HAB) initial_x_position = 1.1 x_correction = -0.187987540973 initial_z_position = 23.281 z_correction = 1.00575649188 total_x = initial_x_position + x_correction total_y = 0. total_z = initial_z_position + z_correction expected_position = V3D(total_x - 26., total_y - 98., total_z) expected_rotation = Quat(0.9968998362876025, 0., 0.07868110579898738, 0.) self.compare_expected_position(expected_position, expected_rotation, component_to_investigate, state.move, workspace)
def test_setRotation(self): """ Test that the component's rotation can be set correctly. """ info = self._ws.componentInfo() quat = Quat(0,0,0,0) info.setRotation(0, quat) retQuat = info.rotation(0) self.assertEquals(quat, retQuat)
def test_that_missing_beam_centre_is_taken_from_lab_move_state_when_no_component_is_specified(self): # Arrange file_name = "SANS2D00028784" lab_z_translation_correction = 123. workspace = load_workspace(file_name) state = SANSMoveTest._get_simple_state(sample_scatter=file_name, lab_z_translation_correction=lab_z_translation_correction) # These values should be used instead of an explicitly specified beam centre state.move.detectors[DetectorType.to_string(DetectorType.LAB)].sample_centre_pos1 = 26. state.move.detectors[DetectorType.to_string(DetectorType.LAB)].sample_centre_pos2 = 98. # Act # The component input is not relevant for SANS2D's initial move. All detectors are moved component = None self._run_move(state, workspace=workspace, move_type="InitialMove", component=component) # Assert for initial move for low angle bank # These values are on the workspace and in the sample logs, component_to_investigate = DetectorType.to_string(DetectorType.LAB) initial_z_position = 23.281 rear_det_z = 11.9989755859 offset = 4. total_x = 0. total_y = 0. total_z = initial_z_position + rear_det_z - offset + lab_z_translation_correction expected_position = V3D(total_x - 26., total_y - 98., total_z) expected_rotation = Quat(1., 0., 0., 0.) self.compare_expected_position(expected_position, expected_rotation, component_to_investigate, state.move, workspace)
def test_that_LARMOR_new_style_can_move(self): # Arrange file_name = "LARMOR00002260" lab_x_translation_correction = 123. workspace = load_workspace(file_name) state = SANSMoveTest._get_simple_state(sample_scatter=file_name, lab_x_translation_correction=lab_x_translation_correction) # Note that the first entry is an angle while the second is a translation (in meter) beam_coordinates = [24., 38.] # Act for initial move component = None move_alg = self._run_move(state, workspace=workspace, move_type="InitialMove", beam_coordinates=beam_coordinates, component=component) # Assert low angle bank for initial move # These values are on the workspace and in the sample logs component_to_investigate = DetectorType.to_string(DetectorType.LAB) # The rotation couples the movements, hence we just insert absoltute value, to have a type of regression test. expected_position = V3D(0, -38, 25.3) expected_rotation = Quat(0.978146, 0, -0.20792, 0) self.compare_expected_position(expected_position, expected_rotation, component_to_investigate, state.move, workspace) # Act + Assert for setting to zero position for all self.check_that_sets_to_zero(workspace, move_alg, state.move, comp_name=None)
def test_that_LARMOR_old_Style_can_be_moved(self): # Arrange file_name = "LARMOR00000063" workspace = load_workspace(file_name) state = SANSMoveTest._get_simple_state(sample_scatter=file_name) # Note that both entries are translations beam_coordinates = [24., 38.] # Act component = None move_alg = self._run_move(state, workspace=workspace, move_type="InitialMove", beam_coordinates=beam_coordinates, component=component) # Assert low angle bank for initial move # These values are on the workspace and in the sample logs component_to_investigate = DetectorType.to_string(DetectorType.LAB) # The rotation couples the movements, hence we just insert absolute value, to have a type of regression test # solely. expected_position = V3D(-beam_coordinates[0], -beam_coordinates[1], 25.3) expected_rotation = Quat(1., 0., 0., 0.) self.compare_expected_position(expected_position, expected_rotation, component_to_investigate, state.move, workspace) # Act + Assert for setting to zero position for all self.check_that_sets_to_zero(workspace, move_alg, state.move, comp_name=None)
def eulerToAngleAxis(a, b, c, convention="YZX"): getV3D = {'X': V3D(1, 0, 0), 'Y': V3D(0, 1, 0), 'Z': V3D(0, 0, 1)} q1 = Quat(a, getV3D[convention[0]]) q2 = Quat(b, getV3D[convention[1]]) q3 = Quat(c, getV3D[convention[2]]) q = q1 * q2 * q3 # Semi-angle in radians deg = math.acos(q[0]) # Prefactor for the axis part s = math.sin(deg) # Angle in degrees deg *= 360.0 / math.pi ax0 = q[1] / s ax1 = q[2] / s ax2 = q[3] / s return deg, ax0, ax1, ax2
def test_angle_axis_constructor(self): v = V3D(1,1,1); # Construct quaternion to represent rotation # of 45 degrees around the 111 axis. q = Quat(90.0, v) c = 1.0/math.sqrt(2.0) s = c/math.sqrt(3.0) self.assertAlmostEquals(q[0],c,) self.assertAlmostEquals(q[1],s) self.assertAlmostEquals(q[2],s) self.assertAlmostEquals(q[3],s)
def _do_test_quaternion(self, angle, axis, expected_axis=None): # Act quaternion = Quat(angle, axis) converted_angle, converted_axis = quaternion_to_angle_and_axis(quaternion) # Assert if expected_axis is not None: axis = expected_axis self.assertAlmostEqual(angle, converted_angle) self.assertAlmostEqual(axis[0], converted_axis[0]) self.assertAlmostEqual(axis[1], converted_axis[1]) self.assertAlmostEqual(axis[2], converted_axis[2])
def test_rotate(self): a = math.sqrt(2.0)/2.0 #Trivial p = Quat(1,0,0,0) #Identity quaternion v = V3D(1,0,0) orig_v = v; p.rotate(v); self.assertEquals(orig_v,v) # Now do more angles v = V3D(1,0,0); p = Quat(90., V3D(0,1,0)); #90 degrees, right-handed, around y p.rotate(v); self.assertEquals(v, V3D(0,0,-1)) v = V3D(1,0,0); p = Quat(45., V3D(0,0,1)) p.rotate(v); self.assertEquals(v, V3D(a, a, 0))
def test_that_LOQ_can_perform_move(self): # Arrange # Setup data info file_name = "LOQ74044" lab_x_translation_correction = 123. beam_coordinates = [45, 25] component = "main-detector-bank" component_key = DetectorType.to_string(DetectorType.LAB) workspace = load_workspace(file_name) state = SANSMoveTest._get_simple_state( sample_scatter=file_name, lab_x_translation_correction=lab_x_translation_correction) # Act move_alg = self._run_move(state, workspace=workspace, move_type="InitialMove", beam_coordinates=beam_coordinates, component=component) # Act + Assert for initial move move_info = state.move center_position = move_info.center_position initial_z_position = 15.15 expected_position = V3D( center_position - beam_coordinates[0] + lab_x_translation_correction, center_position - beam_coordinates[1], initial_z_position) expected_rotation = Quat(1., 0., 0., 0.) self.compare_expected_position(expected_position, expected_rotation, component_key, move_info, workspace) # # Act + Assert for elementary move on high-angle bank component_elementary_move = "HAB" component_elementary_move_key = DetectorType.to_string( DetectorType.HAB) beam_coordinates_elementary_move = [120, 135] self.check_that_elementary_displacement_with_only_translation_is_correct( workspace, move_alg, move_info, beam_coordinates_elementary_move, component_elementary_move, component_elementary_move_key) # Act + Assert for setting to zero position for all self.check_that_sets_to_zero(workspace, move_alg, state.move, comp_name="main-detector-bank")
def test_that_LOQ_can_perform_move(self): lab_x_translation_correction = 123. beam_coordinates = [45, 25] component = "main-detector-bank" component_key = DetectorType.LAB.value workspace = load_empty_instrument("LOQ") state = _get_state_obj(SANSInstrument.LOQ, lab_x_translation_correction) # Initial move move_component(component_name=component, workspace=workspace, state=state, move_type=MoveTypes.INITIAL_MOVE, beam_coordinates=beam_coordinates) center_position = state.move.center_position initial_z_position = 15.15 expected_position = V3D( center_position - beam_coordinates[0] + lab_x_translation_correction, center_position - beam_coordinates[1], initial_z_position) expected_rotation = Quat(1., 0., 0., 0.) compare_expected_position(self, expected_position, expected_rotation, component_key, state.instrument_info, workspace) # Elementary Move component_elementary_move = "HAB" component_elementary_move_key = DetectorType.HAB.value beam_coordinates_elementary_move = [120, 135] check_elementry_displacement_with_translation( self, workspace, state, beam_coordinates_elementary_move, component_elementary_move, component_elementary_move_key) # Reset to zero check_that_sets_to_zero(self, workspace, state=state)
def test_that_missing_beam_centre_is_taken_from_lab_move_state_when_no_component_is_specified( self): lab_z_translation_correction = 123. workspace = self._prepare_sans2d_empty_ws() move_info = _get_state_move_obj( instrument=SANSInstrument.SANS2D, z_translation=lab_z_translation_correction) # These values should be used instead of an explicitly specified beam centre x_offset = 26. y_offset = 98. move_info.detectors[ DetectorType.LAB.value].sample_centre_pos1 = x_offset move_info.detectors[ DetectorType.LAB.value].sample_centre_pos2 = y_offset # The component input is not relevant for SANS2D's initial move. All detectors are moved component = None move_component(component_name=component, move_info=move_info, workspace=workspace, move_type=MoveTypes.INITIAL_MOVE) # Assert for initial move for low angle bank # These values are on the workspace and in the sample logs, component_to_investigate = DetectorType.LAB.value initial_z_position = 23.281 rear_det_z = 11.9989755859 offset = 4. total_x = 0. total_y = 0. total_z = initial_z_position + rear_det_z - offset + lab_z_translation_correction expected_position = V3D(total_x - x_offset, total_y - y_offset, total_z) expected_rotation = Quat(1., 0., 0., 0.) compare_expected_position(self, expected_position, expected_rotation, component_to_investigate, move_info, workspace)
def test_that_LARMOR_new_style_can_move(self): lab_x_translation_correction = 123. workspace = load_empty_instrument("LARMOR") # Taken from LARMOR00002260 AddSampleLog(Workspace=workspace, LogName="Bench_Rot", LogText="0.000973305") # Note that the first entry is an angle while the second is a translation (in meter) beam_coordinates = [24., 38.] # Act for initial move component = None move_info = _get_state_move_obj( instrument=SANSInstrument.LARMOR, x_translation=lab_x_translation_correction) move_component(component_name=component, workspace=workspace, move_info=move_info, move_type=MoveTypes.INITIAL_MOVE, beam_coordinates=beam_coordinates) # Assert low angle bank for initial move # These values are on the workspace and in the sample logs component_to_investigate = DetectorType.LAB.value # The rotation couples the movements, hence we just insert absolute value, to have a type of regression test. expected_position = V3D(0, -38, 25.3) expected_rotation = Quat(0.978146, 0, -0.20792, 0) compare_expected_position(self, expected_position, expected_rotation, component_to_investigate, move_info, workspace) check_that_sets_to_zero(self, workspace, move_info, comp_name=None)
def test_that_SANS2D_can_move(self): workspace = self._prepare_sans2d_empty_ws() lab_z_translation_correction = 123. beam_coordinates = [0.1076, -0.0835] # All detectors are moved on SANS2D component = None move_info = _get_state_move_obj( SANSInstrument.SANS2D, z_translation=lab_z_translation_correction) move_component(component_name=component, workspace=workspace, move_info=move_info, move_type=MoveTypes.INITIAL_MOVE, beam_coordinates=beam_coordinates) # Assert for initial move for low angle bank # These values are on the workspace and in the sample logs, component_to_investigate = DetectorType.LAB.value initial_z_position = 23.281 rear_det_z = 11.9989755859 offset = 4. total_x = 0. total_y = 0. total_z = initial_z_position + rear_det_z - offset + lab_z_translation_correction expected_position = V3D(total_x - beam_coordinates[0], total_y - beam_coordinates[1], total_z) expected_rotation = Quat(1., 0., 0., 0.) compare_expected_position(self, expected_position, expected_rotation, component_to_investigate, move_info, workspace) # Assert for initial move for high angle bank # These values are on the workspace and in the sample logs component_to_investigate = DetectorType.HAB.value initial_x_position = 1.1 x_correction = -0.187987540973 initial_z_position = 23.281 z_correction = 1.00575649188 total_x = initial_x_position + x_correction total_y = 0. total_z = initial_z_position + z_correction expected_position = V3D(total_x - beam_coordinates[0], total_y - beam_coordinates[1], total_z) expected_rotation = Quat(0.9968998362876025, 0., 0.07868110579898738, 0.) compare_expected_position(self, expected_position, expected_rotation, component_to_investigate, move_info, workspace) # Act + Assert for elementary move component_elementary_move = "rear-detector" component_elementary_move_key = DetectorType.LAB.value beam_coordinates_elementary_move = [120, 135] check_elementry_displacement_with_translation( self, workspace, move_info, beam_coordinates_elementary_move, component_elementary_move, component_elementary_move_key) # # Act + Assert for setting to zero position for all check_that_sets_to_zero(self, workspace, move_info, comp_name=None)
def eulerToQuat(a, b, c, convention="YZX"): getV3D = {'X': V3D(1, 0, 0), 'Y': V3D(0, 1, 0), 'Z': V3D(0, 0, 1)} q1 = Quat(a, getV3D[convention[0]]) q2 = Quat(b, getV3D[convention[1]]) q3 = Quat(c, getV3D[convention[2]]) return q1 * q2 * q3
def test_len(self): q = Quat(1,2,3,4); self.assertAlmostEquals(q.len(),math.sqrt(30.0))
def test_value_constructor(self): q = Quat(1, 2, 3, 4) self.assertEquals(q[0], 1.0) self.assertEquals(q[1], 2.0) self.assertEquals(q[2], 3.0) self.assertEquals(q[3], 4.0)
def MyRotateFunction(vector, axis, angle): from copy import copy q = Quat(angle, axis) new_vector = copy(vector) q.rotate(new_vector) return new_vector
def test_index_operator(self): q = Quat(2, 3, 4, 5) self.assertEquals(q[0], 2.0) self.assertEquals(q[1], 3.0) self.assertEquals(q[2], 4.0) self.assertEquals(q[3], 5.0)
def test_setRotation_extreme(self): info = self._ws.componentInfo() quat = Quat(0,0,0,0) with self.assertRaises(OverflowError): info.setRotation(-1, quat)
def test_empty_constructor(self): q = Quat() self.assertEquals(q[0], 1.0) self.assertEquals(q[1], 0.0) self.assertEquals(q[2], 0.0) self.assertEquals(q[3], 0.0)
def test_len2(self): q = Quat(1, 2, 3, 4) self.assertAlmostEquals(q.len2(), 30.0)
def test_rotate(self): a = math.sqrt(2.0) / 2.0 #Trivial p = Quat(1, 0, 0, 0) #Identity quaternion v = V3D(1, 0, 0) orig_v = v p.rotate(v) self.assertEquals(orig_v, v) # Now do more angles v = V3D(1, 0, 0) p = Quat(90., V3D(0, 1, 0)) #90 degrees, right-handed, around y p.rotate(v) self.assertEquals(v, V3D(0, 0, -1)) v = V3D(1, 0, 0) p = Quat(45., V3D(0, 0, 1)) p.rotate(v) self.assertEquals(v, V3D(a, a, 0))
def test_len(self): q = Quat(1, 2, 3, 4) self.assertAlmostEquals(q.len(), math.sqrt(30.0))
def test_len2(self): q = Quat(1,2,3,4); self.assertAlmostEquals(q.len2(),30.0)