Ejemplo n.º 1
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
Ejemplo n.º 2
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