Skip to content

Commit

Permalink
Merge pull request #6 from ajjackson/test
Browse files Browse the repository at this point in the history
Add a test for get_spacegroup, update for modern spglib
  • Loading branch information
ajjackson authored May 28, 2024
2 parents 1c8b060 + fbad7bf commit 1272f70
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 18 deletions.
38 changes: 20 additions & 18 deletions mctools/generic/get_spacegroup.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,43 @@
# -*- coding: utf-8 -*-

import argparse
import os
from pathlib import Path
from typing import Optional

import ase.io
import spglib


def get_spacegroup(filename=False, format=False):
def get_default_file() -> Path:
for candidate in ("geometry.in", "POSCAR", "castep.cell"):
if (structure_file := Path.cwd() / candidate).is_file():
return structure_file

if filename:
pass
elif os.path.isfile('geometry.in'):
filename = 'geometry.in'
elif os.path.isfile('POSCAR'):
filename = 'POSCAR'
else:
raise Exception('No input file!')
raise ValueError("Input file not specified, no default found.")

if format:
atoms = ase.io.read(filename, format=format)
else:
atoms = ase.io.read(filename)

def get_spacegroup(filename: Optional[Path] = None,
filetype: Optional[str] = None):

if filename is None:
filename = get_default_file()

atoms = ase.io.read(str(filename), format=filetype)
cell = (atoms.cell.array, atoms.get_scaled_positions(), atoms.numbers)

print("| Threshold / Å | Space group |")
print("|---------------|-------------------|")

for threshold in (1e-5, 1e-4, 5e-4, 1e-3, 5e-3, 1e-2, 5e-2, 1e-1):
print("| {0:0.5f} | {1: <16} |".format(
threshold, spglib.get_spacegroup(atoms, symprec=threshold)))
threshold, spglib.get_spacegroup(cell, symprec=threshold)))


def main():
parser = argparse.ArgumentParser()
parser.add_argument('filename', action='store', default=False,
parser.add_argument("filename", type=Path, default=None, nargs="?",
help="Input structure file")
parser.add_argument('-f', '--format', action='store', default=False,
parser.add_argument("-f", "--filetype", type=str, default=None,
help="File format for ASE importer")
args = parser.parse_args()
get_spacegroup(filename=args.filename, format=args.format)
get_spacegroup(filename=args.filename, filetype=args.filetype)
51 changes: 51 additions & 0 deletions tests/test_get_spacegroup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import textwrap

import ase.build
from numpy import logical_not
from numpy.random import RandomState
import pytest

from mctools.generic.get_spacegroup import get_spacegroup


FILENAME = "cu_rattled.extxyz"

REF_TEXT = textwrap.dedent(
"""\
| Threshold / Å | Space group |
|---------------|-------------------|
| 0.00001 | P1 (1) |
| 0.00010 | P1 (1) |
| 0.00050 | Pm (6) |
| 0.00100 | Pm (6) |
| 0.00500 | Pmc2_1 (26) |
| 0.01000 | Fm-3m (225) |
| 0.05000 | Fm-3m (225) |
| 0.10000 | Fm-3m (225) |
"""
)


@pytest.fixture
def symmetry_broken_cu() -> ase.Atoms:
atoms = ase.build.bulk("Cu", cubic=True) * (2, 2, 2)

rng = RandomState(seed=1)

# Break symmetry by up to 0.01 on a mirror plane
xy_plane = atoms.positions[:, 2] == 0.0
atoms.positions[xy_plane, :2] += 5e-3 - 1e-2 * rng.rand(xy_plane.sum(), 2)

# Break symmetry by up to 0.0001 elsewhere
off_plane = logical_not(xy_plane)
atoms.positions[off_plane] += 5e-5 - 1e-4 * rng.rand(off_plane.sum(), 3)

return atoms


def test_get_spacegroup(symmetry_broken_cu, tmp_path, capsys) -> None:
symmetry_broken_cu.write(tmp_path / FILENAME)
get_spacegroup(filename=str(tmp_path / FILENAME))
captured = capsys.readouterr()

assert captured.out == REF_TEXT

0 comments on commit 1272f70

Please sign in to comment.