Skip to content

crystallography

crystallography

apply_atom_site_aniso_symmetry_constraints(atom_site_aniso, name_hm, coord_code, _wyckoff_letter, site_fract)

Apply symmetry constraints to anisotropic ADP tensor components.

Uses the Peterse-Palm probe technique to determine which tensor components are constrained by the site symmetry, then delegates to cryspy's vibration_constraints to enforce them.

Parameters:

Name Type Description Default
atom_site_aniso dict[str, float]

Dictionary with keys 'adp_11''adp_23'. Modified in place.

required
name_hm str

Hermann-Mauguin symbol of the space group.

required
coord_code str | None

IT coordinate system code.

required
_wyckoff_letter str

Wyckoff position letter (unused, reserved).

required
site_fract tuple[float, float, float]

Fractional coordinates of the atom site.

required

Returns:

Type Description
tuple[dict[str, float], tuple[bool, ...]]

The atom_site_aniso dictionary with constrained values, and a 6-tuple of booleans indicating which components remain free for refinement (True = free, False = fixed by symmetry).

Source code in src/easydiffraction/crystallography/crystallography.py
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
def apply_atom_site_aniso_symmetry_constraints(
    atom_site_aniso: dict[str, float],
    name_hm: str,
    coord_code: str | None,
    _wyckoff_letter: str,
    site_fract: tuple[float, float, float],
) -> tuple[dict[str, float], tuple[bool, ...]]:
    """
    Apply symmetry constraints to anisotropic ADP tensor components.

    Uses the Peterse-Palm probe technique to determine which tensor
    components are constrained by the site symmetry, then delegates to
    cryspy's ``vibration_constraints`` to enforce them.

    Parameters
    ----------
    atom_site_aniso : dict[str, float]
        Dictionary with keys ``'adp_11'`` … ``'adp_23'``.  Modified in
        place.
    name_hm : str
        Hermann-Mauguin symbol of the space group.
    coord_code : str | None
        IT coordinate system code.
    _wyckoff_letter : str
        Wyckoff position letter (unused, reserved).
    site_fract : tuple[float, float, float]
        Fractional coordinates of the atom site.

    Returns
    -------
    tuple[dict[str, float], tuple[bool, ...]]
        The *atom_site_aniso* dictionary with constrained values, and a
        6-tuple of booleans indicating which components remain free for
        refinement (``True`` = free, ``False`` = fixed by symmetry).
    """
    all_free = (True, True, True, True, True, True)

    it_number = get_it_number_by_name_hm_short(name_hm)
    if it_number is None:
        log.error(f"Failed to get IT_number for name_H-M '{name_hm}'")
        return atom_site_aniso, all_free

    ops = _get_general_position_ops(it_number, coord_code)
    if ops is None:
        return atom_site_aniso, all_free

    stabiliser = _site_stabilizer_rotations(ops, site_fract)
    if len(stabiliser) <= 1:
        # Identity only — no ADP constraints
        return atom_site_aniso, all_free

    numb = _calc_adp_constraint_number(stabiliser)
    if numb == 0:
        return atom_site_aniso, all_free

    param_i = (
        atom_site_aniso['adp_11'],
        atom_site_aniso['adp_22'],
        atom_site_aniso['adp_33'],
        atom_site_aniso['adp_12'],
        atom_site_aniso['adp_13'],
        atom_site_aniso['adp_23'],
    )
    sigma_i = (0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
    ref_i = (True, True, True, True, True, True)

    param_i, _sigma_i, ref_i, _constr_i = vibration_constraints(
        numb,
        param_i,
        sigma_i,
        ref_i,
    )

    keys = ('adp_11', 'adp_22', 'adp_33', 'adp_12', 'adp_13', 'adp_23')
    atom_site_aniso.update(dict(zip(keys, param_i, strict=False)))

    return atom_site_aniso, ref_i

apply_atom_site_symmetry_constraints(atom_site, name_hm, coord_code, wyckoff_letter)

Apply symmetry constraints to atom site coordinates.

Parameters:

Name Type Description Default
atom_site dict[str, Any]

Dictionary containing atom position data.

required
name_hm str

Hermann-Mauguin symbol of the space group.

required
coord_code int

Coordinate system code.

required
wyckoff_letter str

Wyckoff position letter.

required

Returns:

Type Description
dict[str, Any]

The atom_site dictionary with applied symmetry constraints.

Source code in src/easydiffraction/crystallography/crystallography.py
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
def apply_atom_site_symmetry_constraints(
    atom_site: dict[str, Any],
    name_hm: str,
    coord_code: int,
    wyckoff_letter: str,
) -> dict[str, Any]:
    """
    Apply symmetry constraints to atom site coordinates.

    Parameters
    ----------
    atom_site : dict[str, Any]
        Dictionary containing atom position data.
    name_hm : str
        Hermann-Mauguin symbol of the space group.
    coord_code : int
        Coordinate system code.
    wyckoff_letter : str
        Wyckoff position letter.

    Returns
    -------
    dict[str, Any]
        The atom_site dictionary with applied symmetry constraints.
    """
    parsed_exprs = _get_wyckoff_exprs(name_hm, coord_code, wyckoff_letter)
    if parsed_exprs is None:
        return atom_site

    _apply_fract_constraints(atom_site, parsed_exprs)
    return atom_site

apply_cell_symmetry_constraints(cell, name_hm)

Apply symmetry constraints to unit cell parameters.

Parameters:

Name Type Description Default
cell dict[str, float]

Dictionary containing lattice parameters.

required
name_hm str

Hermann-Mauguin symbol of the space group.

required

Returns:

Type Description
dict[str, float]

The cell dictionary with applied symmetry constraints.

Source code in src/easydiffraction/crystallography/crystallography.py
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
def apply_cell_symmetry_constraints(
    cell: dict[str, float],
    name_hm: str,
) -> dict[str, float]:
    """
    Apply symmetry constraints to unit cell parameters.

    Parameters
    ----------
    cell : dict[str, float]
        Dictionary containing lattice parameters.
    name_hm : str
        Hermann-Mauguin symbol of the space group.

    Returns
    -------
    dict[str, float]
        The cell dictionary with applied symmetry constraints.
    """
    it_number = get_it_number_by_name_hm_short(name_hm)
    if it_number is None:
        error_msg = f"Failed to get IT_number for name_H-M '{name_hm}'"
        log.error(error_msg)  # TODO: ValueError? Diagnostics?
        return cell

    crystal_system = get_crystal_system_by_it_number(it_number)
    if crystal_system is None:
        error_msg = f"Failed to get crystal system for IT_number '{it_number}'"
        log.error(error_msg)  # TODO: ValueError? Diagnostics?
        return cell

    if crystal_system == 'cubic':
        a = cell['lattice_a']
        cell['lattice_b'] = a
        cell['lattice_c'] = a
        cell['angle_alpha'] = 90.0
        cell['angle_beta'] = 90.0
        cell['angle_gamma'] = 90.0

    elif crystal_system == 'tetragonal':
        a = cell['lattice_a']
        cell['lattice_b'] = a
        cell['angle_alpha'] = 90.0
        cell['angle_beta'] = 90.0
        cell['angle_gamma'] = 90.0

    elif crystal_system == 'orthorhombic':
        cell['angle_alpha'] = 90.0
        cell['angle_beta'] = 90.0
        cell['angle_gamma'] = 90.0

    elif crystal_system in {'hexagonal', 'trigonal'}:
        a = cell['lattice_a']
        cell['lattice_b'] = a
        cell['angle_alpha'] = 90.0
        cell['angle_beta'] = 90.0
        cell['angle_gamma'] = 120.0

    elif crystal_system == 'monoclinic':
        cell['angle_alpha'] = 90.0
        cell['angle_gamma'] = 90.0

    elif crystal_system == 'triclinic':
        pass  # No constraints to apply

    else:
        error_msg = f'Unknown or unsupported crystal system: {crystal_system}'
        log.error(error_msg)  # TODO: ValueError? Diagnostics?

    return cell

space_groups

Space group reference data.

Loads a gzipped, packaged pickle with crystallographic space-group information. The file is part of the distribution; user input is not involved.