Skip to main content
`Ctrl`+`K`

#

# Source code for ase.io.gromos

    # fmt: off

    """ write gromos96 geometry files
    (the exact file format is copied from the freely available
    gromacs package, http://www.gromacs.org
    its procedure src/gmxlib/confio.c (write_g96_conf)
    """

    import numpy as np

    from ase import Atoms
    from ase.data import chemical_symbols
    from ase.utils import reader, writer

    @reader
    def read_gromos(fileobj):
        """Read gromos geometry files (.g96).
        Reads:
        atom positions,
        and simulation cell (if present)
        tries to set atom types
        """

        lines = fileobj.readlines()
        read_pos = False
        read_box = False
        tmp_pos = []
        symbols = []
        mycell = None
        for line in lines:
            if (read_pos and ('END' in line)):
                read_pos = False
            if (read_box and ('END' in line)):
                read_box = False
            if read_pos:
                symbol, _dummy, x, y, z = line.split()[2:7]
                tmp_pos.append((10 * float(x), 10 * float(y), 10 * float(z)))
                if (len(symbol) != 2):
                    symbols.append(symbol[0].lower().capitalize())
                else:
                    symbol2 = symbol[0].lower().capitalize() + \
                        symbol[1]
                    if symbol2 in chemical_symbols:
                        symbols.append(symbol2)
                    else:
                        symbols.append(symbol[0].lower().capitalize())
                if symbols[-1] not in chemical_symbols:
                    raise RuntimeError("Symbol '{}' not in chemical symbols"
                                       .format(symbols[-1]))
            if read_box:
                try:
                    grocell = list(map(float, line.split()))
                except ValueError:
                    pass
                else:
                    mycell = np.diag(grocell[:3])
                    if len(grocell) >= 9:
                        mycell.flat[[1, 2, 3, 5, 6, 7]] = grocell[3:9]
                    mycell *= 10.
            if ('POSITION' in line):
                read_pos = True
            if ('BOX' in line):
                read_box = True

        gmx_system = Atoms(symbols=symbols, positions=tmp_pos, cell=mycell)
        if mycell is not None:
            gmx_system.pbc = True
        return gmx_system

    @writer
    def write_gromos(fileobj, atoms):
        """Write gromos geometry files (.g96).
        Writes:
        atom positions,
        and simulation cell (if present)
        """

        from ase import units

        natoms = len(atoms)
        try:
            gromos_residuenames = atoms.get_array('residuenames')
        except KeyError:
            gromos_residuenames = []
            for _ in range(natoms):
                gromos_residuenames.append('1DUM')
        try:
            gromos_atomtypes = atoms.get_array('atomtypes')
        except KeyError:
            gromos_atomtypes = atoms.get_chemical_symbols()

        pos = atoms.get_positions()
        pos = pos / 10.0

        vel = atoms.get_velocities()
        if vel is None:
            vel = pos * 0.0
        else:
            vel *= 1000.0 * units.fs / units.nm

        fileobj.write('TITLE\n')
        fileobj.write('Gromos96 structure file written by ASE \n')
        fileobj.write('END\n')
        fileobj.write('POSITION\n')
        count = 1
        rescount = 0
        oldresname = ''
        for resname, atomtype, xyz in zip(gromos_residuenames,
                                          gromos_atomtypes,
                                          pos):
            if resname != oldresname:
                oldresname = resname
                rescount = rescount + 1
            okresname = resname.lstrip('0123456789 ')
            fileobj.write('%5d %-5s %-5s%7d%15.9f%15.9f%15.9f\n' %
                          (rescount, okresname, atomtype, count,
                           xyz[0], xyz[1], xyz[2]))
            count = count + 1
        fileobj.write('END\n')

        if atoms.get_pbc().any():
            fileobj.write('BOX\n')
            mycell = atoms.get_cell()
            grocell = mycell.flat[[0, 4, 8, 1, 2, 3, 5, 6, 7]] * 0.1
            fileobj.write(''.join([f'{x:15.9f}' for x in grocell]))
            fileobj.write('\nEND\n')