def calc_crystal_frame_vectors(reflection_table, experiments): """Calculate the diffraction vectors in the crystal frame.""" reflection_table["s0"] = flex.vec3_double([experiments.beam.get_s0()] * len(reflection_table)) rot_axis = flex.vec3_double([experiments.goniometer.get_rotation_axis()]) angles = reflection_table[ "phi"] * -1.0 * pi / 180 # want to do an inverse rot. reflection_table["s1c"] = rotate_vectors_about_axis( rot_axis, reflection_table["s1"], angles) reflection_table["s0c"] = rotate_vectors_about_axis( rot_axis, reflection_table["s0"], angles) reflection_table["s1c"] = align_rotation_axis_along_z( rot_axis, reflection_table["s1c"]) reflection_table["s0c"] = align_rotation_axis_along_z( rot_axis, reflection_table["s0c"]) return reflection_table
def align_rotation_axis_along_z(exp_rot_axis, vectors): """Rotate the coordinate system such that the exp_rot_axis is along z.""" if list(exp_rot_axis) == [(0.0, 0.0, 1.0)]: return vectors (ux, uy, uz) = exp_rot_axis[0][0], exp_rot_axis[0][1], exp_rot_axis[0][2] cross_prod_uz = flex.vec3_double([(uy, -1.0 * ux, 0.0)]) angle_between_u_z = +1.0 * acos(uz / ((ux**2 + uy**2 + uz**2)**0.5)) phi = flex.double(vectors.size(), angle_between_u_z) new_vectors = rotate_vectors_about_axis(cross_prod_uz, vectors, phi) return flex.vec3_double(new_vectors)