Skip to content

space_group

SpaceGroup

Represent a crystallographic space group, including all necessary symmetry operations in fractional coordinates, the international tables number from 1-230, and the international tables symbol.

Attributes:

Name Type Description
symbol str

The international tables short space group symbol

full_symbol str

The full international tables space group symbol

choice str

The space group choice (if applicable)

centering str

The space group centering (if applicable)

schoenflies str

The Schoenflies space group symbol

centrosymmetric bool

Whether or not the space group is centrosymmetric

symmetry_operations List[SymmetryOperation]

List of symmetry operations making up this space group

Source code in chmpy/crystal/space_group.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
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
504
505
506
507
508
509
510
511
class SpaceGroup:
    """
    Represent a crystallographic space group, including
    all necessary symmetry operations in fractional coordinates,
    the international tables number from 1-230, and the international
    tables symbol.

    Attributes:
        symbol (str): The international tables short space group symbol
        full_symbol (str): The full international tables space group symbol
        choice (str): The space group choice (if applicable)
        centering (str): The space group centering (if applicable)
        schoenflies (str): The Schoenflies space group symbol
        centrosymmetric (bool): Whether or not the space group is centrosymmetric
        symmetry_operations (List[SymmetryOperation]): List of symmetry operations
            making up this space group
    """

    def __init__(self, international_tables_number, choice=""):
        if international_tables_number < 1 or international_tables_number > 230:
            raise ValueError("Space group number must be between [1, 230]")
        self.international_tables_number = international_tables_number
        if international_tables_number in SG_DEFAULT_SETTING_CHOICE and not choice:
            choice = SG_DEFAULT_SETTING_CHOICE[international_tables_number]
        if not choice:
            sgdata = SG_FROM_NUMBER[str(international_tables_number)][0]
        else:
            candidates = SG_FROM_NUMBER[str(international_tables_number)]
            for candidate in candidates:
                if choice == candidate.choice:
                    sgdata = candidate
                    break
            else:
                raise ValueError(f"Could not find choice {choice}")
        self.symbol = sgdata.short
        self.full_symbol = sgdata.full
        self.choice = sgdata.choice
        self.centering = sgdata.centering
        if choice not in ("b", "c", "R"):
            choice = None
        self._point_group = PointGroup.from_number(sgdata.pointgroup, choice=choice)
        self.schoenflies = sgdata.schoenflies
        self.centrosymmetric = sgdata.centrosymmetric
        symops = sgdata.symops
        self.symmetry_operations = [
            SymmetryOperation.from_integer_code(s) for s in symops
        ]
        self._sgdata = sgdata

    @property
    def cif_section(self) -> str:
        "Representation of the SpaceGroup in CIF files"
        return "\n".join(
            f"{i} {sym.cif_form}"
            for i, sym in enumerate(self.symmetry_operations, start=1)
        )

    def crystal17_spacegroup_symbol(self):
        tokens = []
        s = self._sgdata.international.upper()
        if "=" in s:
            s = s.split("=")[-1]
        s = iter(s)
        for ch in s:
            if ch == "_":
                tokens[-1] += next(s)
            elif ch == "/":
                tokens[-1] += ch + next(s)
            elif ch == "-":
                tokens.append(ch + next(s))
            else:
                tokens.append(ch)
        return " ".join(tokens)

    @property
    def crystal_system(self) -> str:
        "The crystal system of the space group e.g. triclinic, monoclinic etc."
        sg = self.international_tables_number
        if sg <= 0 or sg >= 231:
            raise ValueError("International spacegroup number must be between 1-230")
        if sg <= 2:
            return "triclinic"
        if sg <= 16:
            return "monoclinic"
        if sg <= 74:
            return "orthorhombic"
        if sg <= 142:
            return "tetragonal"
        if sg <= 167:
            return "trigonal"
        if sg <= 194:
            return "hexagonal"
        return "cubic"

    @property
    def is_symmorphic(self) -> bool:
        """
        Whether this space group is symmorphic.

        A space group is symmorphic if it can be generated by its point group
        (acting through a common origin) together with the lattice translations,
        i.e. it contains no intrinsic screw axes or glide planes. There are 73
        symmorphic space groups among the 230.

        Examples:
            >>> SpaceGroup(225).is_symmorphic  # Fm-3m
            True
            >>> SpaceGroup(14).is_symmorphic  # P2_1/c
            False
            >>> SpaceGroup(23).is_symmorphic  # I222
            True
            >>> SpaceGroup(24).is_symmorphic  # I2_12_12_1
            False
        """
        return _is_symmorphic(self.symmetry_operations)

    def is_systematically_absent(self, hkl):
        """
        Whether reflections are systematically absent (forbidden by symmetry).

        A reflection h is systematically absent if some symmetry operation
        (R, t) leaves it invariant (h R = h) but introduces a non-integral
        phase (h . t is not an integer), forcing the structure factor to zero
        regardless of the atomic content. This single rule reproduces all of the
        integral (centering), zonal (glide-plane) and serial (screw-axis)
        reflection conditions of the International Tables.

        Args:
            hkl: a single (3,) reflection index or an (N, 3) array of indices

        Returns:
            bool for a single reflection, or an (N,) boolean array, where True
            means the reflection is systematically absent.

        Examples:
            >>> sg = SpaceGroup(14)  # P2_1/c: 2_1 || b, c-glide perp b
            >>> sg.is_systematically_absent((0, 1, 0))  # 0k0, k odd
            True
            >>> sg.is_systematically_absent((1, 0, 1))  # h0l, l odd
            True
            >>> sg.is_systematically_absent([[0, 2, 0], [1, 0, 2]]).tolist()
            [False, False]
        """
        hkl_array = np.atleast_2d(np.asarray(hkl, dtype=int))
        absent = np.zeros(len(hkl_array), dtype=bool)
        for op in self.symmetry_operations:
            rotation = np.round(op.rotation).astype(int)
            # exact phase in twelfths (translations are multiples of 1/12)
            translation = np.round(op.translation * 12).astype(int)
            # reflections invariant under the rotation part: h R = h
            invariant = np.all(hkl_array @ rotation == hkl_array, axis=1)
            if not invariant.any():
                continue
            phase = hkl_array @ translation
            absent |= invariant & (phase % 12 != 0)
        if np.ndim(hkl) == 1:
            return bool(absent[0])
        return absent

    def reflection_conditions(self):
        """
        The reflection conditions (systematic absences) for this space group,
        grouped by reflection class as in the International Tables.

        Returns:
            list[ReflectionCondition]: one entry per reflection class that
            carries a condition, ordered general -> zonal -> axial. An empty
            list means there are no conditions (e.g. P1, P-1).

        Examples:
            >>> for c in SpaceGroup(14).reflection_conditions():  # P2_1/c
            ...     print(c)
            h0l: l=2n
            0k0: k=2n
        """
        from .reflection_conditions import reflection_conditions

        return reflection_conditions(self.symmetry_operations)

    @property
    def point_group(self):
        "the point group of this space group"
        return self._point_group

    @property
    def pg(self):
        "alias for `self.point_group`"
        return self._point_group

    @property
    def sym(self) -> str:
        "alias for `self.symbol`"
        return self.symbol

    @property
    def symbol_unicode(self) -> str:
        "the space group symbol with unicode subscripts"
        symbol = deepcopy(self.full_symbol)
        if "_" in symbol:
            tokens = symbol.split("_")
            symbol = tokens[0] + "".join(subscript(x[0]) + x[1:] for x in tokens[1:])
        if "-" in symbol:
            tokens = symbol.split("-")
            symbol = tokens[0] + "".join(overline(x[0]) + x[1:] for x in tokens[1:])
        return symbol

    @property
    def symops(self):
        "alias for `self.symmetry_operations`"
        return self.symmetry_operations

    @property
    def laue_class(self) -> str:
        "the Laue class of the point group associated with this space group"
        return self._point_group.laue_group

    @property
    def lattice_type(self) -> str:
        "the lattice type of this space group e.g. rhombohedral, hexagonal etc."
        inum = self.international_tables_number
        if inum < 143 or inum > 194:
            return self.crystal_system
        if inum in (146, 148, 155, 160, 161, 166, 167):
            if self.choice == "H":
                return "hexagonal"
            elif self.choice == "R":
                return "rhombohedral"
        else:
            return "hexagonal"

    @property
    def latt(self) -> int:
        """
        The SHELX LATT number associated with this space group. Returns
        a negative if there is no inversion.

        Options are
        ```
        1: P,
        2: I,
        3: rhombohedral obverse on hexagonal axes,
        4: F,
        5: A,
        6: B,
        7: C
        ```

        Examples:
            >>> P1 = SpaceGroup(1)
            >>> P21c = SpaceGroup(14)
            >>> I41 = SpaceGroup(14)
            >>> R3bar = SpaceGroup(148)
            >>> P1.latt
            -1
            >>> P21c.latt
            1
            >>> R3bar.latt
            3

        Returns:
            int: the SHELX LATT number of this space group
        """
        centering_to_latt = {
            "primitive": 1,  # P
            "body": 2,  # I
            "rcenter": 3,  # R
            "face": 4,  # F
            "aface": 5,  # A
            "bface": 6,  # B
            "cface": 7,  # C
        }
        if not self.centrosymmetric:
            return -centering_to_latt[self.centering]
        return centering_to_latt[self.centering]

    def __len__(self):
        return len(self.symmetry_operations)

    def ordered_symmetry_operations(self):
        "The symmetry operations of this space group in order (with identiy first)"
        # make sure we do the unit symop first
        unity = 0
        for i, s in enumerate(self.symmetry_operations):
            if s.is_identity():
                unity = i
                break
        else:
            raise ValueError(
                "Could not find identity symmetry_operation -- invalide space group"
            )
        other_symops = (
            self.symmetry_operations[:unity] + self.symmetry_operations[unity + 1 :]
        )
        return [self.symmetry_operations[unity]] + other_symops

    def apply_all_symops(self, coordinates: np.ndarray):
        """
        For a given set of coordinates, apply all symmetry
        operations in this space group, yielding a set subject
        to only translational symmetry (i.e. a unit cell).
        Assumes the input coordinates are fractional.

        Args:
            coordinates (np.ndarray): (N, 3) set of fractional coordinates

        Returns:
            Tuple[np.ndarray, np.ndarray]: a (MxN) array of generator symop integers
                and an (MxN, 3) array of coordinates where M is the number of symmetry
                operations in this space group.
        """
        nsites = len(coordinates)
        transformed = np.empty((nsites * len(self), 3))
        generator_symop = np.empty(nsites * len(self), dtype=np.int32)

        # make sure we do the unit symop first
        unity = 0
        for i, s in enumerate(self.symmetry_operations):
            if s.integer_code == 16484:
                unity = i
                break
        transformed[0:nsites] = coordinates
        generator_symop[0:nsites] = 16484
        other_symops = (
            self.symmetry_operations[:unity] + self.symmetry_operations[unity + 1 :]
        )
        for i, s in enumerate(other_symops, start=1):
            transformed[i * nsites : (i + 1) * nsites] = s(coordinates)
            generator_symop[i * nsites : (i + 1) * nsites] = s.integer_code
        return generator_symop, transformed

    def __repr__(self):
        return f"<{self.__class__.__name__} {self.international_tables_number}: {self.full_symbol}>"

    def __eq__(self, other):
        return (
            self.international_tables_number == other.international_tables_number
        ) and (self.choice == other.choice)

    def __hash__(self):
        return hash((self.international_tables_number, self.choice))

    def reduced_symmetry_operations(self):
        "returns a reduced list of symmetry operations"
        return reduced_symmetry_list(self.symmetry_operations, self.latt)

    def has_hexagonal_rhombohedral_choices(self) -> bool:
        "returns true if this space group could be"
        "represented as hexagonal or rhombohedral"
        return self.international_tables_number in (146, 148, 155, 160, 161, 166, 167)

    @classmethod
    def from_symmetry_operations(cls, symops, expand_latt=None):
        """
        Find a matching spacegroup for a given set of symmetry
        operations, optionally treating them as a reduced set of
        symmetry operations and expanding them based on the lattice
        type.

        Args:
            symops (List[SymmetryOperation]): a reduced or full list
                of symmetry operations
            expand_latt (int, optional): the SHELX LATT number to expand
                this list of symmetry operations

        Returns:
            SpaceGroup: the matching `SpaceGroup` for the provided symmetry
                operations and LATT

        """
        if expand_latt is not None:
            if not -8 < expand_latt < 8:
                raise ValueError("expand_latt must be between [-7, 7]")
            symops = expanded_symmetry_list(symops, expand_latt)
        encoded = tuple(sorted(s.integer_code for s in symops))
        if encoded not in SG_FROM_SYMOPS:
            raise ValueError(
                "Could not find matching spacegroup for "
                "the following symops:\n{}".format(
                    "\n".join(str(s) for s in sorted(symops))
                )
            )
        else:
            sgdata = SG_FROM_SYMOPS[encoded]
            return SpaceGroup(sgdata.number, choice=sgdata.choice)

    @classmethod
    def from_symbol(cls, symbol):
        symbol = symbol.replace(" ", "")
        sgdata = SG_FROM_SYMBOL.get(symbol, None)
        special_cases = {
            "P21/a": "P12_1/a1",
            "P21/n": "P12_1/n1",
        }
        symbol = special_cases.get(symbol, symbol)
        if sgdata is None:
            for number, groups in SG_FROM_NUMBER.items():
                if int(number) > 14:
                    continue
                for g in groups:
                    intl = g.international.split("=")[-1]
                    if symbol == intl:
                        sgdata = g
                        break
                    elif symbol == intl.replace("_", ""):
                        sgdata = g
                        break
                if sgdata is not None:
                    break
            else:
                raise ValueError(f"Could not find matching space group for '{symbol}'")

        return SpaceGroup(sgdata.number, choice=sgdata.choice)

cif_section property

Representation of the SpaceGroup in CIF files

crystal_system property

The crystal system of the space group e.g. triclinic, monoclinic etc.

is_symmorphic property

Whether this space group is symmorphic.

A space group is symmorphic if it can be generated by its point group (acting through a common origin) together with the lattice translations, i.e. it contains no intrinsic screw axes or glide planes. There are 73 symmorphic space groups among the 230.

Examples:

>>> SpaceGroup(225).is_symmorphic  # Fm-3m
True
>>> SpaceGroup(14).is_symmorphic  # P2_1/c
False
>>> SpaceGroup(23).is_symmorphic  # I222
True
>>> SpaceGroup(24).is_symmorphic  # I2_12_12_1
False

latt property

The SHELX LATT number associated with this space group. Returns a negative if there is no inversion.

Options are

1: P,
2: I,
3: rhombohedral obverse on hexagonal axes,
4: F,
5: A,
6: B,
7: C

Examples:

>>> P1 = SpaceGroup(1)
>>> P21c = SpaceGroup(14)
>>> I41 = SpaceGroup(14)
>>> R3bar = SpaceGroup(148)
>>> P1.latt
-1
>>> P21c.latt
1
>>> R3bar.latt
3

Returns:

Name Type Description
int int

the SHELX LATT number of this space group

lattice_type property

the lattice type of this space group e.g. rhombohedral, hexagonal etc.

laue_class property

the Laue class of the point group associated with this space group

pg property

alias for self.point_group

point_group property

the point group of this space group

sym property

alias for self.symbol

symbol_unicode property

the space group symbol with unicode subscripts

symops property

alias for self.symmetry_operations

apply_all_symops(coordinates)

For a given set of coordinates, apply all symmetry operations in this space group, yielding a set subject to only translational symmetry (i.e. a unit cell). Assumes the input coordinates are fractional.

Parameters:

Name Type Description Default
coordinates ndarray

(N, 3) set of fractional coordinates

required

Returns:

Type Description

Tuple[np.ndarray, np.ndarray]: a (MxN) array of generator symop integers and an (MxN, 3) array of coordinates where M is the number of symmetry operations in this space group.

Source code in chmpy/crystal/space_group.py
def apply_all_symops(self, coordinates: np.ndarray):
    """
    For a given set of coordinates, apply all symmetry
    operations in this space group, yielding a set subject
    to only translational symmetry (i.e. a unit cell).
    Assumes the input coordinates are fractional.

    Args:
        coordinates (np.ndarray): (N, 3) set of fractional coordinates

    Returns:
        Tuple[np.ndarray, np.ndarray]: a (MxN) array of generator symop integers
            and an (MxN, 3) array of coordinates where M is the number of symmetry
            operations in this space group.
    """
    nsites = len(coordinates)
    transformed = np.empty((nsites * len(self), 3))
    generator_symop = np.empty(nsites * len(self), dtype=np.int32)

    # make sure we do the unit symop first
    unity = 0
    for i, s in enumerate(self.symmetry_operations):
        if s.integer_code == 16484:
            unity = i
            break
    transformed[0:nsites] = coordinates
    generator_symop[0:nsites] = 16484
    other_symops = (
        self.symmetry_operations[:unity] + self.symmetry_operations[unity + 1 :]
    )
    for i, s in enumerate(other_symops, start=1):
        transformed[i * nsites : (i + 1) * nsites] = s(coordinates)
        generator_symop[i * nsites : (i + 1) * nsites] = s.integer_code
    return generator_symop, transformed

from_symmetry_operations(symops, expand_latt=None) classmethod

Find a matching spacegroup for a given set of symmetry operations, optionally treating them as a reduced set of symmetry operations and expanding them based on the lattice type.

Parameters:

Name Type Description Default
symops List[SymmetryOperation]

a reduced or full list of symmetry operations

required
expand_latt int

the SHELX LATT number to expand this list of symmetry operations

None

Returns:

Name Type Description
SpaceGroup

the matching SpaceGroup for the provided symmetry operations and LATT

Source code in chmpy/crystal/space_group.py
@classmethod
def from_symmetry_operations(cls, symops, expand_latt=None):
    """
    Find a matching spacegroup for a given set of symmetry
    operations, optionally treating them as a reduced set of
    symmetry operations and expanding them based on the lattice
    type.

    Args:
        symops (List[SymmetryOperation]): a reduced or full list
            of symmetry operations
        expand_latt (int, optional): the SHELX LATT number to expand
            this list of symmetry operations

    Returns:
        SpaceGroup: the matching `SpaceGroup` for the provided symmetry
            operations and LATT

    """
    if expand_latt is not None:
        if not -8 < expand_latt < 8:
            raise ValueError("expand_latt must be between [-7, 7]")
        symops = expanded_symmetry_list(symops, expand_latt)
    encoded = tuple(sorted(s.integer_code for s in symops))
    if encoded not in SG_FROM_SYMOPS:
        raise ValueError(
            "Could not find matching spacegroup for "
            "the following symops:\n{}".format(
                "\n".join(str(s) for s in sorted(symops))
            )
        )
    else:
        sgdata = SG_FROM_SYMOPS[encoded]
        return SpaceGroup(sgdata.number, choice=sgdata.choice)

has_hexagonal_rhombohedral_choices()

returns true if this space group could be

Source code in chmpy/crystal/space_group.py
def has_hexagonal_rhombohedral_choices(self) -> bool:
    "returns true if this space group could be"
    "represented as hexagonal or rhombohedral"
    return self.international_tables_number in (146, 148, 155, 160, 161, 166, 167)

is_systematically_absent(hkl)

Whether reflections are systematically absent (forbidden by symmetry).

A reflection h is systematically absent if some symmetry operation (R, t) leaves it invariant (h R = h) but introduces a non-integral phase (h . t is not an integer), forcing the structure factor to zero regardless of the atomic content. This single rule reproduces all of the integral (centering), zonal (glide-plane) and serial (screw-axis) reflection conditions of the International Tables.

Parameters:

Name Type Description Default
hkl

a single (3,) reflection index or an (N, 3) array of indices

required

Returns:

Type Description

bool for a single reflection, or an (N,) boolean array, where True

means the reflection is systematically absent.

Examples:

>>> sg = SpaceGroup(14)  # P2_1/c: 2_1 || b, c-glide perp b
>>> sg.is_systematically_absent((0, 1, 0))  # 0k0, k odd
True
>>> sg.is_systematically_absent((1, 0, 1))  # h0l, l odd
True
>>> sg.is_systematically_absent([[0, 2, 0], [1, 0, 2]]).tolist()
[False, False]
Source code in chmpy/crystal/space_group.py
def is_systematically_absent(self, hkl):
    """
    Whether reflections are systematically absent (forbidden by symmetry).

    A reflection h is systematically absent if some symmetry operation
    (R, t) leaves it invariant (h R = h) but introduces a non-integral
    phase (h . t is not an integer), forcing the structure factor to zero
    regardless of the atomic content. This single rule reproduces all of the
    integral (centering), zonal (glide-plane) and serial (screw-axis)
    reflection conditions of the International Tables.

    Args:
        hkl: a single (3,) reflection index or an (N, 3) array of indices

    Returns:
        bool for a single reflection, or an (N,) boolean array, where True
        means the reflection is systematically absent.

    Examples:
        >>> sg = SpaceGroup(14)  # P2_1/c: 2_1 || b, c-glide perp b
        >>> sg.is_systematically_absent((0, 1, 0))  # 0k0, k odd
        True
        >>> sg.is_systematically_absent((1, 0, 1))  # h0l, l odd
        True
        >>> sg.is_systematically_absent([[0, 2, 0], [1, 0, 2]]).tolist()
        [False, False]
    """
    hkl_array = np.atleast_2d(np.asarray(hkl, dtype=int))
    absent = np.zeros(len(hkl_array), dtype=bool)
    for op in self.symmetry_operations:
        rotation = np.round(op.rotation).astype(int)
        # exact phase in twelfths (translations are multiples of 1/12)
        translation = np.round(op.translation * 12).astype(int)
        # reflections invariant under the rotation part: h R = h
        invariant = np.all(hkl_array @ rotation == hkl_array, axis=1)
        if not invariant.any():
            continue
        phase = hkl_array @ translation
        absent |= invariant & (phase % 12 != 0)
    if np.ndim(hkl) == 1:
        return bool(absent[0])
    return absent

ordered_symmetry_operations()

The symmetry operations of this space group in order (with identiy first)

Source code in chmpy/crystal/space_group.py
def ordered_symmetry_operations(self):
    "The symmetry operations of this space group in order (with identiy first)"
    # make sure we do the unit symop first
    unity = 0
    for i, s in enumerate(self.symmetry_operations):
        if s.is_identity():
            unity = i
            break
    else:
        raise ValueError(
            "Could not find identity symmetry_operation -- invalide space group"
        )
    other_symops = (
        self.symmetry_operations[:unity] + self.symmetry_operations[unity + 1 :]
    )
    return [self.symmetry_operations[unity]] + other_symops

reduced_symmetry_operations()

returns a reduced list of symmetry operations

Source code in chmpy/crystal/space_group.py
def reduced_symmetry_operations(self):
    "returns a reduced list of symmetry operations"
    return reduced_symmetry_list(self.symmetry_operations, self.latt)

reflection_conditions()

The reflection conditions (systematic absences) for this space group, grouped by reflection class as in the International Tables.

Returns:

Type Description

list[ReflectionCondition]: one entry per reflection class that

carries a condition, ordered general -> zonal -> axial. An empty

list means there are no conditions (e.g. P1, P-1).

Examples:

>>> for c in SpaceGroup(14).reflection_conditions():  # P2_1/c
...     print(c)
h0l: l=2n
0k0: k=2n
Source code in chmpy/crystal/space_group.py
def reflection_conditions(self):
    """
    The reflection conditions (systematic absences) for this space group,
    grouped by reflection class as in the International Tables.

    Returns:
        list[ReflectionCondition]: one entry per reflection class that
        carries a condition, ordered general -> zonal -> axial. An empty
        list means there are no conditions (e.g. P1, P-1).

    Examples:
        >>> for c in SpaceGroup(14).reflection_conditions():  # P2_1/c
        ...     print(c)
        h0l: l=2n
        0k0: k=2n
    """
    from .reflection_conditions import reflection_conditions

    return reflection_conditions(self.symmetry_operations)