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

Fixes PM issues (jlab and non-AnalysisBase) #2310

Merged
merged 4 commits into from
Aug 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions package/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ Changes
* bump minimum numpy version to 1.13.3

Fixes
* fixes ProgressMeter issues with older Jupyter Lab versions (Issue #2078)
* fixes ProgressMeter behaviour for non-AnalysisBase methods (Issue #2084)
* fixed reading AMBER topologies with negative ATOMIC_NUMBERS (Issue #2306)
* fixed reading bz2 compressed psf files (Issue #2232)
* fixed mol2 comment header handling (Issue #2261)
Expand Down
4 changes: 2 additions & 2 deletions package/MDAnalysis/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,8 @@

# custom exceptions and warnings
from .exceptions import (
SelectionError, FinishTimeException, NoDataError, ApplicationError,
SelectionWarning, MissingDataWarning, ConversionWarning, FileFormatWarning,
SelectionError, NoDataError, ApplicationError, SelectionWarning,
MissingDataWarning, ConversionWarning, FileFormatWarning,
StreamWarning
)

Expand Down
16 changes: 10 additions & 6 deletions package/MDAnalysis/analysis/density.py
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,8 @@ def density_from_Universe(universe, delta=1.0, atomselection='name OH2',
(It should be noted that the `padding` keyword is not used when a user
defined grid is assigned).

.. versionchanged:: 0.20.0
ProgressMeter now iterates over the number of frames analysed.
.. versionchanged:: 0.19.0
*gridcenter*, *xdim*, *ydim* and *zdim* keywords added to allow for user
defined boxes
Expand Down Expand Up @@ -751,22 +753,24 @@ def current_coordinates():
grid *= 0.0
h = grid.copy()

pm = ProgressMeter(u.trajectory.n_frames, interval=interval,
start, stop, step = u.trajectory.check_slice_indices(start, stop, step)
n_frames = len(range(start, stop, step))

pm = ProgressMeter(n_frames, interval=interval,
verbose=verbose,
format="Histogramming %(n_atoms)6d atoms in frame "
"%(step)5d/%(numsteps)d [%(percentage)5.1f%%]\r")
start, stop, step = u.trajectory.check_slice_indices(start, stop, step)
for ts in u.trajectory[start:stop:step]:
"%(step)5d/%(numsteps)d [%(percentage)5.1f%%]")

for index, ts in enumerate(u.trajectory[start:stop:step]):
coord = current_coordinates()

pm.echo(ts.frame, n_atoms=len(coord))
pm.echo(index, n_atoms=len(coord))
if len(coord) == 0:
continue

h[:], edges[:] = np.histogramdd(coord, bins=bins, range=arange, normed=False)
grid += h # accumulate average histogram

n_frames = len(range(start, stop, step))
grid /= float(n_frames)

metadata = metadata if metadata is not None else {}
Expand Down
4 changes: 2 additions & 2 deletions package/MDAnalysis/analysis/hbonds/hbond_autocorrel.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,10 +389,10 @@ def run(self, force=False):

pm = ProgressMeter(self.nruns, interval=1,
format="Performing run %(step)5d/%(numsteps)d"
"[%(percentage)5.1f%%]\r")
"[%(percentage)5.1f%%]")

for i, (start, stop) in enumerate(zip(self._starts, self._stops)):
pm.echo(i + 1)
pm.echo(i)

# needed else trj seek thinks a np.int64 isn't an int?
results = self._single_run(int(start), int(stop))
Expand Down
83 changes: 65 additions & 18 deletions package/MDAnalysis/analysis/helanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,10 @@
import numpy as np

import MDAnalysis
from MDAnalysis import FinishTimeException
from MDAnalysis.lib.log import ProgressMeter
from MDAnalysis.lib import mdamath

import warnings
import logging
logger = logging.getLogger("MDAnalysis.analysis.helanal")

Expand Down Expand Up @@ -212,7 +212,9 @@ def helanal_trajectory(universe, selection="name CA",

Raises
------
FinishTimeException
ValueError
If the specified start (begin) time occurs after the end of the
trajectory object.
If the specified finish time precedes the specified start time or
current time stamp of trajectory object.

Expand All @@ -236,6 +238,8 @@ def helanal_trajectory(universe, selection="name CA",
The `quiet` keyword argument is deprecated in favor of the new
`verbose` one.

.. versionchanged:: 0.20.0
ProgressMeter now iterates over the number of frames analysed.
"""
if ref_axis is None:
ref_axis = np.array([0., 0., 1.])
Expand All @@ -248,13 +252,60 @@ def helanal_trajectory(universe, selection="name CA",
start, end = ca.resids[[0, -1]]
trajectory = universe.trajectory

# Validate user supplied begin / end times
traj_end_time = trajectory.ts.time + trajectory.totaltime

if begin is not None:
if traj_end_time < begin:
# Begin occurs after the end of the trajectory, throw error
msg = ("The input begin time ({0} ps) occurs after the end "
"of the trajectory ({1} ps)".format(begin, traj_end_time))
raise ValueError(msg)
elif trajectory.ts.time > begin:
# Begin occurs before trajectory start, warn and reset
msg = ("The input begin time ({0} ps) precedes the starting "
"trajectory time --- Setting starting frame to 0".format(
begin))
warnings.warn(msg)
logger.warning(msg)
start_frame = None
else:
start_frame = int(np.ceil((begin - trajectory.ts.time)
/ trajectory.ts.dt))
else:
start_frame = None

if finish is not None:
if trajectory.ts.time > finish:
# you'd be starting with a finish time (in ps) that has already passed or not
# available
raise FinishTimeException(
'The input finish time ({finish} ps) precedes the current trajectory time of {traj_time} ps.'.format(
finish=finish, traj_time=trajectory.time))
if (begin is not None) and (begin > finish):
# finish occurs before begin time
msg = ("The input finish time ({0} ps) precedes the input begin "
"time ({1} ps)".format(finish, begin))
raise ValueError(msg)
elif trajectory.ts.time > finish:
# you'd be starting with a finish time(in ps) that has already
# passed or is not available
msg = ("The input finish time ({0} ps) precedes the current "
"trajectory time ({1} ps)".format(finish, trajectory.time))
raise ValueError(msg)
elif traj_end_time < finish:
# finish time occurs after the end of trajectory, warn
msg = ("The input finish time ({0} ps) occurs after the end of "
"the trajectory ({1} ps). Finish time will be set to the "
"end of the trajectory".format(finish, traj_end_time))
warnings.warn(msg)
logger.warning(msg)
end_frame = None
else:
# To replicate the original behaviour of break when
# trajectory.time > finish, we add 1 here.
end_frame = int(np.floor((finish - trajectory.ts.time)
// trajectory.ts.dt) + 1)
else:
end_frame = None

start_frame, end_frame, frame_step = trajectory.check_slice_indices(
start_frame, end_frame, 1)
n_frames = len(range(start_frame, end_frame, frame_step))

if start is not None and end is not None:
logger.info("Analysing from residue %d to %d", start, end)
Expand Down Expand Up @@ -292,17 +343,13 @@ def helanal_trajectory(universe, selection="name CA",
global_fitted_tilts = []
global_screw = []

pm = ProgressMeter(trajectory.n_frames, verbose=verbose,
format="Frame %(step)10d: %(time)20.1f ps\r")
for ts in trajectory:
pm.echo(ts.frame, time=ts.time)
pm = ProgressMeter(n_frames, verbose=verbose,
format="Frame {step:5d}/{numsteps} "
" [{percentage:5.1f}%]")

for index, ts in enumerate(trajectory[start_frame:end_frame:frame_step]):
pm.echo(index)
frame = ts.frame
if begin is not None:
if trajectory.time < begin:
continue
if finish is not None:
if trajectory.time > finish:
break

ca_positions = ca.positions
twist, bending_angles, height, rnou, origins, local_helix_axes, local_screw_angles = \
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 @@ -229,7 +229,7 @@ def _prepare(self):
interval = int(self.n_frames // 100)
interval = interval if interval > 0 else 1
format = ("Mean Calculation Step"
"%(step)5d/%(numsteps)d [%(percentage)5.1f%%]\r")
"%(step)5d/%(numsteps)d [%(percentage)5.1f%%]")
mean_pm = ProgressMeter(self.n_frames if self.n_frames else 1,
interval=interval, verbose=self._verbose,
format=format)
Expand Down
2 changes: 1 addition & 1 deletion package/MDAnalysis/analysis/rms.py
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,7 @@ def _prepare(self):
3 + len(self._groupselections_atoms)))

self._pm.format = ("RMSD {rmsd:5.2f} A at frame "
"{step:5d}/{numsteps} [{percentage:5.1f}%]\r")
"{step:5d}/{numsteps} [{percentage:5.1f}%]")
self._mobile_coordinates64 = self.mobile_atoms.positions.copy().astype(np.float64)

def _single_frame(self):
Expand Down
4 changes: 0 additions & 4 deletions package/MDAnalysis/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ class SelectionError(Exception):
"""Raised when a atom selection failed."""


class FinishTimeException(Exception):
"""For Issue 188."""


class NoDataError(ValueError):
"""Raised when empty input is not allowed or required data are missing."""

Expand Down
69 changes: 64 additions & 5 deletions testsuite/MDAnalysisTests/analysis/test_helanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@

import MDAnalysis as mda
import MDAnalysis.analysis.helanal
from MDAnalysis import FinishTimeException
from MDAnalysisTests.datafiles import (GRO, XTC, PSF, DCD, PDB_small,
HELANAL_BENDING_MATRIX)
HELANAL_BENDING_MATRIX,
HELANAL_BENDING_MATRIX_SUBSET)

# reference data from a single PDB file:
# data = MDAnalysis.analysis.helanal.helanal_main(PDB_small,
Expand Down Expand Up @@ -127,6 +127,28 @@ def test_helanal_trajectory(tmpdir, reference=HELANAL_BENDING_MATRIX,
"stats for {0} mismatch".format(label))


def test_helanal_trajectory_slice(tmpdir,
reference=HELANAL_BENDING_MATRIX_SUBSET,
outfile="helanal_bending_matrix.dat"):
"""Simple regression test to validate that begin/finish work as
intended. In this case, frames 10 (time: 10.999999031120204) through to
79 (time: 79.99999295360149) should be picked up."""
u = mda.Universe(PSF, DCD)
with tmpdir.as_cwd():
# Helix 8: 161 - 187 http://www.rcsb.org/pdb/explore.do?structureId=4AKE
MDAnalysis.analysis.helanal.helanal_trajectory(
u, selection="name CA and resnum 161-187", begin=10, finish=80
)
bendingmatrix = read_bending_matrix(outfile)
ref = read_bending_matrix(reference)
assert_equal(sorted(bendingmatrix.keys()), sorted(ref.keys()),
err_msg="different contents in bending matrix data file")
for label in ref.keys():
assert_almost_equal(
bendingmatrix[label], ref[label], err_msg="bending matrix "
"starts for {0} mismatch".format(label))


def test_helanal_main(reference=HELANAL_SINGLE_DATA):
u = mda.Universe(PDB_small)
# Helix 8: 161 - 187 http://www.rcsb.org/pdb/explore.do?structureId=4AKE
Expand All @@ -140,13 +162,50 @@ def test_helanal_main(reference=HELANAL_SINGLE_DATA):
err_msg="data[{0}] mismatch".format(label))


def test_xtc_striding(tmpdir):
"""testing MDAnalysis.analysis.helanal xtc striding: Check for resolution of Issue #188."""
def test_exceptions(tmpdir):
"""Testing exceptions which can be raised"""
u = MDAnalysis.Universe(GRO, XTC)
u.trajectory[1]

# Testing xtc striding: Check for resolution of Issue #188
with tmpdir.as_cwd():
with pytest.raises(FinishTimeException):
with pytest.raises(ValueError):
MDAnalysis.analysis.helanal.helanal_trajectory(
u, selection="name CA", finish=5
)

with tmpdir.as_cwd():
with pytest.raises(ValueError):
MDAnalysis.analysis.helanal.helanal_trajectory(
u, selection="name CA", begin=1, finish=0
)

with tmpdir.as_cwd():
with pytest.raises(ValueError):
MDAnalysis.analysis.helanal.helanal_trajectory(
u, selection="name CA", begin=99999
)


def test_warnings(tmpdir):
"""Testing that a warning which can be raised"""
u = MDAnalysis.Universe(GRO, XTC)
u.trajectory[1]

with tmpdir.as_cwd():
with pytest.warns(UserWarning) as record:
MDAnalysis.analysis.helanal.helanal_trajectory(
u, selection="name CA", begin=-1, finish=99999
)

assert len(record) == 2
wmsg1 = ("The input begin time (-1 ps) precedes the starting "
"trajectory time --- Setting starting frame to 0".format(
-1,0))
assert str(record[0].message.args[0]) == wmsg1
wmsg2 = ("The input finish time ({0} ps) occurs after the end of "
"the trajectory ({1} ps). Finish time will be set to "
"the end of the trajectory".format(
99999,1000.0000762939453))
assert str(record[1].message.args[0]) == wmsg2

Loading