Source code for dpdata.gromacs.gro

#!/usr/bin/env python3
import re

import numpy as np

from ..unit import LengthConversion

nm2ang = LengthConversion("nm", "angstrom").value()
ang2nm = LengthConversion("angstrom", "nm").value()
cell_idx_gmx2dp = [0, 4, 8, 1, 2, 3, 5, 6, 7]


def _format_atom_name(atom_name):
    patt = re.compile("[a-zA-Z]*")
    match = re.search(patt, atom_name)
    fmt_name = match.group().capitalize()
    return fmt_name


def _get_line(line, fmt_atom_name=True):
    atom_name = line[10:15].split()[0]
    if fmt_atom_name:
        atom_name = _format_atom_name(atom_name)
    atom_idx = int(line[15:20].split()[0])
    posis = [float(line[ii : ii + 8]) for ii in range(20, 44, 8)]
    posis = np.array(posis) * nm2ang
    return atom_name, atom_idx, posis


def _get_cell(line):
    cell = np.zeros([3, 3])
    lengths = [float(ii) for ii in line.split()]
    if len(lengths) >= 3:
        for dd in range(3):
            cell[dd][dd] = lengths[dd]
    else:
        raise RuntimeError("wrong box format: ", line)
    if len(lengths) == 9:
        cell[0][1] = lengths[3]
        cell[0][2] = lengths[4]
        cell[1][0] = lengths[5]
        cell[1][2] = lengths[6]
        cell[2][0] = lengths[7]
        cell[2][1] = lengths[8]
    cell = cell * nm2ang
    return cell


[docs] def file_to_system_data(fname, format_atom_name=True, **kwargs): system = {"coords": [], "cells": []} with open(fname) as fp: frame = 0 while True: flag = fp.readline() if not flag: break else: frame += 1 names = [] idxs = [] posis = [] natoms = int(fp.readline()) for ii in range(natoms): n, i, p = _get_line(fp.readline(), fmt_atom_name=format_atom_name) names.append(n) idxs.append(i) posis.append(p) cell = _get_cell(fp.readline()) posis = np.array(posis) if frame == 1: system["orig"] = np.zeros(3) system["atom_names"] = list(set(names)) system["atom_numbs"] = [ names.count(ii) for ii in system["atom_names"] ] system["atom_types"] = [ system["atom_names"].index(ii) for ii in names ] system["atom_types"] = np.array(system["atom_types"], dtype=int) system["coords"].append(posis) system["cells"].append(cell) system["coords"] = np.array(system["coords"]) system["cells"] = np.array(system["cells"]) return system
[docs] def from_system_data(system, f_idx=0, **kwargs): resname = kwargs.get("resname", "MOL") shift = kwargs.get("shift", 0) ret = "" ret += " molecule" + "\n" n_atoms = sum(system["atom_numbs"]) ret += " " + str(n_atoms) + "\n" for i in range(n_atoms): atom_type = system["atom_types"][i] atom_name = system["atom_names"][atom_type] coords = system["coords"][f_idx] * ang2nm ret += "{:>5d}{:<5s}{:>5s}{:5d}{:8.3f}{:8.3f}{:8.3f}\n".format( 1, resname, atom_name, i + shift + 1, *tuple(coords[i]) ) cell = (system["cells"][f_idx].flatten() * ang2nm)[cell_idx_gmx2dp] ret += " " + " ".join([f"{x:.3f}" for x in cell]) return ret