Beispiel #1
0
def lat_in_to_sqs(atat_lattice_in, rename=True):
    """
    Convert a string-like ATAT-style lattice.in to an abstract SQS.

    Parameters
    ----------
    atat_lattice_in : str
        String-like of a lattice.in in the ATAT format.
    rename : bool
        If True, SQS format element names will be renamed, e.g. `a_B` -> `Xab`. Default is True.

    Returns
    -------
    SQS
        Abstract SQS.
    """
    # TODO: handle numeric species, e.g. 'g1'. Fixed
    # Problems: parser has trouble with matching next line and we have to rename it so pymatgen
    # doesn't think it's a charge.
    # parse the data
    parsed_data = _parse_atat_lattice(atat_lattice_in)
    atat_coord_system = parsed_data[0]
    atat_lattice = parsed_data[1]
    atat_atoms = parsed_data[2]
    # create the lattice
    if len(atat_coord_system) == 3:
        # we have a coordinate system matrix
        coord_system = Lattice(atat_coord_system.asList()).matrix
    else:
        # we have length and angles
        #coord_system = Lattice.from_lengths_and_angles(list(atat_coord_system[0]), list(atat_coord_system[1])).matrix
        (lat_a, lat_b, lat_c) = list(atat_coord_system[0])
        (lat_alpha, lat_beta, lat_gamma) = list(atat_coord_system[1])
        coord_system = Lattice.from_parameters(lat_a, lat_b, lat_c, lat_alpha,
                                               lat_beta, lat_gamma).matrix
    direct_lattice = Lattice(atat_lattice.asList())
    lattice = coord_system.dot(direct_lattice.matrix)
    # create the list of atoms, converted to the right coordinate system
    species_list = []
    species_positions = []
    subl_model = {
    }  # format {'subl_name': 'atoms_found_in_subl, e.g. "aaabbbb"'}
    for position, atoms in atat_atoms:
        # atoms can be a list of atoms, e.g. for not abstract SQS
        if len(atoms) > 1:
            raise NotImplementedError(
                'Cannot parse atom list {} because the sublattice is unclear.\nParsed data: {}'
                .format(atoms, atat_atoms))
        atom = atoms[0]
        if rename:
            # change from `a_B` style to `Xab`

            atom = atom.lower().split('_')
        else:
            raise NotImplementedError(
                'Cannot rename because the atom name and sublattice name may be ambigous.'
            )
        # add the abstract atom to the sublattice model
        subl = atom[0]
        #Replace the digital by alphas, 1->a, 2->b, 3->c, ...
        rep_items = re.findall(r"\d+", subl)
        for rep_item in rep_items:
            subl = subl.replace(rep_item, chr(96 + int(rep_item)))
        subl_atom = atom[1]
        subl_model[subl] = subl_model.get(subl, set()).union({subl_atom})
        # add the species and position to the lists
        species_list.append('X' + subl + subl_atom)
        species_positions.append(list(position))
    # create the structure
    sublattice_model = [[e for e in sorted(list(set(subl_model[s])))]
                        for s in sorted(subl_model.keys())]
    sublattice_names = [s for s in sorted(subl_model.keys())]
    sqs = AbstractSQS(direct_lattice,
                      species_list,
                      species_positions,
                      coords_are_cartesian=True,
                      sublattice_model=sublattice_model,
                      sublattice_names=sublattice_names)
    sqs.lattice = Lattice(lattice)
    #sqs.modify_lattice(Lattice(lattice))  #This will be deprecated in v2020

    return sqs