Source code for dxtbx.model.crystal

from __future__ import annotations

from cctbx.sgtbx import space_group as SG
from scitbx import matrix

try:
    from ..dxtbx_model_ext import (
        Crystal,
        MosaicCrystalKabsch2010,
        MosaicCrystalSauter2014,
    )
except ModuleNotFoundError:
    from dxtbx_model_ext import (  # type: ignore
        Crystal,
        MosaicCrystalKabsch2010,
        MosaicCrystalSauter2014,
    )


[docs] class CrystalFactory:
[docs] @staticmethod def from_dict(d, t=None): """Convert the dictionary to a crystal model Params: d The dictionary of parameters t The template dictionary to use Returns: The crystal model """ if d is None and t is None: return None joint = t.copy() if t else {} joint.update(d) # Create the model from the dictionary if "ML_half_mosaicity_deg" in joint: assert "ML_domain_size_ang" in joint if ( joint["ML_half_mosaicity_deg"] is None or joint["ML_domain_size_ang"] is None ): assert ( joint["ML_half_mosaicity_deg"] is None and joint["ML_domain_size_ang"] is None ) else: if joint.get("mosaicity", 0) > 0: print( "Warning, two kinds of mosaicity found. Using Sauter2014 model" ) return MosaicCrystalSauter2014.from_dict(joint) if "mosaicity" in joint: return MosaicCrystalKabsch2010.from_dict(joint) else: return Crystal.from_dict(joint)
[docs] @staticmethod def from_mosflm_matrix( mosflm_A_matrix, unit_cell=None, wavelength=None, space_group=None ): """ Create a crystal_model from a Mosflm A matrix (a*, b*, c*); N.B. assumes the mosflm coordinate frame:: /! Y-axis / ! ^ / ! ! / ! ! / ! ! / / Xd ! ! / / * ^ ! ! / ! 3 ! ! !/ X-ray beam ! ! ! /------------------------/--!---->X-axis / ! / *1! <-/- ! / ! / \\+ve phi ! Yd / / / ! 2 / / ! * / Z-axis Ys ^ _/ Rotation ! /| Xs axis !/ O Also assume that the mosaic spread is 0. :param mosflm_A_matrix: The A matrix in Mosflm convention. :type mosflm_A_matrix: tuple of floats :param unit_cell: The unit cell parameters which are used to determine the wavelength from the Mosflm A matrix. :type unit_cell: cctbx.uctbx.unit_cell :param wavelength: The wavelength to scale the A matrix :type wavelength: float :param space_group: If the space group is None then the space_group will be assigned as P1 :type space_group: cctbx.sgtbx.space_group :returns: A crystal model derived from the given Mosflm A matrix :rtype: :py:class:`crystal_model` """ if not space_group: space_group = SG("P1") A_star = matrix.sqr(mosflm_A_matrix) A = A_star.inverse() if unit_cell: unit_cell_constants = unit_cell.parameters() a = matrix.col(A.elems[0:3]) wavelength = unit_cell_constants[0] / a.length() A *= wavelength elif wavelength: A *= wavelength else: # assume user has pre-scaled pass a = A.elems[0:3] b = A.elems[3:6] c = A.elems[6:9] rotate_mosflm_to_imgCIF = matrix.sqr((0, 0, 1, 0, 1, 0, -1, 0, 0)) _a = rotate_mosflm_to_imgCIF * a _b = rotate_mosflm_to_imgCIF * b _c = rotate_mosflm_to_imgCIF * c return Crystal(_a, _b, _c, space_group=space_group)