Skip to content

Commit

Permalink
tqdm ProgressBar replaces deprecated ProgressMeter (PR #2617)
Browse files Browse the repository at this point in the history
* Fixes #928
* Fixes #2504
* Added the ProgressBar class which inherits the tqdm.auto.tqdm object. 
   - For now, the disable keyword takes precedence over verbose, i.e. if both are set to 
     True the progress bar won't show. Setting disable=True will disable the progress bar 
     as expected. Setting verbose=False will disable the progress bar.
  - Automatically detect which version of tqdm to use (console or notebook):
     If run from a jupyter notebook or jupyter lab, will use the
     tqdm.notebook.tqdm class, else (ipython, shell, or anything else)
     will use the default tqdm.tqdm class
* add tqdm to dependencies
* Deprecate ProgressMeter through warning and text
* Replace ProgressMeter with ProgressBar everywhere in MDAnalysis
* add tests (for #928 and #2504)
* update CHANGELOG and AUTHORS
  • Loading branch information
cbouy committed Mar 22, 2020
1 parent 9a0a657 commit 5f51383
Show file tree
Hide file tree
Showing 18 changed files with 233 additions and 161 deletions.
2 changes: 1 addition & 1 deletion .appveyor.yml
Expand Up @@ -10,7 +10,7 @@ cache:
environment:
global:
CONDA_CHANNELS: conda-forge
CONDA_DEPENDENCIES: pip setuptools wheel cython mock six biopython networkx joblib matplotlib scipy vs2015_runtime pytest mmtf-python GridDataFormats hypothesis pytest-cov codecov chemfiles
CONDA_DEPENDENCIES: pip setuptools wheel cython mock six biopython networkx joblib matplotlib scipy vs2015_runtime pytest mmtf-python GridDataFormats hypothesis pytest-cov codecov chemfiles tqdm
PIP_DEPENDENCIES: gsd==1.9.3 duecredit parmed
DEBUG: "False"
MINGW_64: C:\mingw-w64\x86_64-6.3.0-posix-seh-rt_v5-rev1\mingw64\bin
Expand Down
4 changes: 2 additions & 2 deletions .travis.yml
Expand Up @@ -28,7 +28,7 @@ env:
- SETUP_CMD="${PYTEST_FLAGS}"
- BUILD_CMD="pip install -e package/ && (cd testsuite/ && python setup.py build)"
- CONDA_MIN_DEPENDENCIES="mmtf-python mock six biopython networkx cython matplotlib scipy griddataformats hypothesis gsd codecov"
- CONDA_DEPENDENCIES="${CONDA_MIN_DEPENDENCIES} seaborn>=0.7.0 clustalw=2.1 netcdf4 scikit-learn joblib>=0.12 chemfiles"
- CONDA_DEPENDENCIES="${CONDA_MIN_DEPENDENCIES} seaborn>=0.7.0 clustalw=2.1 netcdf4 scikit-learn joblib>=0.12 chemfiles tqdm>=4.43.0"
- CONDA_CHANNELS='biobuilds conda-forge'
- CONDA_CHANNEL_PRIORITY=True
- PIP_DEPENDENCIES="duecredit parmed"
Expand Down Expand Up @@ -73,7 +73,7 @@ matrix:
PIP_DEPENDENCIES="${PIP_DEPENDENCIES} setuptools<45.0.0"

- env: NAME="asv check"
PYTHON_VERSION=2.7
PYTHON_VERSION=2.7
CODECOV="false"
MAIN_CMD=""
SETUP_CMD=""
Expand Down
1 change: 1 addition & 0 deletions package/AUTHORS
Expand Up @@ -136,6 +136,7 @@ Chronological list of authors
- Anshul Angaria
- Shubham Sharma
- Yuxuan Zhuang
- Cédric Bouysset
- Abhishek Shandilya
- Morgan L. Nance
- Faraaz Shah
Expand Down
4 changes: 3 additions & 1 deletion package/CHANGELOG
Expand Up @@ -17,7 +17,7 @@ mm/dd/yy richardjgowers, kain88-de, lilyminium, p-j-smith, bdice, joaomcteixeira
PicoCentauri, davidercruz, jbarnoud, RMeli, IAlibay, mtiberti, CCook96,
Yuan-Yu, xiki-tempula, HTian1997, Iv-Hristov, hmacdope, AnshulAngaria,
ss62171, Luthaf, yuxuanzhuang, abhishandy, mlnance, shfrz, orbeckst,
wvandertoorn
wvandertoorn, cbouy

* 0.21.0

Expand Down Expand Up @@ -114,6 +114,8 @@ Enhancements
* PersistenceLength.plot() now create new axes if current axes not provided (Issue #2590)

Changes
* Deprecated :class:`ProgressMeter` and replaced it with :class:`ProgressBar` using
the tqdm package (Issue #928, PR #2617). Also fixes issue #2504.
* Removed `details` from `ClusteringMethod`s (Issue #2575, PR #2620)
* Removed deprecated :meth:`PersistenceLength.perform_fit` (Issue #2596)
* Changed :meth:`PSAnalysis.generate_paths` keywords `store` and `filename`
Expand Down
15 changes: 4 additions & 11 deletions package/MDAnalysis/analysis/base.py
Expand Up @@ -38,7 +38,7 @@
import numpy as np
from MDAnalysis import coordinates
from MDAnalysis.core.groups import AtomGroup
from MDAnalysis.lib.log import ProgressMeter
from MDAnalysis.lib.log import ProgressBar

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -131,13 +131,6 @@ def _setup_frames(self, trajectory, start=None, stop=None, step=None):
self.stop = stop
self.step = step
self.n_frames = len(range(start, stop, step))
interval = int(self.n_frames // 100)
if interval == 0:
interval = 1

verbose = getattr(self, '_verbose', False)
self._pm = ProgressMeter(self.n_frames if self.n_frames else 1,
interval=interval, verbose=verbose)

def _single_frame(self):
"""Calculate data from a single frame of trajectory
Expand Down Expand Up @@ -178,13 +171,13 @@ def run(self, start=None, stop=None, step=None, verbose=None):
self._setup_frames(self._trajectory, start, stop, step)
logger.info("Starting preparation")
self._prepare()
for i, ts in enumerate(
self._trajectory[self.start:self.stop:self.step]):
for i, ts in enumerate(ProgressBar(
self._trajectory[self.start:self.stop:self.step],
verbose=verbose)):
self._frame_index = i
self._ts = ts
# logger.info("--> Doing frame {} of {}".format(i+1, self.n_frames))
self._single_frame()
self._pm.echo(self._frame_index)
logger.info("Finishing up")
self._conclude()
return self
Expand Down
13 changes: 4 additions & 9 deletions package/MDAnalysis/analysis/density.py
Expand Up @@ -191,7 +191,8 @@
from MDAnalysis import NoDataError, MissingDataWarning
from .. import units
from ..lib import distances
from MDAnalysis.lib.log import ProgressMeter
from MDAnalysis.lib.log import ProgressBar
from MDAnalysis.lib.log import ProgressMeter # remove in 2.0
from MDAnalysis.lib.util import deprecate

from .base import AnalysisBase
Expand Down Expand Up @@ -1078,21 +1079,15 @@ def current_coordinates():
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%%]")

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

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

grid /= float(n_frames)

metadata = metadata if metadata is not None else {}
Expand Down
12 changes: 4 additions & 8 deletions package/MDAnalysis/analysis/hbonds/hbond_analysis.py
Expand Up @@ -331,7 +331,7 @@ class HydrogenBondAnalysis_OtherFF(HydrogenBondAnalysis):

from MDAnalysis import MissingDataWarning, NoDataError, SelectionError, SelectionWarning
from .. import base
from MDAnalysis.lib.log import ProgressMeter
from MDAnalysis.lib.log import ProgressBar
from MDAnalysis.lib.NeighborSearch import AtomNeighborSearch
from MDAnalysis.lib import distances

Expand Down Expand Up @@ -952,10 +952,6 @@ def run(self, start=None, stop=None, step=None, verbose=None, **kwargs):
self._timeseries = []
self.timesteps = []

pm = ProgressMeter(self.n_frames,
format="HBonds frame {current_step:5d}: {step:5d}/{numsteps} [{percentage:5.1f}%]\r",
verbose=kwargs.get('verbose', False))

try:
self.u.trajectory.time
def _get_timestep():
Expand All @@ -970,7 +966,9 @@ def _get_timestep():
logger.info("Starting analysis (frame index start=%d stop=%d, step=%d)",
self.start, self.stop, self.step)

for progress, ts in enumerate(self.u.trajectory[self.start:self.stop:self.step]):
for ts in ProgressBar(self.u.trajectory[self.start:self.stop:self.step],
desc="HBond analysis",
verbose=kwargs.get('verbose', False)):
# all bonds for this timestep
frame_results = []
# dict of tuples (atom.index, atom.index) for quick check if
Expand All @@ -981,7 +979,6 @@ def _get_timestep():
timestep = _get_timestep()
self.timesteps.append(timestep)

pm.echo(progress, current_step=frame)
self.logger_debug("Analyzing frame %(frame)d, timestep %(timestep)f ps", vars())
if self.update_selection1:
self._update_selection_1()
Expand Down Expand Up @@ -1041,7 +1038,6 @@ def _get_timestep():
dist, angle])

self._timeseries.append(frame_results)

logger.info("HBond analysis: complete; timeseries %s.timeseries",
self.__class__.__name__)

Expand Down
11 changes: 4 additions & 7 deletions package/MDAnalysis/analysis/hbonds/hbond_autocorrel.py
Expand Up @@ -213,7 +213,7 @@

import warnings

from MDAnalysis.lib.log import ProgressMeter
from MDAnalysis.lib.log import ProgressBar
from MDAnalysis.lib.distances import capped_distance, calc_angles, calc_bonds
from MDAnalysis.core.groups import requires

Expand Down Expand Up @@ -392,12 +392,9 @@ def run(self, force=False):
# for normalising later
counter = np.zeros_like(master_results, dtype=np.float32)

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

for i, (start, stop) in enumerate(zip(self._starts, self._stops)):
pm.echo(i)
for i, (start, stop) in ProgressBar(enumerate(zip(self._starts,
self._stops)), total=self.nruns,
desc="Performing run"):

# needed else trj seek thinks a np.int64 isn't an int?
results = self._single_run(int(start), int(stop))
Expand Down
11 changes: 3 additions & 8 deletions package/MDAnalysis/analysis/helanal.py
Expand Up @@ -124,7 +124,7 @@
import numpy as np

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

import warnings
Expand Down Expand Up @@ -346,14 +346,10 @@ def helanal_trajectory(universe, select="name CA",
global_fitted_tilts = []
global_screw = []

pm = ProgressMeter(n_frames, verbose=verbose,
format="Frame {step:5d}/{numsteps} "
" [{percentage:5.1f}%]")
for ts in ProgressBar(trajectory[start_frame:end_frame:frame_step],
verbose=verbose, desc="Helix analysis"):

for index, ts in enumerate(trajectory[start_frame:end_frame:frame_step]):
pm.echo(index)
frame = ts.frame

ca_positions = ca.positions
twist, bending_angles, height, rnou, origins, local_helix_axes, local_screw_angles = \
main_loop(ca_positions, ref_axis=ref_axis)
Expand Down Expand Up @@ -414,7 +410,6 @@ def helanal_trajectory(universe, select="name CA",
store.append(tmp)
#for store,tmp in zip(global_tilt,local_helix_axes): store.append(mdamath.angle(tmp,ref_axis))


twist_mean, twist_sd, twist_abdev = stats(global_twist)
height_mean, height_sd, height_abdev = stats(global_height)
rnou_mean, rnou_sd, rnou_abdev = stats(global_rnou)
Expand Down
18 changes: 5 additions & 13 deletions package/MDAnalysis/analysis/pca.py
Expand Up @@ -111,7 +111,7 @@

from MDAnalysis import Universe
from MDAnalysis.analysis.align import _fit_to
from MDAnalysis.lib.log import ProgressMeter
from MDAnalysis.lib.log import ProgressBar

from .base import AnalysisBase

Expand Down Expand Up @@ -161,11 +161,11 @@ class PCA(AnalysisBase):
Notes
-----
Computation can be speed up by supplying a precalculated mean structure
.. versionchanged:: 1.0.0
align=True now correctly aligns the trajectory and computes the correct
means and covariance matrix
.. versionchanged:: 0.19.0
The start frame is used when performing selections and calculating
mean positions. Previously the 0th frame was always used.
Expand Down Expand Up @@ -230,15 +230,8 @@ def _prepare(self):
self._ref_atom_positions -= self._ref_cog

if self._calc_mean:
interval = int(self.n_frames // 100)
interval = interval if interval > 0 else 1
format = ("Mean Calculation Step"
"%(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)
for i, ts in enumerate(self._u.trajectory[self.start:self.stop:
self.step]):
for ts in ProgressBar(self._u.trajectory[self.start:self.stop:self.step],
verbose=self._verbose, desc="Mean Calculation"):
if self.align:
mobile_cog = self._atoms.center_of_geometry()
mobile_atoms, old_rmsd = _fit_to(self._atoms.positions - mobile_cog,
Expand All @@ -248,7 +241,6 @@ def _prepare(self):
ref_com=self._ref_cog)

self.mean += self._atoms.positions.ravel()
mean_pm.echo(i)
self.mean /= self.n_frames

self.mean_atoms = self._atoms
Expand Down
5 changes: 0 additions & 5 deletions package/MDAnalysis/analysis/rms.py
Expand Up @@ -145,7 +145,6 @@
import MDAnalysis.lib.qcprot as qcp
from MDAnalysis.analysis.base import AnalysisBase
from MDAnalysis.exceptions import SelectionError, NoDataError
from MDAnalysis.lib.log import ProgressMeter
from MDAnalysis.lib.util import asiterable, iterable, get_weights


Expand Down Expand Up @@ -625,8 +624,6 @@ def _prepare(self):
self.rmsd = np.zeros((self.n_frames,
3 + len(self._groupselections_atoms)))

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

def _single_frame(self):
Expand Down Expand Up @@ -673,8 +670,6 @@ def _single_frame(self):
self._ref_coordinates64, self._mobile_coordinates64,
self._n_atoms, None, self.weights_select)

self._pm.rmsd = self.rmsd[self._frame_index, 2]


class RMSF(AnalysisBase):
r"""Calculate RMSF of given atoms across a trajectory.
Expand Down
20 changes: 7 additions & 13 deletions package/MDAnalysis/analysis/waterdynamics.py
Expand Up @@ -455,7 +455,7 @@

import numpy as np
import MDAnalysis.analysis.hbonds
from MDAnalysis.lib.log import ProgressMeter
from MDAnalysis.lib.log import ProgressBar


class HydrogenBondLifetimes(object):
Expand Down Expand Up @@ -808,11 +808,9 @@ def _sameMolecTandDT(self, selection, t0d, tf):

def _selection_serial(self, universe, selection_str):
selection = []
pm = ProgressMeter(universe.trajectory.n_frames,
interval=10, verbose=True)
for ts in universe.trajectory:
for ts in ProgressBar(universe.trajectory, verbose=True,
total=universe.trajectory.n_frames):
selection.append(universe.select_atoms(selection_str))
pm.echo(ts.frame)
return selection

@staticmethod
Expand Down Expand Up @@ -983,11 +981,9 @@ def run(self, **kwargs):

def _selection_serial(self, universe, selection_str):
selection = []
pm = ProgressMeter(universe.trajectory.n_frames,
interval=10, verbose=True)
for ts in universe.trajectory:
for ts in ProgressBar(universe.trajectory, verbose=True,
total=universe.trajectory.n_frames):
selection.append(universe.select_atoms(selection_str))
pm.echo(ts.frame)
return selection


Expand Down Expand Up @@ -1125,11 +1121,9 @@ def _sameMolecTandDT(self, selection, t0d, tf):

def _selection_serial(self, universe, selection_str):
selection = []
pm = ProgressMeter(universe.trajectory.n_frames,
interval=10, verbose=True)
for ts in universe.trajectory:
for ts in ProgressBar(universe.trajectory, verbose=True,
total=universe.trajectory.n_frames):
selection.append(universe.select_atoms(selection_str))
pm.echo(ts.frame)
return selection

def run(self, **kwargs):
Expand Down

0 comments on commit 5f51383

Please sign in to comment.