Пример #1
0
def parser(name, data):
    """ Parse turbomole specific input file """
    tmol = Molecule(name)
    for i in range(len(data)):
        if "$coord" in data[i]:
            for l in data[i + 1:]:
                if '$' in l:
                    break
                line = l.split()
                tmol.newAtom(line[3].capitalize(), line[0:3], fmt='bohr')
            break
    return tmol, None
Пример #2
0
def parser(name, data):
    """ Parse sybyl mol2 files """
    tmol = Molecule(name)
    parsing = False
    for line in data:
        if not line.strip():
            continue
        elif line.strip()[0] == '#':
            continue
        elif "@<TRIPOS>ATOM" in line:
            parsing = True
        elif parsing:
            if "@<TRIPOS>" in line:
                tmol.setFmt("angstrom", scale=True)
                return tmol, None
            at = line.strip().split()
            tmol.newAtom(at[5].upper(), at[2:5], charge=float(at[8]))
Пример #3
0
def parser(name, data):
    """ Parse AIMALL output to molecule

    Creates atoms from NACPs
    Other critical points will be parsed directly
    """
    tmol = Molecule(name)
    i = 0
    while i < len(data):
        line = data[i].split()
        if line and line[0] == 'CP#':
            i += 1
            cptype = data[i].split()[3]
            if cptype == 'NACP':
                cptype = data[i].split()[4].rstrip('0123456789')
            tmol.newAtom(cptype, line[4:], fmt='bohr')
        i += 1
    return tmol, None
Пример #4
0
def parser(name, data):
    """ Parse xyz files (angstrom) """
    # create list of mol, trajectory support
    tmol = Molecule(name, steps=0)
    i = 0
    while i < len(data):
            # handle empty lines at eof or between molecules
            if not data[i].strip().isdigit():
                    i += 1
                    continue
            # fixed format nat and comment
            tmol.newStep()
            nat = int(data[i])
            tmol.comment = data[i + 1].strip()
            # read coordinates and types
            tmol.newAtoms(nat)
            for j in range(nat):
                line = data[j + i + 2].split()
                tmol.setAtom(j, line[0], line[1:4])
            tmol.setFmt('angstrom', scale=True)
            i += nat + 2
    return tmol, None
Пример #5
0
def parser(name, data):
    """ Parse Lammps custom dump files

    Preliminary implementation!
    Needs to be 'custom' format with either:
    'id element xs ys yz'
    or
    'id element x y z'
    Only orthogonal cells for now
    Assumes angstrom
    """
    tmol = Molecule(name, steps=0)
    i = 0
    while i < len(data):
        line = data[i]
        if 'ITEM' in line:
            if 'TIMESTEP' in line:
                i += 2
                tmol.newStep()
            elif 'NUMBER OF ATOMS' in line:
                nat = int(data[i + 1])
                i += 2
            elif 'BOX BOUNDS' in line:
                tvec = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
                tvec[0][0] = float(data[i + 1].split()[1]) -\
                    float(data[i + 1].split()[0])
                tvec[1][1] = float(data[i + 2].split()[1]) -\
                    float(data[i + 2].split()[0])
                tvec[2][2] = float(data[i + 3].split()[1]) -\
                    float(data[i + 3].split()[0])
                tmol.setVec(tvec)
                tmol.setCellDim(1, fmt='angstrom')
                i += 4
            elif 'ATOMS' in line:
                line = line.split()
                if 'id' not in line or 'element' not in line or\
                        ('xs' not in line and 'x' not in line):
                    raise NotImplementedError("Lammps dump in not (yet) "
                                              "recognized format")
                # ididx = line.index('id') - 2
                elidx = line.index('element') - 2
                if 'xs' in line:
                    xidx = line.index('xs') - 2
                    yidx = line.index('ys') - 2
                    zidx = line.index('zs') - 2
                    fmt = 'crystal'
                else:
                    xidx = line.index('x') - 2
                    yidx = line.index('y') - 2
                    zidx = line.index('z') - 2
                    fmt = 'angstrom'
                if 'q' in line:
                    qidx = line.index('q') - 2
                else:
                    qidx = False
                tmol.newAtoms(nat)
                for j in range(nat):
                    at = data[j + 1 + i].split()
                    if qidx:
                        tmol.setAtom(j, at[elidx],
                                     [at[xidx], at[yidx], at[zidx]],
                                     charge=float(at[qidx]))
                    else:
                        tmol.setAtom(j, at[elidx],
                                     [at[xidx], at[yidx], at[zidx]])
                tmol.setFmt(fmt, scale=True)
                i += nat + 1
        else:
            i += 1
    return tmol, None
Пример #6
0
def parser(name, data):
    """ Parse Lammps data file

    Element parsed via comment in 'Masses' part
    Assumes angstrom, atom_style in [angle,atomic,bond,charge,full,molecular]
    """
    tmol = Molecule(name)
    i = 0
    tvec = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
    while i < len(data):
        line = data[i].strip()
        if 'atoms' in line:
            nat = int(line.split()[0])
        elif 'atom types' in line:
            types = [0] * int(line.split()[0])
        elif 'xlo xhi' in line:
            tvec[0][0] = float(line.split()[1]) - float(line.split()[0])
        elif 'ylo yhi' in line:
            tvec[1][1] = float(line.split()[1]) - float(line.split()[0])
        elif 'zlo zhi' in line:
            tvec[2][2] = float(line.split()[1]) - float(line.split()[0])
        elif 'xy xz yz' in line:
            tvec[1][0], tvec[2][0], tvec[2][1] = line.split()[:3]
        elif 'Masses' in line:
            for j in range(i + 2, i + 2 + len(types)):
                if '#' in data[j]:
                    el = data[j].split('#')
                    t = el[1].strip()
                    types[int(el[0].split()[0]) - 1] = t
                    tmol.pse[t]['m'] = float(el[0].split()[1])
                else:
                    raise NotImplementedError("Can't deduce elements")
            i += len(types) + 1
        elif 'Atoms' in line:
            atomlist = []
            for j in range(i + 2, i + 2 + nat):
                atomlist.append(data[j].strip().split())
            if '#' in line and line.split('#')[1].strip() in lammps_atom_style:
                style = lammps_atom_style[line.split('#')[1].
                                          strip()].split('} ')
                atypepos = style.index('{2:d')
                cpos = style.index('{3: .4f')
                try:
                    qpos = style.index('{6: .4f')
                except:
                    qpos = None
            else:
                # make a guess for column-content:
                nargs = len(atomlist[0])
                atypepos = 1
                cpos = -3
                testimageflags = 0
                for j in range(nargs, 1, -1):
                    try:
                        test = [int(k[j]) for k in atomlist]
                    except:
                        pass
                    else:
                        # check for imageflags (3 integer columns)
                        if nargs > 7 and j > 3:
                            testimageflags += 1
                            if testimageflags == 3:
                                cpos = -6
                        # check if one of the first two entries
                        # and not an empty charge column
                        elif j == 2 and set(test) != set([0]):
                            atypepos = j
                            break
                # guess where charge is found:
                if nargs + cpos - 1 > atypepos:
                    qpos = atypepos + 1
                else:
                    qpos = False
            # gotta load 'em all!
            tmol.newAtoms(nat)
            for j, at in enumerate(atomlist):
                tmol.setAtom(j, types[int(at[atypepos]) - 1],
                             at[cpos:cpos + 3 if cpos + 3 else None],
                             float(at[qpos]) if qpos else None)
            tmol.setFmt('angstrom', scale=True)
            tmol.setVec(tvec)
            tmol.setCellDim(1, fmt='angstrom')
        i += 1
    return tmol, None
Пример #7
0
def parser(name, data):
    """ Parse Gaussian Cube file """
    tmol = Molecule(name)
    fmt = "bohr"
    # two lines of comments, combine
    tmol.comment = data[0] + ";" + data[1]
    # nat, origin[3]
    nat = int(data[2].split()[0])
    origin = [float(data[2].split()[i]) for i in [1, 2, 3]]
    # n of datapoints(dir), cell_vec[3]
    nvol = [0, 0, 0]
    tvec = [0, 0, 0]
    for i in [0, 1, 2]:
        line = data[i + 3].split()
        nvol[i] = int(line[0])
        if nvol[i] < 0:
            nvol[i] = -nvol[i]
            fmt = "angstrom"
        tvec[i] = [float(line[j]) * nvol[i] for j in [1, 2, 3]]
    tmol.setVec(tvec)
    pse = list(glob_pse.keys())
    tmol.newAtoms(nat)
    for i in range(nat):
        # line = Z, charge, coord(x, y, z)
        line = data[i + 6].split()
        tmol.setAtom(i, pse[int(line[0])], line[2:5], charge=float(line[1]))
    tmol.setFmt(fmt, scale=False)
    tmol.setCellDim(1, fmt=fmt)
    # rest of file has datagrid, x is outer loop, z inner
    vol = [[[0] * nvol[2] for i in range(nvol[1])] for j in range(nvol[0])]
    i = 6 + nat
    line = data[i].split()
    for x in range(nvol[0]):
        for y in range(nvol[1]):
            for z in range(nvol[2]):
                while not line and i < (len(data) - 1):
                    i += 1
                    line = data[i].split()
                vol[x][y][z] = float(line.pop(0))
    tmol.setVol(vol, origin)
    return tmol, None
Пример #8
0
def parser(name, data):
    """ Parse CPMD Input file """
    tmol = Molecule(name)
    tparam = deepcopy(param["default"])
    tparam["name"] = name
    i = 0
    ibrav = '14'
    symmetries = {'ISOLATED': '0',
                  'CUBIC': '1',
                  'FACE CENTERED CUBIC': '2',
                  'FCC': '2',
                  'BODY CENTERED CUBIC': '3',
                  'BCC': '3',
                  'HEXAGONAL': '4',
                  'TRIGONAL': '5',
                  'RHOMBOHEDRAL': '5',
                  'TETRAGONAL': '6',
                  'BODY CENTERED TETRAGONAL': '7',
                  'BCT': '7',
                  'ORTHORHOMBIC': '8',
                  'MONOCLINIC': '12',
                  'TRICLINIC': '14'}
    fmt = 'bohr'
    unitvec = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    scalevec = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    types = []
    while i < len(data):
        if data[i][0] == '!' or data[i].split() == []:
            i += 1
        elif '&' in data[i] and data[i].strip() != "&END":
            # start recording namelist
            nl = data[i].strip()
            i += 1
            while "&END" not in data[i]:
                if nl == "&SYSTEM" and "ANGSTROM" in data[i]:
                    fmt = "angstrom"
                elif nl == "&SYSTEM" and "KPOINTS" in data[i]:
                    if "MONKHORST" in data[i]:
                        kpoints = data[i + 1].split()
                        if "SHIFT=" in data[i]:
                            kpoints += data[i].split("SHIFT=")[1].split()[0:3]
                        else:
                            kpoints += ['0', '0', '0']
                        tmol.setKpoints('active', 'mpg')
                        tmol.setKpoints('mpg', kpoints)
                        i += 1
                    else:
                        kpoints = []
                        crystal = False
                        bands = False
                        if "SCALED" in data[i]:
                            crystal = True
                        if "BANDS" in data[i]:
                            bands = True
                            j = 1
                            line = data[i + j].split()
                            while not all([float(k) == 0 for k in line]):
                                kpoints.append(line[1:4] + [line[0]])
                                kpoints.append(line[4:] + ['0'])
                                j += 1
                                line = data[i + j].split()
                            i += j
                        else:
                            nk = int(data[i + 1])
                            for j in range(nk):
                                kpoints.append(data[i + j + 2].split())
                            i += 1 + nk
                        tmol.setKpoints('active', 'discrete')
                        tmol.setKpoints('discrete', kpoints)
                        tmol.setKpoints('options',
                                        {'crystal': crystal, 'bands': bands})
                elif nl == "&SYSTEM" and "SCALE" in data[i]:
                    if "CARTESIAN" in data[i]:
                        fmt = "alat"
                    else:
                        fmt = "crystal"
                    for token in data[i].strip().split():
                        if 'S=' in token:
                            scalevec[0][0] = 1 / float(token.strip('S='))
                            scalevec[1][1] = 1 / float(token.strip('S='))
                            scalevec[2][2] = 1 / float(token.strip('S='))
                        elif 'SX=' in token:
                            scalevec[0][0] = 1 / float(token.strip('SX='))
                        elif 'SY=' in token:
                            scalevec[1][1] = 1 / float(token.strip('SY='))
                        elif 'SZ=' in token:
                            scalevec[2][2] = 1 / float(token.strip('SZ='))
                elif nl == "&SYSTEM" and "SYMMETRY" in data[i]:
                    arg = data[i + 1].strip()
                    if arg.isdigit():
                        ibrav = arg
                    else:
                        ibrav = symmetries[arg]
                    i += 1
                elif nl == "&SYSTEM" and "CELL" in data[i]:
                    cell = list(map(float, data[i + 1].split()))
                    if "VECTORS" in data[i]:
                        while len(cell) < 9:
                            i += 1
                            cell += list(map(float, data[i + 1].split()))
                        ibrav = '-2'
                    else:
                        # cell = [a,b/a,c/a,cos(alpha),cos(beta),cos(gamma)]
                        a, b, c, alpha, beta, gamma = cell
                        tmol.setCellDim(a)
                        if "ABSOLUTE" in data[i]:
                            # cell = [a, b, c, ...]
                            b = b / a
                            c = c / a
                        if "DEGREE" in data[i]:
                            # cell = [..., alpha, beta, gamma]
                            alpha, beta, gamma =\
                                map(cos, map(deg2rad, [alpha, beta, gamma]))
                    i += 1
                elif nl == "&ATOMS" and data[i][0] == '*':
                    atype = regex('[-_.]', data[i][1:].strip())[0]
                    while atype in types:
                        if not atype[-1].isdigit():
                            atype += "1"
                        else:
                            atype = atype[:-1] + str(int(atype[-1]) + 1)
                    types.append(atype)
                    tmol.pse[atype]['CPPP'] = data[i][1:].strip()
                    tmol.pse[atype]['CPNL'] = data[i + 1].strip()
                    nat = int(data[i + 2])
                    for j in range(nat):
                        tmol.newAtom(atype, data[i + 3 + j].split()[:3])
                    i += 2 + nat
                elif nl == "&ATOMS" and "CONSTRAINTS" in data[i]:
                    # parse coordinate-fixes
                    j = 1
                    constraints = ""
                    line = data[i + j]
                    while "END" not in line:
                        if "FIX" in line and ("ALL" in line or "QM" in line):
                            for at in range(tmol.nat):
                                tmol.setAtom(at, fix=[True, True, True])
                        elif "FIX" in line and "ELEM" in line:
                            j += 1
                            vals = data[i + j].split()
                            Z = int(vals.pop(0))
                            if "SEQ" in line:
                                beg = int(vals.pop(0)) - 1
                                end = int(vals.pop(0))
                                r = range(beg, end)
                            else:
                                r = range(tmol.nat)
                            for at in r:
                                if tmol.pse[tmol.getAtom(at)[0]]["Z"] == Z:
                                    tmol.setAtom(at, fix=[True, True, True])
                        elif "FIX" in line and "PPTY" in line:
                            j += 1
                            vals = data[i + j].split()
                            PP = int(vals.pop(0)) - 1
                            if "SEQ" in line:
                                beg = int(vals.pop(0)) - 1
                                end = int(vals.pop(0))
                                r = range(beg, end)
                            else:
                                r = range(tmol.nat)
                            for at in r:
                                if tmol.getAtom(at)[0] == types[PP]:
                                    tmol.setAtom(at, fix=[True, True, True])
                        elif "FIX" in line and "SEQ" in line:
                            j += 1
                            vals = data[i + j].split()
                            for at in range(int(vals[0]) - 1, int(vals[1])):
                                tmol.setAtom(at, fix=[True, True, True])
                        elif "FIX" in line and "ATOM" in line:
                            j += 1
                            vals = data[i + j].split()
                            count = int(vals.pop(0))
                            for k in range(count):
                                if not vals:
                                    j += 1
                                    vals = data[i + j].split()
                                tmol.setAtom(int(vals.pop(0)) - 1,
                                             fix=[True, True, True])
                        elif "FIX" in line and "COOR" in line:
                            j += 1
                            vals = data[i + j].split()
                            count = int(vals.pop(0))
                            for k in range(count):
                                j += 1
                                fixcoord = list(map(int, data[i + j].split()))
                                tmol.setAtom(fixcoord[0] - 1, fix=[
                                    bool(not fixcoord[1]),
                                    bool(not fixcoord[2]),
                                    bool(not fixcoord[3])])
                        elif line.strip():
                            constraints += line
                        j += 1
                        line = data[i + j]
                    if constraints:
                        tparam[nl] += "CONSTRAINTS\n" + constraints +\
                                      "END CONSTRAINTS\n"
                    i += j
                elif nl == "&ATOMS" and "ISOTOPE" in data[i]:
                    j = 0
                    for t in types:
                        j += 1
                        mass = data[i + j].strip()
                        tmol.pse[t]['m'] = float(mass)
                    i += j
                else:
                    tparam[nl] += data[i]
                i += 1
        else:
            i += 1
    # apply cell vec (scale SX etc.)
    if scalevec != unitvec:
        tmol.setVec(scalevec, scale=True)
        tmol.setVec(unitvec)
    # parse cell parameters
    if ibrav == '-2':
        tmol.setVec([cell[0:3], cell[3:6], cell[6:9]])
    elif ibrav == '1':
        # simple cubic
        pass
    elif ibrav == '2':
        # face centered cubic
        tmol.setVec([[-0.5, 0, 0.5], [0, 0.5, 0.5], [-0.5, 0.5, 0]])
    elif ibrav == '3':
        # body centered cubic
        tmol.setVec([[0.5, 0.5, 0.5], [-0.5, 0.5, 0.5], [-0.5, -0.5, 0.5]])
    elif ibrav == '4':
        # hexagonal
        tmol.setVec([[1, 0, 0], [-0.5, sqrt(3) * 0.5, 0], [0, 0, c]])
    elif ibrav == '5':
        # trigonal
        tx = sqrt((1 - alpha) / 2)
        ty = sqrt((1 - alpha) / 6)
        tz = sqrt((1 + 2 * alpha) / 3)
        tmol.setVec([[tx, -ty, tz], [0, 2 * ty, tz], [-tx, -ty, tz]])
    elif ibrav == '6':
        # simple tetragonal
        tmol.setVec([[1, 0, 0], [0, 1, 0], [0, 0, c]])
    elif ibrav == '7':
        # body centered tetragonal
        tmol.setVec([[0.5, -0.5, c * 0.5],
                     [0.5, 0.5, c * 0.5],
                     [-0.5, -0.5, c * 0.5]])
    elif ibrav == '0' or ibrav == '8':
        # simple orthorhombic
        tmol.setVec([[1, 0, 0], [0, b, 0], [0, 0, c]])
    elif ibrav == '12':
        # simple monoclinic
        tmol.setVec([[1, 0, 0],
                     [b * alpha, b * sqrt(1 - alpha**2), 0],
                     [0, 0, c]])
    elif ibrav == '14':
        # triclinic
        singam = sqrt(1 - gamma**2)
        tmol.setVec([[1, 0, 0], [b * gamma, b * singam, 0],
                     [c * beta, c * (alpha - beta * gamma) / singam,
                      c * sqrt(1 + 2 * alpha * beta * gamma - alpha * alpha -
                               beta * beta - gamma * gamma) / singam]])
    # scale alat with explicit vectors
    if fmt == 'alat' and ibrav == '-2':
        vec = tmol.getVec()
        a = sqrt(vec[0][0] * vec[0][0] + vec[0][1] *
                 vec[0][1] + vec[0][2] * vec[0][2])
        b = sqrt(vec[1][0] * vec[1][0] + vec[1][1] *
                 vec[1][1] + vec[1][2] * vec[1][2])
        c = sqrt(vec[2][0] * vec[2][0] + vec[2][1] *
                 vec[2][1] + vec[2][2] * vec[2][2])
        tmol.setVec([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
        tmol.setVec([[a, 0, 0], [0, b, 0], [0, 0, c]], scale=True)
        tmol.setVec(vec)
    # scale crystal, alat /w symmetry, angstrom-atoms
    tmol.setFmt(fmt, scale=True)
    # scale angstrom-cell
    tmol.setCellDim(tmol.getCellDim(fmt='bohr'), fmt=fmt)
    return tmol, tparam
Пример #9
0
def parser(name, data):
    """ Parse PWScf output to trajectory """
    tmol = Molecule(name, steps=0)
    i = 0
    vec = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
    gamma = False
    while i < len(data):
        line = data[i].split()
        # ignore empty lines
        if not line:
            pass
        # read number of atoms
        elif line[0:3] == ['number', 'of', 'atoms/cell']:
            nat = int(line[4])
        # read cell dimension
        elif line[0] == 'celldm(1)=':
            celldm = float(line[1])
        # read initial cell vectors
        elif line[0:2] == ['crystal', 'axes:']:
            for j in [0, 1, 2]:
                temp = data[i + 1 + j].split()
                vec[j] = [float(x) for x in temp[3:6]]
        # read initial positions:
        elif line[0] == 'site':
            tmol.newStep()
            tmol.setCellDim(celldm)
            tmol.setVec(vec)
            tmol.newAtoms(nat)
            for j in range(nat):
                atom = data[j + i + 1].split()
                tmol.setAtom(j, atom[1], atom[6:9])
            tmol.setFmt('alat', scale=True)
            i += nat
        # read k-points:
        elif line[0] == 'gamma-point':
            gamma = True
        elif line[0:3] == ['number', 'of', 'k'] and not gamma:
            nk = int(line[4])
            if nk < 100:
                kpoints = []
                for j in range(i + 2, i + nk + 2):
                    kp = data[j].split()
                    kpoints.append([kp[4], kp[5], kp[6].strip('), '), kp[9]])
                tmol.setKpoints('discrete', kpoints)
                tmol.setKpoints('active', 'discrete')
                i += nk
        # read step-vectors if cell is variable
        elif line[0] == 'CELL_PARAMETERS':
            for j in [0, 1, 2]:
                temp = data[i + 1 + j].split()
                vec[j] = [float(x) for x in temp[0:3]]
        # read step-coordinates
        elif line[0] == 'ATOMIC_POSITIONS':
            tmol.newStep()
            tmol.setCellDim(celldm)
            tmol.setVec(vec)
            tmol.newAtoms(nat)
            for j in range(nat):
                atom = data[j + i + 1].split()
                tmol.setAtom(j, atom[0], atom[1:4],
                             fix=[not int(x) for x in atom[4:]])
            tmol.setFmt(line[1].strip('()'), scale=True)
            i += nat
        # break on reaching final coordinates (duplicate)
        elif line[0] == 'Begin':
            break
        # ignore everything else
        else:
            pass
        i += 1
    return tmol, None
Пример #10
0
def parser(name, data):
    """ Parse (animated) XCrysDen structure files

    Optionally contains datagrids/animations/forces
    Parses multiple datagrids into multiple steps
    """
    animated = False
    periodic = False
    pbcformats = ["MOLECULE", "POLYMER", "SLAB", "CRYSTAL"]
    i = 0
    while i < len(data):
        if data[i][0] == '#':
            pass
        elif "ANIMSTEPS" in data[i]:
            tmol = Molecule(name, steps=int(data[i].strip("ANIMSTEPS \r\n")))
            animated = True
        elif data[i].strip() in pbcformats:
            periodic = True
        # Parse coordinates of isolated molecule
        elif not periodic and "ATOMS" in data[i]:
            if animated:
                tmol.changeStep(int(data[i].strip("ATOMS \r\n")) - 1)
            else:
                tmol = Molecule(name, steps=1)
            j = 1
            while i + j < len(data) and len(data[i + j].split()) in [4, 7]:
                line = data[i + j].split()
                tmol.newAtom(line[0], line[1:4])
                j += 1
            tmol.setFmt("angstrom", scale=True)
            i += j - 1
        # Parse periodic structure containing cell and coordinates
        elif periodic and "PRIMVEC" in data[i]:
            vec = [data[i + j].split() for j in range(1, 4)]
            if animated and data[i].strip("PRIMVEC \r\n"):
                tmol.changeStep(int(data[i].strip("PRIMVEC ")) - 1)
                tmol.setVec(vec)
                tmol.setCellDim(1, fmt='angstrom')
            elif animated:
                tmol.setVecAll(vec)
                tmol.setCellDimAll(1, fmt='angstrom')
            else:
                tmol = Molecule(name, steps=1)
                tmol.setVec(vec)
                tmol.setCellDim(1, fmt='angstrom')
            i += 3
        elif periodic and "PRIMCOORD" in data[i]:
            if animated:
                tmol.changeStep(int(data[i].strip("PRIMCOORD \r\n")) - 1)
            nat = int(data[i + 1].split()[0])
            tmol.newAtoms(nat)
            for j in range(nat):
                line = data[j + 2 + i].split()
                tmol.setAtom(j, line[0], line[1:4])
            tmol.setFmt("angstrom", scale=True)
            i += nat + 1
        elif periodic and "CONVVEC" in data[i]:
            # could be used, but not atm
            pass
        elif periodic and "CONVCOORD" in data[i]:  # pragma: no cover
            # should not even be there
            pass
        elif "BEGIN_" in data[i]:
            datatype = data[i].strip("BEGIN_BLOCK_ \r\n")
            endblock = "END_BLOCK_" + datatype
            endgrid = "END_" + datatype
            j = 1
            grids = []
            # only parse 3D datagrids
            while endblock not in data[i + j]:
                if datatype in data[i + j] and datatype == "DATAGRID_3D":
                    nvol = list(map(int, data[i + j + 1].split()))
                    vol = [[[0] * nvol[2] for y in range(nvol[1])]
                           for z in range(nvol[0])]
                    origin = list(map(float, data[i + j + 2].split()))
                    # assume spanning space equals cell
                    j += 6
                    line = data[i + j].split()
                    for z in range(nvol[2]):
                        for y in range(nvol[1]):
                            for x in range(nvol[0]):
                                while not (line or endgrid in data[i + j + 1]):
                                    j += 1
                                    line = data[i + j].split()
                                vol[x][y][z] = float(line.pop(0))
                    del vol[-1]
                    for n in vol:
                        del n[-1]
                        for m in n:
                            del m[-1]
                    grids.append((vol, origin))
                    j += 1
                j += 1
            if grids:
                tmol.changeStep(0)
                tmol.setVol(*grids[0])
                if len(grids) > 1:
                    for k in range(1, len(grids)):
                        tmol.copyStep()
                        tmol.setVol(*grids[k])
            i += j
        i += 1
    return tmol, None
Пример #11
0
def parser(name, data):
    """ Parse Empire specific xyz file """
    tmol = Molecule(name)
    nat = int(data[0])
    tmol.comment = data[1].strip()
    tmol.newAtoms(nat)
    for j in range(nat):
        line = data[j + 2].split()
        tmol.setAtom(j, line[0], line[1:4])
    tmol.setFmt("angstrom", scale=True)
    vec = [0, 0, 0]
    for i in range(3):
        vec[i] = [float(x) for x in data[nat + 3 + i].split()]
    tmol.setVec(vec)
    tmol.setCellDim(1, fmt="angstrom")
    return tmol, None
Пример #12
0
def parser(name, data):
    """ Parse PWScf input files

    Namelists will be parsed and saved in PW parameter set
    Supported Cards:
    - ATOMIC_SPECIES
    - ATOMIC_POSITIONS
    - K_POINTS
    - CELL_PARAMETERS
    Not supported:
    - CONSTRAINTS
    - OCCUPATIONS
    - ATOMIC_FORCES (PWSCFv5)
    """
    tmol = Molecule(name)
    tparam = {"type": "pwi", "name": name}
    tvec = []
    # parse data and create tparam
    while data:
        header = data.pop(0).strip().split()
        #  ignore empty lines
        if not header:
            pass
        #  parse namelists
        elif header[0][0] == '&':
            tnl = OrderedDict()
            #  parse entries
            line = regex(', \s*(?![^()]*\))', data.pop(0).strip())
            while line[0] != '/':
                for j in range(len(line)):
                    if line[j]:
                        tnl[line[j].split('=')[0].strip()] =\
                            line[j].split('=')[1].strip()
                line = regex(', \s*(?![^()]*\))', data.pop(0).strip())
            tparam[header[0].lower()] = tnl
        #  parse card
        elif header[0][0].isupper():
            # ATOMIC_SPECIES:
            # Name   Weight  PP-file
            if header[0] == 'ATOMIC_SPECIES':
                for i in range(int(tparam['&system']['ntyp'])):
                    line = data.pop(0).strip().split()
                    tmol.pse[line[0]]['m'] = float(line[1])
                    tmol.pse[line[0]]['PWPP'] = line[2]
            # ATOMIC_POSITIONS fmt
            # Name   x   y   z
            elif header[0] == 'ATOMIC_POSITIONS':
                fmt = header[1].strip('{()}')
                tmol.newAtoms(int(tparam['&system']['nat']))
                for i in range(int(tparam['&system']['nat'])):
                    # support empty lines
                    temp = data.pop(0).split()
                    while not temp:
                            temp = data.pop(0).split()
                    tmol.setAtom(i, temp[0], temp[1:4],
                                 fix=[not int(x) for x in temp[4:]])
            # K_POINTS fmt
            elif header[0] == 'K_POINTS':
                active = header[1].strip('{()}')
                # Gamma point only
                if active == 'gamma':
                    tmol.setKpoints('active', 'gamma')
                # Monkhorst Pack Grid:
                # x y z offset
                elif active == 'automatic':
                    line = data.pop(0).split()
                    tmol.setKpoints('mpg', line)
                    tmol.setKpoints('active', 'mpg')
                # else:
                # number of kpoints
                # x y z weight
                else:
                    nk = int(data.pop(0).split()[0])
                    kpoints = []
                    for i in range(nk):
                        kpoints.append(data.pop(0).split())
                    tmol.setKpoints('discrete', kpoints)
                    tmol.setKpoints('active', 'discrete')
                    if active == 'tpiba':
                        pass
                    elif active == 'tpiba_b':
                        tmol.setKpoints('options', {'bands': True,
                                                    'crystal': False})
                    elif active == 'crystal':
                        tmol.setKpoints('options', {'bands': False,
                                                    'crystal': True})
                    elif active == 'crystal_b':
                        tmol.setKpoints('options', {'bands': True,
                                                    'crystal': True})
            # CELL_PARAMETERS
            # only needed if ibrav=0
            # tbd changed between pw4 and pw5, ignored for now
            elif header[0] == 'CELL_PARAMETERS':
                for i in [0, 1, 2]:
                    line = data.pop(0).strip().split()
                    tvec.append([float(x) for x in line])
            else:
                pass
    # Identify cell parameter representation, parse it
    ibrav = tparam['&system']['ibrav']
    tparam['&system']['ibrav'] = '0'
    # Get cell values
    sys = tparam['&system']
    a = b = c = cosab = cosac = cosbc = None
    if 'celldm(1)' in sys:
        a = float(sys['celldm(1)'])
        del sys['celldm(1)']
        tmol.setCellDim(a, fmt='bohr')
        if 'celldm(2)' in sys:
            b = float(sys['celldm(2)'])
            del sys['celldm(2)']
        if 'celldm(3)' in sys:
            c = float(sys['celldm(3)'])
            del sys['celldm(3)']
        if 'celldm(4)' in sys:
            cosab = float(sys['celldm(4)'])
            del sys['celldm(4)']
        if 'celldm(5)' in sys:
            cosac = float(sys['celldm(5)'])
            del sys['celldm(5)']
        if 'celldm(6)' in sys:
            cosbc = float(sys['celldm(6)'])
            del sys['celldm(6)']
        if ibrav == '14':
            cosab, cosbc = cosbc, cosab
    elif 'A' in sys:
        a = float(sys['A'])
        del sys['A']
        tmol.setCellDim(a, fmt='angstrom')
        if 'B' in sys:
            b = float(sys['B']) / a
            del sys['B']
        if 'C' in sys:
            c = float(sys['C']) / a
            del sys['C']
        if 'cosAB' in sys:
            cosab = float(sys['cosAB'])
            del sys['cosAB']
        if 'cosAC' in sys:
            cosac = float(sys['cosAC'])
            del sys['cosAC']
        if 'cosBC' in sys:
            cosbc = float(sys['cosBC'])
            del sys['cosBC']
    elif ibrav != '0':
        raise ValueError('Neither celldm(1) nor A specified')

    def checkCellVal(v, n):
        if v is None:
            raise ValueError(n + ' is needed, but was not specified')
    if ibrav == '0':
        # check if CELL_PARAMETERS card has been read
        # if not present, throw error
        if not tvec:
                raise ValueError('ibrav=0, but CELL_PARAMETERS missing')
        else:
                tmol.setVec(tvec)
    elif ibrav == '1':
        # simple cubic
        pass
    elif ibrav == '2':
        # face centered cubic
        tmol.setVec([[-0.5, 0, 0.5], [0, 0.5, 0.5], [-0.5, 0.5, 0]])
    elif ibrav == '3':
        # body centered cubic
        tmol.setVec([[0.5, 0.5, 0.5], [-0.5, 0.5, 0.5], [-0.5, -0.5, 0.5]])
    elif ibrav == '4':
        # hexagonal
        checkCellVal(c, 'c')
        tmol.setVec([[1, 0, 0], [-0.5, sqrt(3) * 0.5, 0], [0, 0, c]])
    elif ibrav == '5':
        # trigonal
        checkCellVal(cosab, 'cosab')
        tx = sqrt((1 - cosab) / 2)
        ty = sqrt((1 - cosab) / 6)
        tz = sqrt((1 + 2 * cosab) / 3)
        tmol.setVec([[tx, -ty, tz], [0, 2 * ty, tz], [-tx, -ty, tz]])
    elif ibrav == '-5':
        # trigonal, alternative
        checkCellVal(cosab, 'cosab')
        tx = sqrt((1 - cosab) / 2)
        ty = sqrt((1 - cosab) / 6)
        tz = sqrt((1 + 2 * cosab) / 3)
        u = (tz - 2 * sqrt(2) * ty) / sqrt(3)
        v = (tz + sqrt(2) * ty) / sqrt(3)
        tmol.setVec([[u, v, v], [v, u, v], [v, v, u]])
    elif ibrav == '6':
        # simple tetragonal
        checkCellVal(c, 'c')
        tmol.setVec([[1, 0, 0], [0, 1, 0], [0, 0, c]])
    elif ibrav == '7':
        # body centered tetragonal
        checkCellVal(c, 'c')
        tmol.setVec([[0.5, -0.5, c * 0.5],
                     [0.5, 0.5, c * 0.5],
                     [-0.5, -0.5, c * 0.5]])
    elif ibrav == '8':
        # simple orthorhombic
        checkCellVal(c, 'c')
        checkCellVal(b, 'b')
        tmol.setVec([[1, 0, 0], [0, b, 0], [0, 0, c]])
    elif ibrav == '9':
        # basis centered orthorhombic
        checkCellVal(c, 'c')
        checkCellVal(b, 'b')
        tmol.setVec([[0.5, b * 0.5, 0], [-0.5, b * 0.5, 0], [0, 0, c]])
    elif ibrav == '10':
        # face centered orthorhombic
        checkCellVal(c, 'c')
        checkCellVal(b, 'b')
        tmol.setVec([[0.5, 0, c * 0.5],
                     [0.5, b * 0.5, 0],
                     [0, b * 0.5, c * 0.5]])
    elif ibrav == '11':
        # body centered orthorhombic
        checkCellVal(c, 'c')
        checkCellVal(b, 'b')
        tmol.setVec([[0.5, b * 0.5, c * 0.5],
                     [-0.5, b * 0.5, c * 0.5],
                     [-0.5, -b * 0.5, c * 0.5]])
    elif ibrav == '12':
        # simple monoclinic
        checkCellVal(c, 'c')
        checkCellVal(b, 'b')
        checkCellVal(cosab, 'cosab')
        tmol.setVec([[1, 0, 0],
                     [b * cosab, b * sqrt(1 - cosab**2), 0],
                     [0, 0, c]])
    elif ibrav == '-12':
        # simple monoclinic, alternate definition
        checkCellVal(c, 'c')
        checkCellVal(b, 'b')
        checkCellVal(cosac, 'cosac')
        tmol.setVec([[1, 0, 0], [0, b, 0],
                     [c * cosac, 0, c * sqrt(1 - cosac**2)]])
    elif ibrav == '13':
        # base centered monoclinic
        checkCellVal(c, 'c')
        checkCellVal(b, 'b')
        checkCellVal(cosab, 'cosab')
        tmol.setVec([[0.5, 0, -c * 0.5],
                     [b * cosab, b * sqrt(1 - cosab**2), 0],
                     [0.5, 0, c * 0.5]])
    elif ibrav == '14':
        # triclinic
        checkCellVal(c, 'c')
        checkCellVal(b, 'b')
        checkCellVal(cosab, 'cosab')
        checkCellVal(cosac, 'cosac')
        checkCellVal(cosbc, 'cosbc')
        singam = sqrt(1 - cosab**2)
        tmol.setVec([[1, 0, 0], [b * cosab, b * singam, 0],
                    [c * cosac, c * (cosbc - cosac * cosab) / singam,
                     c * sqrt(1 + 2 * cosbc * cosac * cosab - cosbc * cosbc -
                              cosac * cosac - cosab * cosab) / singam]])
    # scale atoms after creating cell:
    tmol.setFmt(fmt, scale=True)
    # delete nat and ntype before returning
    del tparam['&system']['nat']
    del tparam['&system']['ntyp']
    return tmol, tparam