Esempio n. 1
0
def load_vasprun(filename):
    from pathlib import Path
    import xml.etree.ElementTree as ET
    from chmpy.crystal import UnitCell, Crystal, AsymmetricUnit, SpaceGroup

    xml = ET.parse(filename)
    root = xml.getroot()
    structures = {}
    atominfo = root.find("atominfo")
    elements = []
    for child in atominfo.findall("array"):
        if child.get("name") == "atoms":
            atoms = child.find("set")
            for atom in atoms.findall("rc"):
                elements.append(Element[atom.find("c").text])

    for structure in root.findall("structure"):
        name = structure.get("name")
        crystal = structure.find("crystal")
        positions = structure.find("varray")
        direct = None
        for child in crystal:
            if child.get("name") == "basis":
                basis = []
                for row in child:
                    basis.append([float(x) for x in row.text.split()])
                direct = np.array(basis)
        pos = []
        for row in positions:
            pos.append([float(x) for x in row.text.split()])
        pos = np.array(pos)
        structures[name] = Crystal(
            UnitCell(direct), SpaceGroup(1), AsymmetricUnit(elements, pos)
        )
    return structures
Esempio n. 2
0
def standardize_crystal(crystal, method="spglib", **kwargs):
    if method != "spglib":
        raise NotImplementedError("Only spglib is currently supported")

    lattice = crystal.unit_cell.direct
    uc_dict = crystal.unit_cell_atoms()
    positions = uc_dict["frac_pos"]
    elements = uc_dict["element"]
    asym_atoms = uc_dict["asym_atom"]
    asym_labels = uc_dict["label"]
    cell = lattice, positions, elements

    reduced_cell = standardize_cell(cell, **kwargs)

    if reduced_cell is None:
        LOG.warn("Could not find reduced cell for crystal %s", crystal)
        return None
    dataset = get_symmetry_dataset(reduced_cell)
    asym_idx = np.unique(dataset["equivalent_atoms"])
    asym_idx = asym_idx[np.argsort(asym_atoms[asym_idx])]
    sg = SpaceGroup(dataset["number"], choice=dataset["choice"])

    reduced_lattice, positions, elements = reduced_cell
    unit_cell = UnitCell(reduced_lattice)
    asym = AsymmetricUnit(
        [Element[x] for x in elements[asym_idx]],
        positions[asym_idx],
        labels=asym_labels[asym_idx],
    )
    return Crystal(unit_cell, sg, asym)
Esempio n. 3
0
def expand_periodic_images(cell, filename, dest=None, supercell=(1, 1, 1)):
    frames = parse_traj_file(filename)
    sg = SpaceGroup(1)
    xyz_strings = []
    for elements, comment, positions in frames:
        asym = AsymmetricUnit(elements, cell.to_fractional(positions))
        c = Crystal(cell, sg, asym).as_P1_supercell(supercell)
        pos = c.to_cartesian(c.asymmetric_unit.positions)
        el = c.asymmetric_unit.elements
        xyz_strings.append(to_xyz_string(el, pos, comment=comment))
    if dest is not None:
        Path(dest).write_text("\n".join(xyz_strings))
    else:
        return "\n".join(xyz_strings)
Esempio n. 4
0
def load_turbomole_string(tmol_string):
    from chmpy.util.unit import units

    "Initialize from an xtb coord string resulting from optimization"
    data = {}
    sections = tmol_string.split("$")
    for section in sections:
        if not section or section.startswith("end"):
            continue
        lines = section.strip().splitlines()
        label = lines[0].strip()
        data[label] = [x.strip() for x in lines[1:]]
    lattice = [] if "lattice bohr" in data else None
    elements = []
    positions = []
    for line in data.pop("coord"):
        x, y, z, el = line.split()
        positions.append((float(x), float(y), float(z)))
        elements.append(Element[el])
    ANGS = units.angstrom(1.0)
    pos_cart = np.array(positions) * ANGS
    result = {
        "positions": pos_cart,
        "elements": elements,
    }
    if lattice is not None:
        for line in data.pop("lattice bohr"):
            lattice.append([float(x) for x in line.split()])
        direct = np.array(lattice) * ANGS
        uc = UnitCell(direct)
        pos_frac = uc.to_fractional(pos_cart)
        asym = AsymmetricUnit(elements, pos_frac)
        result["unit_cell"] = uc
        result["asymmetric_unit"] = asym
        result["space_group"] = SpaceGroup(1)

    result.update(**data)
    return result
Esempio n. 5
0
def detect_symmetry(crystal, method="spglib", **kwargs):
    if method != "spglib":
        raise NotImplementedError("Only spglib is currently supported")

    lattice = crystal.unit_cell.direct
    uc_dict = crystal.unit_cell_atoms()
    positions = uc_dict["frac_pos"]
    elements = uc_dict["element"]
    asym_atoms = uc_dict["asym_atom"]
    cell = lattice, positions, elements
    dataset = get_symmetry_dataset(cell, **kwargs)
    if dataset["number"] == crystal.space_group.international_tables_number:
        LOG.warn("Could not find additional symmetry for crystal %s", crystal)
        return None
    asym_idx = np.unique(dataset["equivalent_atoms"])
    asym_idx = asym_idx[np.argsort(asym_atoms[asym_idx])]
    sg = SpaceGroup(dataset["number"], choice=dataset["choice"])
    asym = AsymmetricUnit(
        [Element[x] for x in dataset["std_types"][asym_idx]],
        dataset["std_positions"][asym_idx],
    )
    unit_cell = UnitCell(dataset["std_lattice"])
    return Crystal(unit_cell, sg, asym)
 def test_from_records(self):
     records = [{"label": "H1", "element": "H", "position": (0, 0, 0)}]
     asym = AsymmetricUnit.from_records(records)
     self.assertTrue(len(asym) == 1)
 def test_asymmetric_unit_constructor(self):
     asym = ice_ii_asym()
     self.assertTrue(len(asym) == 36)
     asym_generated_labels = AsymmetricUnit(_ICE_II_ELEMENTS,
                                            _ICE_II_POSITIONS)
     self.assertTrue(all(asym_generated_labels.labels == asym.labels))
def ice_ii_asym():
    return AsymmetricUnit(_ICE_II_ELEMENTS,
                          _ICE_II_POSITIONS,
                          labels=_ICE_II_LABELS)