Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cythonized Timestep [Core] #3683

Merged
merged 73 commits into from
Jun 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
15f6f34
add start of timestep class
hmacdope May 24, 2022
401201d
finalize copy over
hmacdope May 24, 2022
7c9eb5f
add to init dunder and change tested class
hmacdope May 24, 2022
a1a5253
passes api tests
hmacdope May 24, 2022
0238c0b
partially working
hmacdope May 25, 2022
2334483
fix hasattr calls
hmacdope May 25, 2022
7919324
imporve error message
hmacdope May 25, 2022
ddac2ef
remove frame get set method
hmacdope May 25, 2022
3db54d6
add _frame attr
hmacdope May 25, 2022
085a7b4
make sure to cinit numpy arrays
hmacdope May 25, 2022
64cba3b
working
hmacdope May 25, 2022
25a6a7b
make changes to base
hmacdope May 25, 2022
5d7d8ef
partially fix pickling
hmacdope May 26, 2022
954aaf3
move docs around
hmacdope May 26, 2022
2d84a67
change dlpoly test to has_ rather than AttributeError
hmacdope May 26, 2022
a26f4fc
change dms test to has_velocities rather than hasattr
hmacdope May 26, 2022
84222d5
fix import in TRJ / TRZ
hmacdope May 26, 2022
b440cc3
fix attributeError
hmacdope May 26, 2022
2a6bc0d
improve setter API
hmacdope May 27, 2022
af95363
remove requirement for c-style contiguity
hmacdope May 27, 2022
e8e2305
add start of NPY API calls
hmacdope May 27, 2022
1151da6
work on correct casting and pathing for ndarray creation
hmacdope May 27, 2022
47e53dc
move to helper method
hmacdope May 27, 2022
9695fa1
improve casting etc, but whole new class of errors
hmacdope May 27, 2022
c58ed6a
stash
hmacdope May 27, 2022
00d3ccd
add in docs changes
hmacdope May 28, 2022
5c5ae31
remove doc subclasses of Timestep in TRJ and memory readers
hmacdope May 28, 2022
478e193
add docs to build
hmacdope May 28, 2022
1f225e0
tidy up a fraction in timestep.pyx
hmacdope May 28, 2022
be8b156
add cast
hmacdope May 28, 2022
c64143a
improve casts
hmacdope May 28, 2022
a478b80
okay I know this works
hmacdope May 28, 2022
1800b8b
add options
hmacdope May 28, 2022
cec7f85
promising improvememnt
hmacdope May 28, 2022
aa01cb8
move memory reader to Timestep
hmacdope May 29, 2022
255de91
update forces and vels to use PyArray interface
hmacdope May 29, 2022
548d0ce
clean up unsued snippets and make array innit smaller
hmacdope May 30, 2022
4d393c5
add in some explanatory notes
hmacdope May 30, 2022
f9a5d2a
Merge remote-tracking branch 'upstream/develop' into CythonTimestep
hmacdope May 30, 2022
12d52b0
improve for docs
hmacdope May 31, 2022
058e6ea
tidy docstrings
hmacdope May 31, 2022
e606af5
change to 0 size init
hmacdope May 31, 2022
e9923b4
autopep8
hmacdope May 31, 2022
80a1407
add __all__ and change docs in init
hmacdope May 31, 2022
7cab52f
fix docs build
hmacdope May 31, 2022
9bb8eb7
fix bug on setting pos
hmacdope Jun 1, 2022
138727b
change import
hmacdope Jun 1, 2022
405d55b
change refs in docs to base.Timestep to timestep.Timestep
hmacdope Jun 1, 2022
b900709
fix imports in readers that specifically import timestep
hmacdope Jun 1, 2022
1df32e0
change from attribute error in TRZwriter so that velocities can be co…
hmacdope Jun 1, 2022
90ca2a2
add explicit import for NoDataError
hmacdope Jun 1, 2022
3c89c85
move to copy api
hmacdope Jun 1, 2022
e2bfd33
iron out _frame attribute hanging around in TRZ reader
hmacdope Jun 1, 2022
3b15c8d
remove useless imports
hmacdope Jun 1, 2022
daa2c9c
add pxd and libmda imports
hmacdope Jun 1, 2022
5f709eb
move decls of C level vars to pxd file
hmacdope Jun 1, 2022
cee8860
remove header junk
hmacdope Jun 5, 2022
714c97c
add and improve comments
hmacdope Jun 5, 2022
e2f1827
change BUG to NOTE for dtype
hmacdope Jun 5, 2022
95372bf
add header int64_t
hmacdope Jun 5, 2022
32e2a80
remove __ne__
hmacdope Jun 5, 2022
9fbf8d1
change isinstance __eq__ check to return NotImplemented
hmacdope Jun 5, 2022
af3337d
add dtype tests
hmacdope Jun 5, 2022
92cad0b
add timestep API test for setting box to None
hmacdope Jun 5, 2022
8b862bb
remove try except block for repr
hmacdope Jun 6, 2022
8c735b7
add test for __repr__ with and without a box
hmacdope Jun 6, 2022
93d63d6
Merge remote-tracking branch 'upstream/develop' into CythonTimestep
hmacdope Jun 6, 2022
3525127
add alloc flags
hmacdope Jun 6, 2022
5631c33
remove dtype kwarg
hmacdope Jun 6, 2022
35c4772
remove __getattr__ special method
hmacdope Jun 6, 2022
c691ace
add __getattr__ dunder back in
hmacdope Jun 6, 2022
1829281
CHANGELOG
hmacdope Jun 6, 2022
2ca43d6
Merge branch 'develop' into CythonTimestep
richardjgowers Jun 13, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The rules for this file:
* release numbers follow "Semantic Versioning" http://semver.org

------------------------------------------------------------------------------
??/??/?? IAlibay, PicoCentauri, orbeckst
??/??/?? IAlibay, PicoCentauri, orbeckst, hmacdope

* 2.3.0

Expand All @@ -24,6 +24,8 @@ Enhancements
* Add `norm` parameter to InterRDF, InterRDF_s to normalize as rdf,
number density or do not normalize at all. (Issue #3687)
* Additional logger.info output when per-frame analysis starts (PR #3710)
* Timestep has been converted to a Cython Extension type
(CZI Performance track, PR #3683)

Changes

Expand Down
2 changes: 1 addition & 1 deletion package/MDAnalysis/analysis/distances.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def contact_matrix(coord, cutoff=15.0, returntype="numpy", box=None):
* ``"sparse"``: return as a :class:`scipy.sparse.lil_matrix`
box : array-like or ``None``, optional, default ``None``
Simulation cell dimensions in the form of
:attr:`MDAnalysis.trajectory.base.Timestep.dimensions` when
:attr:`MDAnalysis.trajectory.timestep.Timestep.dimensions` when
periodic boundary conditions should be taken into account for
the calculation of contacts.

Expand Down
2 changes: 1 addition & 1 deletion package/MDAnalysis/analysis/pca.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ def project_single_frame(self, components=None, group=None, anchor=None):
-------
function
The resulting function f(ts) takes as input a
:class:`~MDAnalysis.coordinates.base.Timestep` ts,
:class:`~MDAnalysis.coordinates.timestep.Timestep` ts,
and returns ts with the projected structure

.. warning::
Expand Down
2 changes: 1 addition & 1 deletion package/MDAnalysis/auxiliary/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@

'Assignment' of auxiliary steps to trajectory timesteps is determined from the time
of the auxiliary step, ``dt`` of the trajectory and time at the first frame of the
trajectory (obtained through a :class:`~MDAnalysis.coordinates.base.Timestep`
trajectory (obtained through a :class:`~MDAnalysis.coordinates.timestep.Timestep`
instance from the trajectory), as::

frame = floor((time_at_step - time_at_frame_0 + dt/2)/dt)
Expand Down
12 changes: 6 additions & 6 deletions package/MDAnalysis/auxiliary/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,13 +355,13 @@ def update_ts(self, ts):

Parameters
----------
ts : :class:`~MDAnalysis.coordinates.base.Timestep` object
ts : :class:`~MDAnalysis.coordinates.timestep.Timestep` object
The trajectory timestep for which corresponding auxiliary data is
to be read and updated.

Returns
-------
:class:`~MDAnalysis.coordinates.base.Timestep`
:class:`~MDAnalysis.coordinates.timestep.Timestep`
*ts* with the representative auxiliary
value in ``ts.aux`` be updated appropriately.

Expand Down Expand Up @@ -395,7 +395,7 @@ def read_ts(self, ts):

Parameters
----------
ts : :class:`~MDAnalysis.coordinates.base.Timestep` object
ts : :class:`~MDAnalysis.coordinates.timestep.Timestep` object
The trajectory timestep for which corresponding auxiliary data is
to be read.

Expand Down Expand Up @@ -449,7 +449,7 @@ def step_to_frame(self, step, ts, return_time_diff=False):
step : int
Number of the auxiliary step to calculate closest trajectory frame
for.
ts : :class:`~MDAnalysis.coordinates.base.Timestep` object
ts : :class:`~MDAnalysis.coordinates.timestep.Timestep` object
(Any) timestep from the trajectory the calculated frame number is to
correspond to.
return_time_diff : bool, optional
Expand Down Expand Up @@ -492,7 +492,7 @@ def move_to_ts(self, ts):

Parameters
----------
ts : :class:`~MDAnalysis.coordinates.base.Timestep` object
ts : :class:`~MDAnalysis.coordinates.timestep.Timestep` object
The trajectory timestep before which the auxiliary reader is to
be positioned.
"""
Expand Down Expand Up @@ -526,7 +526,7 @@ def next_nonempty_frame(self, ts):

Parameters
----------
ts : :class:`~MDAnalysis.coordinates.base.Timestep` object
ts : :class:`~MDAnalysis.coordinates.timestep.Timestep` object
Any timestep from the trajectory for which the next 'non-empty'
frame is to be found.

Expand Down
1 change: 0 additions & 1 deletion package/MDAnalysis/coordinates/DLPoly.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import numpy as np

from . import base
from .base import Timestep
from . import core
from ..lib import util
from ..lib.util import cached, store_init_arguments
Expand Down
2 changes: 0 additions & 2 deletions package/MDAnalysis/coordinates/DMS.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@
from . import base
from .core import triclinic_box

from .base import Timestep


class DMSReader(base.SingleFrameReaderBase):
"""
Expand Down
3 changes: 0 additions & 3 deletions package/MDAnalysis/coordinates/FHIAIMS.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,6 @@
from ..lib import mdamath


from .base import Timestep


class FHIAIMSReader(base.SingleFrameReaderBase):
"""Reader for the FHIAIMS geometry format.

Expand Down
3 changes: 1 addition & 2 deletions package/MDAnalysis/coordinates/GRO.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,10 @@
import numpy as np

from . import base
from .base import Timestep
from .core import triclinic_box, triclinic_vectors
from ..exceptions import NoDataError
from ..lib import util

from .timestep import Timestep

"""unitcell dimensions (A, B, C, alpha, beta, gamma)

Expand Down
8 changes: 4 additions & 4 deletions package/MDAnalysis/coordinates/H5MD.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,11 @@ class H5MDReader(base.ReaderBase):

Additional data in the *observables* group of the H5MD file are
loaded into the :attr:`Timestep.data
<MDAnalysis.coordinates.base.Timestep.data>` dictionary.
<MDAnalysis.coordinates.timestep.Timestep.data>` dictionary.

Only 3D-periodic boxes or no periodicity are supported; for no
periodicity, :attr:`Timestep.dimensions
<MDAnalysis.coordinates.base.Timestep.dimensions>` will return ``None``.
<MDAnalysis.coordinates.timestep.Timestep.dimensions>` will return ``None``.

Although H5MD can store varying numbers of particles per time step
as produced by, e.g., GCMC simulations, MDAnalysis can currently
Expand Down Expand Up @@ -826,7 +826,7 @@ class H5MDWriter(base.WriterBase):
H5MD trajectories are automatically recognised by the
file extension ".h5md".

All data from the input :class:`~MDAnalysis.coordinates.base.Timestep` is
All data from the input :class:`~MDAnalysis.coordinates.timestep.Timestep` is
written by default. For detailed information on how :class:`H5MDWriter`
handles units, compression, and chunking, see the Notes section below.

Expand Down Expand Up @@ -934,7 +934,7 @@ class H5MDWriter(base.WriterBase):

By default, the writer will write all available data (positions,
velocities, and forces) if detected in the input
:class:`~MDAnalysis.coordinates.base.Timestep`. In addition, the settings
:class:`~MDAnalysis.coordinates.timestep.Timestep`. In addition, the settings
for `compression` and `compression_opts` will be read from
the first available group of positions, velocities, or forces and used as
the default value. To write a file without any one of these datsets,
Expand Down
9 changes: 5 additions & 4 deletions package/MDAnalysis/coordinates/PDB.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@
from ..lib import util
from ..lib.util import store_init_arguments
from . import base
from .timestep import Timestep
from ..topology.core import guess_atom_element
from ..exceptions import NoDataError

Expand Down Expand Up @@ -870,13 +871,13 @@ def _update_frame(self, obj):
* :attr:`PDBWriter.trajectory` (the underlying trajectory
:class:`~MDAnalysis.coordinates.base.Reader`)
* :attr:`PDBWriter.timestep` (the underlying trajectory
:class:`~MDAnalysis.coordinates.base.Timestep`)
:class:`~MDAnalysis.coordinates.timestep.Timestep`)

Before calling :meth:`_write_next_frame` this method **must** be
called at least once to enable extracting topology information from the
current frame.
"""
if isinstance(obj, base.Timestep):
if isinstance(obj, Timestep):
raise TypeError("PDBWriter cannot write Timestep objects "
"directly, since they lack topology information ("
"atom names and types) required in PDB files")
Expand Down Expand Up @@ -970,14 +971,14 @@ def _write_next_frame(self, ts=None, **kwargs):

:Keywords:
*ts*
:class:`base.Timestep` object containing coordinates to be written to trajectory file;
:class:`timestep.Timestep` object containing coordinates to be written to trajectory file;
if ``None`` then :attr:`PDBWriter.ts`` is tried.
*multiframe*
``False``: write a single frame (default); ``True`` behave as a trajectory writer

.. Note::

Before using this method with another :class:`base.Timestep` in the *ts*
Before using this method with another :class:`timestep.Timestep` in the *ts*
argument, :meth:`PDBWriter._update_frame` *must* be called
with the :class:`~MDAnalysis.core.groups.AtomGroup.Universe` as
its argument so that topology information can be gathered.
Expand Down
36 changes: 1 addition & 35 deletions package/MDAnalysis/coordinates/TRJ.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,28 +41,6 @@
* lengths in Angstrom (Å)
* time in ps (but see below)

AMBER trajectory coordinate frames are based on a custom :class:`Timestep`
object.

.. autoclass:: Timestep
:members:

.. attribute:: _pos

coordinates of the atoms as a :class:`numpy.ndarray` of shape `(n_atoms, 3)`

.. attribute:: _velocities

velocities of the atoms as a :class:`numpy.ndarray` of shape `(n_atoms, 3)`;
only available if the trajectory contains velocities or if the
*velocities* = ``True`` keyword has been supplied.

.. attribute:: _forces

forces of the atoms as a :class:`numpy.ndarray` of shape `(n_atoms, 3)`;
only available if the trajectory contains forces or if the
*forces* = ``True`` keyword has been supplied.


.. _netcdf-trajectories:

Expand Down Expand Up @@ -159,6 +137,7 @@
from math import isclose

import MDAnalysis
from .timestep import Timestep
from . import base
from ..lib import util
from ..lib.util import store_init_arguments
Expand All @@ -172,19 +151,6 @@
logger.warning("netCDF4 is not available. Writing AMBER ncdf files will be slow.")


class Timestep(base.Timestep):
"""AMBER trajectory Timestep.

The Timestep can be initialized with `arg` being an integer
(the number of atoms) and an optional keyword argument `velocities` to
allocate space for both coordinates and velocities;

.. versionchanged:: 0.10.0
Added ability to contain Forces
"""
order = 'C'


class TRJReader(base.ReaderBase):
"""AMBER trajectory reader.

Expand Down
23 changes: 13 additions & 10 deletions package/MDAnalysis/coordinates/TRZ.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
import errno

from . import base
from .base import Timestep
from ..exceptions import NoDataError
from .timestep import Timestep
from ..lib import util
from ..lib.util import cached, store_init_arguments
from .core import triclinic_box, triclinic_vectors
Expand All @@ -62,8 +63,8 @@ class TRZReader(base.ReaderBase):

Attributes
----------
ts : base.Timestep
:class:`~MDAnalysis.coordinates.base.Timestep` object containing
ts : timestep.Timestep
:class:`~MDAnalysis.coordinates.timestep.Timestep` object containing
coordinates of current frame

Note
Expand All @@ -83,6 +84,8 @@ class TRZReader(base.ReaderBase):
.. versionchanged:: 2.1.0
TRZReader now returns a default :attr:`dt` of 1.0 when it cannot be
obtained from the difference between two frames.
.. versionchanged:: 2.3.0
_frame attribute moved to `ts.data` dictionary.
"""

format = "TRZ"
Expand Down Expand Up @@ -198,7 +201,7 @@ def _read_next_timestep(self, ts=None):
"Maybe `topology` is wrong?".format(
self.n_atoms))
ts.frame = data['nframe'][0] - 1 # 0 based for MDA
ts._frame = data['ntrj'][0]
ts.data['frame'] = data['ntrj'][0] # moved from attr to data
ts.time = data['treal'][0]
ts.dimensions = triclinic_box(*(data['box'].reshape(3, 3)))
ts.data['pressure'] = data['pressure']
Expand Down Expand Up @@ -295,9 +298,9 @@ def skip_timestep(self):
"""Timesteps between trajectory frames"""
curr_frame = self.ts.frame
try:
t0 = self.ts._frame
t0 = self.ts.data['frame']
self.next()
t1 = self.ts._frame
t1 = self.ts.data['frame']
skip_timestep = t1 - t0
except StopIteration:
return 0
Expand Down Expand Up @@ -520,8 +523,8 @@ def _write_next_frame(self, obj):
data[att] = 0.0
faked_attrs.append(att)
try:
data['step'] = ts._frame
except AttributeError:
data['step'] = ts.data['frame']
except KeyError:
data['step'] = ts.frame
faked_attrs.append('step')
try:
Expand All @@ -543,8 +546,8 @@ def _write_next_frame(self, obj):
unitcell = np.zeros(9, dtype=np.float32)

try:
vels = ts._velocities
except AttributeError:
vels = ts.velocities
except NoDataError:
vels = np.zeros((self.n_atoms, 3), dtype=np.float32, order='F')
warnings.warn("Timestep didn't have velocity information, "
"this will be set to zero in output trajectory. ")
Expand Down
4 changes: 2 additions & 2 deletions package/MDAnalysis/coordinates/TXYZ.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
from ..lib import util
from . import base
from ..lib.util import openany, cached, store_init_arguments

from .timestep import Timestep

class TXYZReader(base.ReaderBase):
"""Reads from a TXYZ file"""
Expand All @@ -61,7 +61,7 @@ class TXYZReader(base.ReaderBase):
format = ['TXYZ', 'ARC']
# these are assumed!
units = {'time': 'ps', 'length': 'Angstrom'}
_Timestep = base.Timestep
_Timestep = Timestep

@store_init_arguments
def __init__(self, filename, **kwargs):
Expand Down
3 changes: 2 additions & 1 deletion package/MDAnalysis/coordinates/XYZ.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
logger = logging.getLogger('MDAnalysis.coordinates.XYZ')

from . import base
from .timestep import Timestep
from ..lib import util
from ..lib.util import cached, store_init_arguments
from ..exceptions import NoDataError
Expand Down Expand Up @@ -334,7 +335,7 @@ class XYZReader(base.ReaderBase):
format = "XYZ"
# these are assumed!
units = {'time': 'ps', 'length': 'Angstrom'}
_Timestep = base.Timestep
_Timestep = Timestep

@store_init_arguments
def __init__(self, filename, **kwargs):
Expand Down
Loading