Source code for MDAnalysis.coordinates.TPR

# -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*-
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 fileencoding=utf-8
#
# MDAnalysis --- https://www.mdanalysis.org
# Copyright (c) 2006-2017 The MDAnalysis Development Team and contributors
# (see the file AUTHORS for the full list of names)
#
# Released under the Lesser GNU Public Licence, v2.1 or any higher version
#
# Please cite your use of MDAnalysis in published work:
#
# R. J. Gowers, M. Linke, J. Barnoud, T. J. E. Reddy, M. N. Melo, S. L. Seyler,
# D. L. Dotson, J. Domanski, S. Buchoux, I. M. Kenney, and O. Beckstein.
# MDAnalysis: A Python package for the rapid analysis of molecular dynamics
# simulations. In S. Benthall and S. Rostrup editors, Proceedings of the 15th
# Python in Science Conference, pages 102-109, Austin, TX, 2016. SciPy.
# doi: 10.25080/majora-629e541a-00e
#
# N. Michaud-Agrawal, E. J. Denning, T. B. Woolf, and O. Beckstein.
# MDAnalysis: A Toolkit for the Analysis of Molecular Dynamics Simulations.
# J. Comput. Chem. 32 (2011), 2319--2327, doi:10.1002/jcc.21787
#

"""
TPR file format --- :mod:`MDAnalysis.coordinates.TPR`
======================================================

Class for reading positions and velocities from GROMACS TPR files.


Reading TPR files
-----------------
MDAnalysis can read positions and velocities from GROMACS TPR files,
and can also do so using different versions of the topology and
coordinate file for a given system.


For example, both of these are supported modes for reading
in positions and velocities from GROMACS TPR files::

   >>> u = mda.Universe(TPR2020, TPR2024_4)
   >>> u = mda.Universe(TPR2020)


Classes
-------

.. autoclass:: TPRReader
   :members:
   :inherited-members:

"""

from . import base
from ..lib import util
from .timestep import Timestep
import MDAnalysis.topology.tpr.utils as tpr_utils
import MDAnalysis.topology.tpr.setting as S

import logging

logger = logging.getLogger("MDAnalysis.coordinates.TPR")

import numpy as np


[docs] class TPRReader(base.SingleFrameReaderBase): # TODO: reduce duplication with `TPRparser`; # we could share some state for the position # in the binary file to avoid re-reading topology # or perhaps combine the topology and coordinate reading # with some inheritance shenanigans? """Class supporting read in of positions and velocities from GROMACS TPR files. .. versionadded:: 2.10.0 """ format = "TPR" units = {"length": "nm", "velocity": "nm/ps"} _Timestep = Timestep def _read_first_frame(self): # Read header/move over topology # TODO: reduce duplication with TPRparser perhaps... with util.openany(self.filename, mode="rb") as infile: tprf = infile.read() data = tpr_utils.TPXUnpacker(tprf) try: th = tpr_utils.read_tpxheader(data) # tpxheader except (EOFError, ValueError): msg = f"{self.filename}: Invalid tpr coordinate file or cannot be recognized" logger.critical(msg) raise IOError(msg) self.ts = ts = self._Timestep(th.natoms, **self._ts_kwargs) self.n_atoms = th.natoms # Starting with gromacs 2020 (tpx version 119), the body of the file # is encoded differently. We change the unpacker accordingly. if th.fver >= S.tpxv_AddSizeField and th.fgen >= 27: actual_body_size = len(data.get_buffer()) - data.get_position() if actual_body_size == 4 * th.sizeOfTprBody: # See issue #2428. msg = ( "TPR files produced with beta versions of gromacs 2020 " "are not supported." ) logger.critical(msg) raise IOError(msg) data = tpr_utils.TPXUnpacker2020.from_unpacker(data) state_ngtc = th.ngtc # done init_state() in src/gmxlib/tpxio.c if th.bBox: tpr_utils.extract_box_info(data, th.fver) if state_ngtc > 0: if th.fver < 69: # redundancy due to different versions tpr_utils.ndo_real(data, state_ngtc) tpr_utils.ndo_real( data, state_ngtc ) # relevant to Berendsen tcoupl_lambda tpr_top = tpr_utils.do_mtop( data, th.fver, tpr_resid_from_one=True, precision=th.precision ) if th.bX: self.ts._pos = np.asarray( tpr_utils.ndo_rvec(data, th.natoms), dtype=np.float32 ) if th.bV: self.ts.velocities = np.asarray( tpr_utils.ndo_rvec(data, th.natoms), dtype=np.float32 ) self.ts.has_velocities = True