# ReferenceFrame.py # Maintained by G.Winter # 19th November 2007 # # Code to handle transformations between reference frames, e.g. from xia2 # to Mosflm, xia2 to XDS &c. # # This is prone to errors most likely... the following descriptions assume # Rossmann geometry for the experiment, with the X-ray beam at right angles # with a rotation axis which is parallel to a detector axis and with the # beam perpendicular (approximately) to the detector face. # # Reference frame definitions # --------------------------- # # (1) Cambridge as used in Mosflm, cribbed from Mosflm documentation. # # X: the direction of the X-ray beam photons # Y: defined to give a right handed coordinate system # Z: the principle rotation axis, such that looking down this axis # towards the sample, positive phi is anti-clockwise # # (2) imgCIF as used in xia2, cribbed from presentation from Herb Bernstein. # # X: the principle goniometer axis # Y: defined to give a right handed coordinate system # Z: from the sample towards the X-ray source (=> is -X in Cambridge frame) # [the component perpendicular to the rotation axis] # # (3) XDS frame, as used by xia2. # # This is largely free, as the program allows the user to define everything # in laboratory coordinates. However, I adopt the following conventions: # # X: identical to the detector fast axis*1 and parallel (approximately) to # the rotation axis [MAR, MARCCD, ADSC] # [*1 for RIGAKU SATURN this is antiparallel] # Y: identical to the detector slow axis and parallel (approximately) to # the rotation axis [RIGAKU SATURN] or antiparallel (approximately) # [RIGAKU RAXIS] # Z: orthogonal to the detector face and parallel (approximately) to the # direct beam vector - this is defined as 0,0,1 initially and refined # # This last lot is a mess so I should probably define a robust coordinate # frame for the XDS interface and perform the transformations inside the # XDS wrappers... # # Thus, the definitions will be as follows: # # X: parallel to the detector fast axis # Y: parallel to the detector slow axis # Z: perpendicular to the face of the detector # # So the rotation and beam axes may need to be altered... in a detector # dependent manner. # # Mos2Xia2 = (0, 0, 1, 0, 1, 0, -1, 0, 0) def mosflm_to_xia2(v): '''Convert a vector v from Mosflm reference frame to xia2.''' from MatrixExpert import matvecmul, invert return matvecmul(Mos2Xia2, v) def xia2_to_mosflm(v): '''Convert a vector v from xia2 frame to Mosflm.''' from MatrixExpert import matvecmul, invert Xia22Mos = invert(Mos2Xia2) return matvecmul(Xia22Mos, v) if __name__ == '__main__': if mosflm_to_xia2((1, 0, 0)) != [0, 0, -1]: raise RuntimeError, 'transformation error i' if mosflm_to_xia2((0, 1, 0)) != [0, 1, 0]: raise RuntimeError, 'transformation error j' if mosflm_to_xia2((0, 0, 1)) != [1, 0, 0]: raise RuntimeError, 'transformation error k'