Beispiel #1
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
Beispiel #2
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
Beispiel #3
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
Beispiel #4
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
Beispiel #5
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
Beispiel #6
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
Beispiel #7
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
Beispiel #8
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