1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
# -*- Mode: python; tab-width: 4; indent-tabs-mode:nil; coding:utf-8 -*-
# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
#
# 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
#
"""NAMDBIN files format --- :mod:`MDAnalysis.coordinates.NAMDBIN`
================================================================================
Read/Write coordinates in `NAMD double-precision binary format`_ (suffix "coor" or "namdbin").
.. _`NAMD double-precision binary format` : https://www.ks.uiuc.edu/Research/namd/2.10/ug/node11.html#SECTION00061500000000000000
Classes
-------
.. autoclass:: NAMDBINReader
:members:
.. autoclass:: NAMDBINWriter
:members:
"""
from struct import pack
import numpy as np
from . import base
from ..lib import util
class NAMDBINReader(base.SingleFrameReaderBase):
"""Reader for NAMD binary coordinate files.
.. versionadded:: 1.0.0
"""
format = ["COOR", "NAMDBIN"]
units = {"length": "Angstrom"}
def _read_first_frame(self):
# Read header
with open(self.filename, "rb") as namdbin:
self.n_atoms = np.fromfile(namdbin, dtype=np.int32, count=1)[0]
self.ts = self._Timestep(self.n_atoms, **self._ts_kwargs)
self.ts.frame = 0
coord_double = np.fromfile(
namdbin, dtype=np.float64, count=self.n_atoms * 3
)
self.ts._pos[:] = np.array(coord_double, float).reshape(
self.n_atoms, 3
)
@staticmethod
def parse_n_atoms(filename, **kwargs):
with open(filename, "rb") as namdbin:
n_atoms = np.fromfile(namdbin, dtype=np.int32, count=1)[0]
return n_atoms
def Writer(self, filename, **kwargs):
"""Returns a NAMDBINWriter for *filename*.
Parameters
----------
filename: str
filename of the output NAMDBIN file
Returns
-------
:class:`NAMDBINWriter`
"""
return NAMDBINWriter(filename, **kwargs)
class NAMDBINWriter(base.WriterBase):
"""Writer for NAMD binary coordinate files.
Note
----
* Does not handle writing to bz2 or gz compressed file types.
.. versionadded:: 1.0.0
"""
format = ["COOR", "NAMDBIN"]
units = {"time": None, "length": "Angstrom"}
def __init__(self, filename, n_atoms=None, **kwargs):
"""
Parameters
----------
filename : str or :class:`~MDAnalysis.lib.util.NamedStream`
name of the output file or a stream
n_atoms : int
number of atoms for the output coordinate
"""
self.filename = util.filename(filename)
def _write_next_frame(self, obj):
"""Write information associated with ``obj`` at current frame into
trajectory
Parameters
----------
obj : :class:`~MDAnalysis.core.groups.AtomGroup` or
:class:`~MDAnalysis.core.universe.Universe`
write coordinate information associated with `obj`
.. versionchanged:: 1.0.0
Renamed from `write` to `_write_next_frame`.
.. versionchanged:: 2.0.0
Deprecated support for Timestep argument has now been removed.
Use AtomGroup or Universe as an input instead.
"""
if hasattr(obj, "atoms"): # AtomGroup or Universe
atoms = obj.atoms
n_atoms = len(atoms)
coor = atoms.positions.reshape(n_atoms * 3)
else:
errmsg = "Input obj is neither an AtomGroup or Universe"
raise TypeError(errmsg) from None
with util.openany(self.filename, "wb") as namdbin:
# Write NUMATOMS
namdbin.write(pack("i", n_atoms))
# Write Coordinate
namdbin.write(pack("{:d}d".format(len(coor)), *coor))
|