occ
Loading...
Searching...
No Matches
occ::crystal Namespace Reference

functionality related to periodic crystal structures, space groups, symmetry operations More...

Namespaces

namespace  xray_wavelength
 Characteristic K-alpha X-ray wavelengths, in Angstroms.
namespace  impl

Classes

struct  AsymmetricUnit
 A class representing an asymmetric unit of a crystal structure. More...
struct  CrystalAtomRegion
 A class representing a region of atoms in a crystal lattice. More...
struct  CrystalDimers
 A class representing the molecular dimers in a crystal lattice. More...
class  Crystal
 A class representing a crystal structure. More...
struct  SymmetryDimerLabeller
struct  DimerIndex
 Represents a pair of sites in a crystal structure. More...
struct  DimerIndexHash
struct  DimerMappingEdge
struct  DimerMappingVertex
class  DimerMappingTable
 Maps and manages symmetry relationships between dimers in a crystal. More...
struct  HKL
 A struct representing a lattice vector triplet (h, k, l) in a crystal lattice. More...
struct  PowderPeak
 A single powder peak. More...
struct  PowderPatternSettings
class  PowderPattern
 A simulated powder X-ray diffraction pattern. More...
struct  SiteIndex
struct  SiteIndexHash
struct  SiteMappingEdge
struct  SiteMappingVertex
class  SiteMappingTable
class  ReciprocalAsymmetricUnit
class  SpaceGroup
 This class represents a space group. More...
class  StandardBondLengths
 Standard hydrogen bond lengths for various elements. More...
struct  MaximalSubgroup
 A maximal subgroup of a space group. More...
struct  SubgroupPath
 A subgroup reached by descending one or more maximal-subgroup steps. More...
struct  SubgroupSearchParameters
struct  SubgroupTransform
 A change of setting from a space group to one of its subgroups. More...
struct  ZPrimeSearchParameters
struct  SurfaceCutResult
 Results from analyzing a crystal surface cut. More...
class  Surface
 Represents and analyzes a crystal surface defined by Miller indices. More...
struct  CrystalSurfaceGenerationParameters
 Parameters for crystal surface generation. More...
struct  SymmetryOperationFormat
class  SymmetryOperation
 Class representing a 3D symmetry operation. More...
class  UnitCell
 This class represents a unit cell of a crystal lattice. More...
struct  XrayFormFactor
 A neutral-atom or ion X-ray form factor from Waasmaier & Kirfel (1995). More...
class  Molecule
 Storage class for relevant information of a Molecule. More...

Typedefs

using DimerMappingGraph
using SiteMappingGraph = core::graph::Graph<SiteMappingVertex, SiteMappingEdge>
using SGData = gemmi::SpaceGroup
using IVec
using Mat3N
using PeriodicBondGraph
using IVec
using Mat3N

Enumerations

enum class  SubgroupType { Translationengleiche , Klassengleiche }
 Whether a group-subgroup relation preserves translations or class. More...

Functions

Eigen::MatrixXd muldin (const Eigen::VectorXd &x)
double d_spacing (const HKL &hkl, const UnitCell &uc)
 The d-spacing of a reflection, in Angstroms.
std::vector< PowderPeak > unique_reflections (const Crystal &crystal, double d_min)
 Enumerate the symmetry-unique reflections with d >= d_min.
CVec structure_factors (const Crystal &crystal, const std::vector< PowderPeak > &reflections, bool debye_waller=true)
 Structure factors F(hkl) for the given reflections.
double lorentz_polarization (double two_theta)
 Lorentz-polarization factor for an unpolarized source.
PowderPattern compute_powder_pattern (const Crystal &crystal, const PowderPatternSettings &settings={})
 Compute a powder pattern for the given crystal.
const std::vector< MaximalSubgroup > & maximal_subgroups (int space_group_number)
 The maximal subgroups of a space group.
std::vector< MaximalSubgroup > maximal_subgroups (int space_group_number, SubgroupType type)
 The maximal subgroups of a given type.
std::vector< SubgroupPath > subgroup_paths (int space_group_number, const SubgroupSearchParameters &params={})
 All subgroups reachable from a space group, by traversing the graph of maximal-subgroup relations.
Crystal to_subgroup (const Crystal &crystal, const SubgroupTransform &transform, double tolerance=1e-4, bool molecular_asymmetric_unit=true)
 Re-describe a crystal in one of its subgroups.
SubgroupTransform compose (const SubgroupTransform &first, const SubgroupTransform &second)
 Compose two subgroup transformations, applied left to right.
Crystal to_standard_setting (const Crystal &crystal, double tolerance=1e-4)
 Re-describe a crystal in the standard (ITA reference) setting of its space group.
Crystal with_grouped_asymmetric_unit (const Crystal &crystal, const IVec &groups, double tolerance=1e-4)
 Re-choose a crystal's asymmetric unit so that groups of atoms stay together.
Crystal with_molecular_asymmetric_unit (const Crystal &crystal, double tolerance=1e-4)
 Re-choose the asymmetric unit so that whole molecules stay together.
double z_prime (const Crystal &crystal)
 The number of molecules in the asymmetric unit, Z'.
bool has_whole_molecule_asymmetric_unit (const Crystal &crystal)
 True if the asymmetric unit consists of whole molecules.
std::optional< SubgroupTransform > find_subgroup_for_z_prime (const Crystal &crystal, const ZPrimeSearchParameters &params={})
 Find a subgroup in which the crystal has the target Z'.
std::vector< Surface > generate_surfaces (const Crystal &c, const CrystalSurfaceGenerationParameters &={})
bool friedel_mate_is_equivalent (const Crystal &c, const HKL &hkl)
 Whether the crystal's point group maps hkl onto -h-k-l, i.e.
std::vector< size_t > laue_orbit_partners (const Crystal &c, const std::vector< Surface > &surfaces, size_t i)
 Positions in surfaces that share a Laue-class orbit with surfaces[i], including i itself.
std::vector< std::pair< HKL, SymmetryOperation > > face_images (const Crystal &c, const HKL &hkl)
 The distinct faces equivalent to hkl under the crystal's point group, each with the first symmetry operation (R|t) that produces it: the image is R^-T hkl, and a cut at offset o on hkl maps to o + image.t on it.
bool is_closed_group (const std::vector< SymmetryOperation > &operations)
 Whether a list of operations is a whole group: closed under composition, up to lattice translations.
UnitCell cubic_cell (double length)
 Construct a cubic unit cell from a given length.
UnitCell rhombohedral_cell (double length, double angle)
 Construct a rhombohedral unit cell from a given length and angle.
UnitCell tetragonal_cell (double a, double c)
 Construct a tetragonal unit cell from two given lengths.
UnitCell hexagonal_cell (double a, double c)
 Construct a hexagonal unit cell from two given lengths.
UnitCell orthorhombic_cell (double a, double b, double c)
 Construct an orthorhombic unit cell from three given lengths.
UnitCell monoclinic_cell (double a, double b, double c, double angle)
 Construct an orthorhombic unit cell from three given lengths and one angle.
UnitCell triclinic_cell (double a, double b, double c, double alpha, double beta, double gamma)
 Construct an orthorhombic unit cell from three given lengths and three angles.
std::optional< XrayFormFactor > xray_form_factor (std::string_view label)
 Look up a form factor by scattering-type label, e.g.
std::optional< XrayFormFactor > xray_form_factor (int atomic_number)
 Look up the neutral atom for an atomic number (1-98); nullopt if out of range.
void to_json (nlohmann::json &j, const CrystalDimers &)
void from_json (const nlohmann::json &j, CrystalDimers &)
void to_json (nlohmann::json &j, const AsymmetricUnit &)
void from_json (const nlohmann::json &j, AsymmetricUnit &)
void to_json (nlohmann::json &j, const UnitCell &)
void from_json (const nlohmann::json &j, UnitCell &)
void to_json (nlohmann::json &j, const CrystalAtomRegion &)
void from_json (const nlohmann::json &j, CrystalAtomRegion &)
template<typename T>
constexpr bool is_close (T a, T b, const T rtol=Eigen::NumTraits< T >::dummy_precision(), const T atol=Eigen::NumTraits< T >::epsilon())

Detailed Description

functionality related to periodic crystal structures, space groups, symmetry operations

depends on occ::core and the gemmi library

Typedef Documentation

◆ DimerMappingGraph

◆ IVec [1/2]

using occ::IVec

◆ IVec [2/2]

using occ::IVec

◆ Mat3N [1/2]

using occ::Mat3N

◆ Mat3N [2/2]

using occ::Mat3N

◆ PeriodicBondGraph

◆ SGData

using occ::crystal::SGData = gemmi::SpaceGroup

◆ SiteMappingGraph

Enumeration Type Documentation

◆ SubgroupType

enum class occ::crystal::SubgroupType
strong

Whether a group-subgroup relation preserves translations or class.

Enumerator
Translationengleiche 

translationengleiche: the lattice is kept, point group symmetry is lost

Klassengleiche 

klassengleiche: the point group is kept, translations are lost

Function Documentation

◆ compose()

SubgroupTransform occ::crystal::compose ( const SubgroupTransform & first,
const SubgroupTransform & second )

Compose two subgroup transformations, applied left to right.

\(x'' = P_2^{-1}(P_1^{-1}(x - p_1) - p_2) = (P_1 P_2)^{-1}(x - (p_1 + P_1 p_2))\)

◆ compute_powder_pattern()

PowderPattern occ::crystal::compute_powder_pattern ( const Crystal & crystal,
const PowderPatternSettings & settings = {} )

Compute a powder pattern for the given crystal.

◆ cubic_cell()

UnitCell occ::crystal::cubic_cell ( double length)

Construct a cubic unit cell from a given length.

◆ d_spacing()

double occ::crystal::d_spacing ( const HKL & hkl,
const UnitCell & uc )

The d-spacing of a reflection, in Angstroms.

Note
This exists because HKL::d(cell.reciprocal()) returns the reciprocal lattice vector length |G| = 1/d, in Angstrom^-1, despite its name. Prefer this function whenever an actual d-spacing is wanted.

◆ face_images()

std::vector< std::pair< HKL, SymmetryOperation > > occ::crystal::face_images ( const Crystal & c,
const HKL & hkl )

The distinct faces equivalent to hkl under the crystal's point group, each with the first symmetry operation (R|t) that produces it: the image is R^-T hkl, and a cut at offset o on hkl maps to o + image.t on it.

Exact integer arithmetic. Build facet normals from these images (reciprocal * image) rather than by rotating a cartesian normal, which is exact only when the cell has the full metric symmetry: on a relaxed cell that has drifted slightly, a face an operation leaves in place comes back as a near-duplicate of itself.

◆ find_subgroup_for_z_prime()

std::optional< SubgroupTransform > occ::crystal::find_subgroup_for_z_prime ( const Crystal & crystal,
const ZPrimeSearchParameters & params = {} )

Find a subgroup in which the crystal has the target Z'.

The common case: a molecule sitting on a special position gives \(Z' < 1\), so the asymmetric unit is only a fragment. Descending into a subgroup that lacks the offending symmetry element makes the whole molecule independent, without changing the structure at all.

Candidates are tried in order of increasing index, so the least drastic descent that works is the one returned. Only translationengleiche relations are followed by default, since those keep the unit cell.

Returns
the transformation to apply (feed it to to_subgroup), or nullopt if no subgroup within the search bounds gives the target Z'

◆ friedel_mate_is_equivalent()

bool occ::crystal::friedel_mate_is_equivalent ( const Crystal & c,
const HKL & hkl )

Whether the crystal's point group maps hkl onto -h-k-l, i.e.

whether the two faces belong to the same form.

True for the 11 centrosymmetric point groups. False for the other 21, where (hkl) and (-h-k-l) are distinct forms — this is hemimorphism, and the two ends of a polar axis can carry different terminations and different surface energies.

The pair is nonetheless always degenerate in d, because 1/d² = hᵀG*h is a quadratic form in the indices and so is invariant under h → -h, whatever the metric. Ordering faces by d therefore cannot separate a Friedel pair: d has the symmetry of the Laue class, while equivalence of faces has the symmetry of the point group, and for the non-centrosymmetric groups the Laue class has index two over it. Anything that truncates a d-ordered list has to cut on whole Laue orbits or it splits such a pair arbitrarily, which is what laue_orbit_partners is for.

◆ from_json() [1/4]

void occ::crystal::from_json ( const nlohmann::json & j,
AsymmetricUnit &  )

◆ from_json() [2/4]

void occ::crystal::from_json ( const nlohmann::json & j,
CrystalAtomRegion &  )

◆ from_json() [3/4]

void occ::crystal::from_json ( const nlohmann::json & j,
CrystalDimers &  )

◆ from_json() [4/4]

void occ::crystal::from_json ( const nlohmann::json & j,
UnitCell &  )

◆ generate_surfaces()

std::vector< Surface > occ::crystal::generate_surfaces ( const Crystal & c,
const CrystalSurfaceGenerationParameters & = {} )

◆ has_whole_molecule_asymmetric_unit()

bool occ::crystal::has_whole_molecule_asymmetric_unit ( const Crystal & crystal)

True if the asymmetric unit consists of whole molecules.

When a molecule sits on a special position the asymmetric unit holds only part of it, and the rest is generated by symmetry. This is what makes \(Z' < 1\) structures awkward to work with: the asymmetric unit is not a chemically meaningful object.

◆ hexagonal_cell()

UnitCell occ::crystal::hexagonal_cell ( double a,
double c )

Construct a hexagonal unit cell from two given lengths.

◆ is_close()

template<typename T>
bool occ::util::is_close ( T a,
T b,
const T rtol = Eigen::NumTraits<T>::dummy_precision(),
const T atol = Eigen::NumTraits<T>::epsilon() )
constexpr

◆ is_closed_group()

bool occ::crystal::is_closed_group ( const std::vector< SymmetryOperation > & operations)

Whether a list of operations is a whole group: closed under composition, up to lattice translations.

A list that is not – an operation missing or mistyped – cannot be used as given.

◆ laue_orbit_partners()

std::vector< size_t > occ::crystal::laue_orbit_partners ( const Crystal & c,
const std::vector< Surface > & surfaces,
size_t i )

Positions in surfaces that share a Laue-class orbit with surfaces[i], including i itself.

A single form when the point group is centrosymmetric, a Friedel pair of forms otherwise. Truncating a d-ordered surface list on these groups keeps the cut crystallographically meaningful.

◆ lorentz_polarization()

double occ::crystal::lorentz_polarization ( double two_theta)

Lorentz-polarization factor for an unpolarized source.

Parameters
two_thetathe Bragg angle in radians – note that PowderPeak and PowderPatternSettings both carry degrees.

Diverges as 1/theta^2 at low angle, which is physical: the Lorentz factor really does blow up as the Bragg condition degenerates.

◆ maximal_subgroups() [1/2]

const std::vector< MaximalSubgroup > & occ::crystal::maximal_subgroups ( int space_group_number)

The maximal subgroups of a space group.

Parameters
space_group_numberthe ITA number of the parent, 1-230
Exceptions
std::out_of_rangeif the number is not in 1-230
Note
Klassengleiche relations are tabulated only up to index 9. Maximal isomorphic subgroups are infinite in number, so no finite table can be complete.

◆ maximal_subgroups() [2/2]

std::vector< MaximalSubgroup > occ::crystal::maximal_subgroups ( int space_group_number,
SubgroupType type )

The maximal subgroups of a given type.

◆ monoclinic_cell()

UnitCell occ::crystal::monoclinic_cell ( double a,
double b,
double c,
double angle )

Construct an orthorhombic unit cell from three given lengths and one angle.

◆ muldin()

Eigen::MatrixXd occ::crystal::muldin ( const Eigen::VectorXd & x)

◆ orthorhombic_cell()

UnitCell occ::crystal::orthorhombic_cell ( double a,
double b,
double c )

Construct an orthorhombic unit cell from three given lengths.

◆ rhombohedral_cell()

UnitCell occ::crystal::rhombohedral_cell ( double length,
double angle )

Construct a rhombohedral unit cell from a given length and angle.

◆ structure_factors()

CVec occ::crystal::structure_factors ( const Crystal & crystal,
const std::vector< PowderPeak > & reflections,
bool debye_waller = true )

Structure factors F(hkl) for the given reflections.

\[ F(h) = \sum_j occ_j \, f_j(s) \, \exp(2 \pi i \, h \cdot r_j) \]

summed over the unit cell atoms, with \( s = \sin\theta/\lambda = 1/(2d) \).

◆ subgroup_paths()

std::vector< SubgroupPath > occ::crystal::subgroup_paths ( int space_group_number,
const SubgroupSearchParameters & params = {} )

All subgroups reachable from a space group, by traversing the graph of maximal-subgroup relations.

Composes the basis change and origin shift along each path. Paths reaching the same subgroup by the same transformation are deduplicated.

Note
These are paths, not distinct subgroups. Two different descents can land on the same subgroup carrying different transformations, and both are reported. For example P2_1/c reaches P1 at index 4 three times – via P-1, via P2_1 and via Pc – and since P1 is unconstrained in its origin, all three are in fact the same subgroup. The descent route is itself meaningful (it is what Bilbao's SUBGROUPGRAPH shows), so they are kept; deduplicate on the actual symmetry operations if you want distinct subgroups.
Subgroups are reported individually, not grouped into conjugacy classes under the affine normalizer (which is how Bilbao presents them).

◆ tetragonal_cell()

UnitCell occ::crystal::tetragonal_cell ( double a,
double c )

Construct a tetragonal unit cell from two given lengths.

◆ to_json() [1/4]

void occ::crystal::to_json ( nlohmann::json & j,
const AsymmetricUnit &  )

◆ to_json() [2/4]

void occ::crystal::to_json ( nlohmann::json & j,
const CrystalAtomRegion &  )

◆ to_json() [3/4]

void occ::crystal::to_json ( nlohmann::json & j,
const CrystalDimers &  )

◆ to_json() [4/4]

void occ::crystal::to_json ( nlohmann::json & j,
const UnitCell &  )

◆ to_standard_setting()

Crystal occ::crystal::to_standard_setting ( const Crystal & crystal,
double tolerance = 1e-4 )

Re-describe a crystal in the standard (ITA reference) setting of its space group.

P2_1/c, P2_1/a and P2_1/n are all space group 14, and tabulated data – including the subgroup relations here – is given for the standard setting only. Real structures frequently are not in it: of 47 experimental structures checked, several were P2_1/a or P2_1/n. Converting first makes the tables apply.

The structure is unchanged; only its description is.

◆ to_subgroup()

Crystal occ::crystal::to_subgroup ( const Crystal & crystal,
const SubgroupTransform & transform,
double tolerance = 1e-4,
bool molecular_asymmetric_unit = true )

Re-describe a crystal in one of its subgroups.

The structure itself is unchanged – the same atoms in the same places. What changes is the description: the cell is transformed by \(P\) (for a klassengleiche relation this is a supercell, so \(\det P > 1\) and the atoms are tiled), the origin is shifted by \(p\), and the asymmetric unit is re-derived under the subgroup's symmetry, splitting orbits that the parent held together.

The subgroup's symmetry operations are taken directly from its space group number: because the transformation is tabulated, no symmetry identification is needed.

The asymmetric unit is chosen molecule by molecule, so a molecule comes through whole wherever the subgroup's symmetry allows it – see with_molecular_asymmetric_unit. Pass molecular_asymmetric_unit = false to take the cheaper atom-by-atom choice, which is equally valid but can scatter a molecule across symmetry images.

Parameters
crystalthe parent structure
transformthe subgroup relation to apply
tolerancefractional-coordinate tolerance for matching atoms
molecular_asymmetric_unitkeep molecules intact in the asymmetric unit
Returns
the same structure, described in the subgroup
Exceptions
std::runtime_errorif the subgroup's symmetry does not in fact hold for the transformed structure (which would mean the transformation and the subgroup's standard setting disagree)

◆ triclinic_cell()

UnitCell occ::crystal::triclinic_cell ( double a,
double b,
double c,
double alpha,
double beta,
double gamma )

Construct an orthorhombic unit cell from three given lengths and three angles.

◆ unique_reflections()

std::vector< PowderPeak > occ::crystal::unique_reflections ( const Crystal & crystal,
double d_min )

Enumerate the symmetry-unique reflections with d >= d_min.

Reflections are reduced under the Laue group (the rotation parts of the space group, plus inversion by Friedel's law). Each returned peak carries the multiplicity of its orbit. Only hkl, d and multiplicity are set.

◆ with_grouped_asymmetric_unit()

Crystal occ::crystal::with_grouped_asymmetric_unit ( const Crystal & crystal,
const IVec & groups,
double tolerance = 1e-4 )

Re-choose a crystal's asymmetric unit so that groups of atoms stay together.

The asymmetric unit is a choice: any set of atoms that generates the unit cell exactly once under the space group will do. Picking one representative per orbit in whatever order the atoms happen to come in is valid but chemically useless – it can scatter a molecule across several symmetry images, so the asymmetric unit is a handful of atoms from here and a handful from there.

Walking the atoms group by group instead makes each group land in the asymmetric unit whole, wherever the symmetry permits it. Where it does not – a group sitting on a special position, mapped onto itself by part of the group – only its own asymmetric part can be taken, which is correct and unavoidable.

Parameters
crystalthe structure to re-describe (unchanged; only the choice of asymmetric unit differs)
groupsone entry per unit cell atom, in the order of crystal.unit_cell_atoms(), giving the group that atom belongs to. Atoms sharing a value are kept together where symmetry allows.
tolerancefractional-coordinate tolerance for matching atoms
Exceptions
std::invalid_argumentif groups is not one entry per unit cell atom

◆ with_molecular_asymmetric_unit()

Crystal occ::crystal::with_molecular_asymmetric_unit ( const Crystal & crystal,
double tolerance = 1e-4 )

Re-choose the asymmetric unit so that whole molecules stay together.

with_grouped_asymmetric_unit with the groups taken from the crystal's own molecules. This is what makes "Z' = 1 with the whole molecule as the asymmetric unit" a construction rather than a coincidence.

◆ xray_form_factor() [1/2]

std::optional< XrayFormFactor > occ::crystal::xray_form_factor ( int atomic_number)

Look up the neutral atom for an atomic number (1-98); nullopt if out of range.

Hydrogen is the bonded "H".

◆ xray_form_factor() [2/2]

std::optional< XrayFormFactor > occ::crystal::xray_form_factor ( std::string_view label)

Look up a form factor by scattering-type label, e.g.

"C", "Na1+", "O2-".

Labels follow the cctbx/International Tables spelling: the element symbol, optionally followed by the charge as digit-then-sign. The table also holds the valence-state entries "Cval" and "Sival".

"H" is not Waasmaier & Kirfel's hydrogen but cctbx's fit to the more contracted Stewart, Davidson & Simpson (1965) bonded hydrogen, which is what cctbx and rinse-descriptor scatter hydrogen with. The free atom is "Hiso".

Returns
nullopt if the label is not in the table.

◆ z_prime()

double occ::crystal::z_prime ( const Crystal & crystal)

The number of molecules in the asymmetric unit, Z'.

\[ Z' = \frac{Z}{\text{multiplicity of the general position}} \]

i.e. the number of molecules in the unit cell divided by the number of symmetry operations. \(Z' < 1\) means the molecule sits on a special position: it is mapped onto itself by some symmetry operation of the crystal, so only a fraction of it (a half for an inversion centre, a third for a 3-fold, ...) is crystallographically independent. Benzene in Pbca has \(Z' = 1/2\).