From f3facaecb0e19d1885e059ba48cf654665b82e79 Mon Sep 17 00:00:00 2001 From: VOD555 Date: Thu, 6 May 2021 20:42:18 -0700 Subject: [PATCH 01/16] using self.results instead of self --- package/MDAnalysis/analysis/rdf.py | 38 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/package/MDAnalysis/analysis/rdf.py b/package/MDAnalysis/analysis/rdf.py index c85ab37eb90..e4225d4307c 100644 --- a/package/MDAnalysis/analysis/rdf.py +++ b/package/MDAnalysis/analysis/rdf.py @@ -250,12 +250,12 @@ def _prepare(self): count, edges = np.histogram([-1], **self.rdf_settings) count = count.astype(np.float64) count *= 0.0 - self.count = count - self.edges = edges - self.bins = 0.5 * (edges[:-1] + edges[1:]) + self.results.count = count + self.results.edges = edges + self.results.bins = 0.5 * (edges[:-1] + edges[1:]) # Need to know average volume - self.volume = 0.0 + self.results.volume = 0.0 # Set the max range to filter the search radius self._maxrange = self.rdf_settings['range'][1] @@ -273,9 +273,9 @@ def _single_frame(self): count = np.histogram(dist, **self.rdf_settings)[0] - self.count += count + self.results.count += count - self.volume += self._ts.volume + self.results.volume += self._ts.volume def _conclude(self): # Number of each selection @@ -294,12 +294,12 @@ def _conclude(self): vol *= 4/3.0 * np.pi # Average number density - box_vol = self.volume / self.n_frames + box_vol = self.results.volume / self.n_frames density = N / box_vol - rdf = self.count / (density * vol * self.n_frames) + rdf = self.results.count / (density * vol * self.n_frames) - self.rdf = rdf + self.results.rdf = rdf class InterRDF_s(AnalysisBase): @@ -394,12 +394,12 @@ def _prepare(self): count_list = [np.zeros((ag1.n_atoms, ag2.n_atoms, len(count)), dtype=np.float64) for ag1, ag2 in self.ags] - self.count = count_list - self.edges = edges - self.bins = 0.5 * (edges[:-1] + edges[1:]) + self.results.count = count_list + self.results.edges = edges + self.results.bins = 0.5 * (edges[:-1] + edges[1:]) # Need to know average volume - self.volume = 0.0 + self.results.volume = 0.0 self._maxrange = self.rdf_settings['range'][1] @@ -414,7 +414,7 @@ def _single_frame(self): self.count[i][idx1, idx2, :] += np.histogram(dist[j], **self.rdf_settings)[0] - self.volume += self._ts.volume + self.results.volume += self._ts.volume def _conclude(self): @@ -431,16 +431,16 @@ def _conclude(self): indices.append([ag1.indices, ag2.indices]) # Average number density - box_vol = self.volume / self.n_frames + box_vol = self.results.volume / self.n_frames density = 1 / box_vol if self._density: - rdf.append(self.count[i] / (vol * self.n_frames)) + rdf.append(self.results.count[i] / (vol * self.n_frames)) else: - rdf.append(self.count[i] / (density * vol * self.n_frames)) + rdf.append(self.results.count[i] / (density * vol * self.n_frames)) - self.rdf = rdf - self.indices = indices + self.results.rdf = rdf + self.results.indices = indices def get_cdf(self): r"""Calculate the cumulative counts for all sites. From 13d93ca3b8e7feb4a904bebf3be50e654131f411 Mon Sep 17 00:00:00 2001 From: VOD555 Date: Thu, 6 May 2021 22:00:51 -0700 Subject: [PATCH 02/16] update tests --- package/MDAnalysis/analysis/rdf.py | 36 +++++++++--------- .../MDAnalysisTests/analysis/test_rdf.py | 14 +++---- .../MDAnalysisTests/analysis/test_rdf_s.py | 38 ++++++++++--------- 3 files changed, 47 insertions(+), 41 deletions(-) diff --git a/package/MDAnalysis/analysis/rdf.py b/package/MDAnalysis/analysis/rdf.py index e4225d4307c..6a893260f17 100644 --- a/package/MDAnalysis/analysis/rdf.py +++ b/package/MDAnalysis/analysis/rdf.py @@ -243,7 +243,7 @@ def __init__(self, g1, g2, self.rdf_settings = {'bins': nbins, 'range': range} - self._exclusion_block = exclusion_block + self.results._exclusion_block = exclusion_block def _prepare(self): # Empty histogram to store the RDF @@ -259,15 +259,15 @@ def _prepare(self): # Set the max range to filter the search radius self._maxrange = self.rdf_settings['range'][1] - def _single_frame(self): pairs, dist = distances.capped_distance(self.g1.positions, self.g2.positions, self._maxrange, box=self.u.dimensions) # Maybe exclude same molecule distances - if self._exclusion_block is not None: - idxA, idxB = pairs[:, 0]//self._exclusion_block[0], pairs[:, 1]//self._exclusion_block[1] + if self.results._exclusion_block is not None: + idxA = pairs[:, 0]//self.results._exclusion_block[0], + idxB = pairs[:, 1]//self.results._exclusion_block[1] mask = np.where(idxA != idxB)[0] dist = dist[mask] @@ -284,14 +284,14 @@ def _conclude(self): N = nA * nB # If we had exclusions, take these into account - if self._exclusion_block: - xA, xB = self._exclusion_block + if self.results._exclusion_block: + xA, xB = self.results._exclusion_block nblocks = nA / xA N -= xA * xB * nblocks # Volume in each radial shell - vol = np.power(self.edges[1:], 3) - np.power(self.edges[:-1], 3) - vol *= 4/3.0 * np.pi + vols = np.power(self.results.edges, 3) + vol = 4/3.0 * np.pi * (vols[1:] - vols[:-1]) # Average number density box_vol = self.results.volume / self.n_frames @@ -391,10 +391,11 @@ def _prepare(self): # Empty list to store the RDF count_list = [] count, edges = np.histogram([-1], **self.rdf_settings) - count_list = [np.zeros((ag1.n_atoms, ag2.n_atoms, len(count)), dtype=np.float64) + l = len(count) + count_ini = [np.zeros((ag1.n_atoms, ag2.n_atoms, l), dtype=np.float64) for ag1, ag2 in self.ags] - self.results.count = count_list + self.results.count = count_ini self.results.edges = edges self.results.bins = 0.5 * (edges[:-1] + edges[1:]) @@ -411,16 +412,16 @@ def _single_frame(self): box=self.u.dimensions) for j, (idx1, idx2) in enumerate(pairs): - self.count[i][idx1, idx2, :] += np.histogram(dist[j], - **self.rdf_settings)[0] + self.results.count[i][idx1, idx2, :] += np.histogram(dist[j], + **self.rdf_settings)[0] self.results.volume += self._ts.volume def _conclude(self): # Volume in each radial shell - vol = np.power(self.edges[1:], 3) - np.power(self.edges[:-1], 3) - vol *= 4/3.0 * np.pi + vols = np.power(self.results.edges, 3) + vol = 4/3.0 * np.pi * (vols[1:] - vols[:-1]) # Empty lists to restore indices, RDF indices = [] @@ -437,7 +438,8 @@ def _conclude(self): if self._density: rdf.append(self.results.count[i] / (vol * self.n_frames)) else: - rdf.append(self.results.count[i] / (density * vol * self.n_frames)) + rdf.append(self.results.count[i] / + (density * vol * self.n_frames)) self.results.rdf = rdf self.results.indices = indices @@ -462,11 +464,11 @@ def get_cdf(self): # Empty list to restore CDF cdf = [] - for count in self.count: + for count in self.results.count: cdf.append(np.cumsum(count, axis=2) / self.n_frames) # Results stored in self.cdf # self.cdf is a list of cdf between pairs of AtomGroups in ags - self.cdf = cdf + self.results.cdf = cdf return cdf diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf.py b/testsuite/MDAnalysisTests/analysis/test_rdf.py index 5839b31aae0..df701b57a90 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf.py @@ -47,7 +47,7 @@ def test_nbins(u): s2 = u.atoms[3:] rdf = InterRDF(s1, s2, nbins=412).run() - assert len(rdf.bins) == 412 + assert len(rdf.results.bins) == 412 def test_range(u): @@ -56,8 +56,8 @@ def test_range(u): rmin, rmax = 1.0, 13.0 rdf = InterRDF(s1, s2, range=(rmin, rmax)).run() - assert rdf.edges[0] == rmin - assert rdf.edges[-1] == rmax + assert rdf.results.edges[0] == rmin + assert rdf.results.edges[-1] == rmax def test_count_sum(sels): @@ -65,14 +65,14 @@ def test_count_sum(sels): # should see 8 comparisons in count s1, s2 = sels rdf = InterRDF(s1, s2).run() - assert rdf.count.sum() == 8 + assert rdf.results.count.sum() == 8 def test_count(sels): # should see two distances with 4 counts each s1, s2 = sels rdf = InterRDF(s1, s2).run() - assert len(rdf.count[rdf.count == 4]) == 2 + assert len(rdf.results.count[rdf.results.count == 4]) == 2 def test_double_run(sels): @@ -80,11 +80,11 @@ def test_double_run(sels): s1, s2 = sels rdf = InterRDF(s1, s2).run() rdf.run() - assert len(rdf.count[rdf.count == 4]) == 2 + assert len(rdf.results.count[rdf.results.count == 4]) == 2 def test_exclusion(sels): # should see two distances with 4 counts each s1, s2 = sels rdf = InterRDF(s1, s2, exclusion_block=(1, 2)).run() - assert rdf.count.sum() == 4 + assert rdf.results.count.sum() == 4 diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py index 7fafc37def4..09824a10565 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py @@ -54,15 +54,15 @@ def rdf(u, sels): def test_nbins(u, sels): rdf = InterRDF_s(u, sels, nbins=412).run() - assert len(rdf.bins) == 412 + assert len(rdf.results.bins) == 412 def test_range(u, sels): rmin, rmax = 1.0, 13.0 rdf = InterRDF_s(u, sels, range=(rmin, rmax)).run() - assert rdf.edges[0] == rmin - assert rdf.edges[-1] == rmax + assert rdf.results.edges[0] == rmin + assert rdf.results.edges[-1] == rmax def test_count_size(rdf): @@ -73,30 +73,35 @@ def test_count_size(rdf): # 2 elements in rdf.count[1] # 2 elements in rdf.count[1][0] # 2 elements in rdf.count[1][1] - assert len(rdf.count) == 2 - assert len(rdf.count[0]) == 1 - assert len(rdf.count[0][0]) == 2 - assert len(rdf.count[1]) == 2 - assert len(rdf.count[1][0]) == 2 - assert len(rdf.count[1][1]) == 2 + assert len(rdf.results.count) == 2 + assert len(rdf.results.count[0]) == 1 + assert len(rdf.results.count[0][0]) == 2 + assert len(rdf.results.count[1]) == 2 + assert len(rdf.results.count[1][0]) == 2 + assert len(rdf.results.count[1][1]) == 2 def test_count(rdf): # should see one distance with 5 counts in count[0][0][1] # should see one distance with 3 counts in count[1][1][0] - assert len(rdf.count[0][0][1][rdf.count[0][0][1] == 5]) == 1 - assert len(rdf.count[1][1][0][rdf.count[1][1][0] == 3]) == 1 + sel0 = rdf.results.count[0][0][1] == 5 + sel1 = rdf.results.count[1][1][0] == 3 + assert len(rdf.results.count[0][0][1][sel0]) == 1 + assert len(rdf.results.count[1][1][0][sel1]) == 1 def test_double_run(rdf): # running rdf twice should give the same result - assert len(rdf.count[0][0][1][rdf.count[0][0][1] == 5]) == 1 - assert len(rdf.count[1][1][0][rdf.count[1][1][0] == 3]) == 1 + sel0 = rdf.results.count[0][0][1] == 5 + sel1 = rdf.results.count[1][1][0] == 3 + assert len(rdf.results.count[0][0][1][sel0]) == 1 + assert len(rdf.results.count[1][1][0][sel1]) == 1 def test_cdf(rdf): rdf.get_cdf() - assert rdf.cdf[0][0][0][-1] == rdf.count[0][0][0].sum()/rdf.n_frames + ref = rdf.results.count[0][0][0].sum()/rdf.n_frames + assert rdf.results.cdf[0][0][0][-1] == ref @pytest.mark.parametrize("density, value", [ @@ -106,11 +111,10 @@ def test_cdf(rdf): def test_density(u, sels, density, value): kwargs = {'density': density} if density is not None else {} rdf = InterRDF_s(u, sels, **kwargs).run() - assert_almost_equal(max(rdf.rdf[0][0][0]), value) + assert_almost_equal(max(rdf.results.rdf[0][0][0]), value) if not density: s1 = u.select_atoms('name ZND and resid 289') s2 = u.select_atoms( 'name OD1 and resid 51 and sphzone 5.0 (resid 289)') rdf_ref = InterRDF(s1, s2).run() - assert_almost_equal(rdf_ref.rdf, rdf.rdf[0][0][0]) - + assert_almost_equal(rdf_ref.results.rdf, rdf.results.rdf[0][0][0]) From fa9161ebb7c9a1b6df2f25a2c91c516e37938b7e Mon Sep 17 00:00:00 2001 From: VOD555 Date: Thu, 6 May 2021 23:06:02 -0700 Subject: [PATCH 03/16] add tests for DeprecationWarning --- package/MDAnalysis/analysis/rdf.py | 93 +++++++++++++------ .../MDAnalysisTests/analysis/test_rdf.py | 25 +++-- .../MDAnalysisTests/analysis/test_rdf_s.py | 45 +++++---- 3 files changed, 113 insertions(+), 50 deletions(-) diff --git a/package/MDAnalysis/analysis/rdf.py b/package/MDAnalysis/analysis/rdf.py index 6a893260f17..c0d7d1d6c43 100644 --- a/package/MDAnalysis/analysis/rdf.py +++ b/package/MDAnalysis/analysis/rdf.py @@ -172,6 +172,7 @@ .. - Coordination number """ +import warnings import numpy as np from ..lib.util import blocks_of @@ -243,19 +244,19 @@ def __init__(self, g1, g2, self.rdf_settings = {'bins': nbins, 'range': range} - self.results._exclusion_block = exclusion_block + self._exclusion_block = exclusion_block def _prepare(self): # Empty histogram to store the RDF count, edges = np.histogram([-1], **self.rdf_settings) count = count.astype(np.float64) count *= 0.0 - self.results.count = count - self.results.edges = edges + self.count = count + self.edges = edges self.results.bins = 0.5 * (edges[:-1] + edges[1:]) # Need to know average volume - self.results.volume = 0.0 + self.volume = 0.0 # Set the max range to filter the search radius self._maxrange = self.rdf_settings['range'][1] @@ -265,17 +266,17 @@ def _single_frame(self): self._maxrange, box=self.u.dimensions) # Maybe exclude same molecule distances - if self.results._exclusion_block is not None: - idxA = pairs[:, 0]//self.results._exclusion_block[0], - idxB = pairs[:, 1]//self.results._exclusion_block[1] + if self._exclusion_block is not None: + idxA = pairs[:, 0]//self._exclusion_block[0], + idxB = pairs[:, 1]//self._exclusion_block[1] mask = np.where(idxA != idxB)[0] dist = dist[mask] count = np.histogram(dist, **self.rdf_settings)[0] - self.results.count += count + self.count += count - self.results.volume += self._ts.volume + self.volume += self._ts.volume def _conclude(self): # Number of each selection @@ -284,23 +285,39 @@ def _conclude(self): N = nA * nB # If we had exclusions, take these into account - if self.results._exclusion_block: - xA, xB = self.results._exclusion_block + if self._exclusion_block: + xA, xB = self._exclusion_block nblocks = nA / xA N -= xA * xB * nblocks # Volume in each radial shell - vols = np.power(self.results.edges, 3) + vols = np.power(self.edges, 3) vol = 4/3.0 * np.pi * (vols[1:] - vols[:-1]) # Average number density - box_vol = self.results.volume / self.n_frames + box_vol = self.volume / self.n_frames density = N / box_vol - rdf = self.results.count / (density * vol * self.n_frames) + rdf = self.count / (density * vol * self.n_frames) self.results.rdf = rdf + @property + def bins(self): + wmsg = ("The `bins` attribute was deprecated in MDAnalysis 2.0.0 " + "and will be removed in MDAnalysis 3.0.0. Please use " + "`results.bins` instead") + warnings.warn(wmsg, DeprecationWarning) + return self.results.bins + + @property + def rdf(self): + wmsg = ("The `rdf` attribute was deprecated in MDAnalysis 2.0.0 " + "and will be removed in MDAnalysis 3.0.0. Please use " + "`results.rdf` instead") + warnings.warn(wmsg, DeprecationWarning) + return self.results.rdf + class InterRDF_s(AnalysisBase): r"""Site-specific intermolecular pair distribution function @@ -350,7 +367,7 @@ class InterRDF_s(AnalysisBase): Results are available through the :attr:`bins` and :attr:`rdf` attributes:: - plt.plot(rdf.bins, rdf.rdf[0][0, 0]) + plt.plot(rdf.results.bins, rdf.results.rdf[0][0, 0]) (Which plots the rdf between the first atom in ``s1`` and the first atom in ``s2``) @@ -363,7 +380,7 @@ class InterRDF_s(AnalysisBase): Results are available through the :attr:`cdf` attribute:: - plt.plot(rdf.bins, rdf.cdf[0][0, 0]) + plt.plot(rdf.results.bins, rdf.results.cdf[0][0, 0]) (Which plots the cdf between the first atom in ``s1`` and the first atom in ``s2``) @@ -395,12 +412,12 @@ def _prepare(self): count_ini = [np.zeros((ag1.n_atoms, ag2.n_atoms, l), dtype=np.float64) for ag1, ag2 in self.ags] - self.results.count = count_ini - self.results.edges = edges + self.count = count_ini + self.edges = edges self.results.bins = 0.5 * (edges[:-1] + edges[1:]) # Need to know average volume - self.results.volume = 0.0 + self.volume = 0.0 self._maxrange = self.rdf_settings['range'][1] @@ -412,15 +429,15 @@ def _single_frame(self): box=self.u.dimensions) for j, (idx1, idx2) in enumerate(pairs): - self.results.count[i][idx1, idx2, :] += np.histogram(dist[j], + self.count[i][idx1, idx2, :] += np.histogram(dist[j], **self.rdf_settings)[0] - self.results.volume += self._ts.volume + self.volume += self._ts.volume def _conclude(self): # Volume in each radial shell - vols = np.power(self.results.edges, 3) + vols = np.power(self.edges, 3) vol = 4/3.0 * np.pi * (vols[1:] - vols[:-1]) # Empty lists to restore indices, RDF @@ -432,13 +449,13 @@ def _conclude(self): indices.append([ag1.indices, ag2.indices]) # Average number density - box_vol = self.results.volume / self.n_frames + box_vol = self.volume / self.n_frames density = 1 / box_vol if self._density: - rdf.append(self.results.count[i] / (vol * self.n_frames)) + rdf.append(self.count[i] / (vol * self.n_frames)) else: - rdf.append(self.results.count[i] / + rdf.append(self.count[i] / (density * vol * self.n_frames)) self.results.rdf = rdf @@ -464,7 +481,7 @@ def get_cdf(self): # Empty list to restore CDF cdf = [] - for count in self.results.count: + for count in self.count: cdf.append(np.cumsum(count, axis=2) / self.n_frames) # Results stored in self.cdf @@ -472,3 +489,27 @@ def get_cdf(self): self.results.cdf = cdf return cdf + + @property + def bins(self): + wmsg = ("The `bins` attribute was deprecated in MDAnalysis 2.0.0 " + "and will be removed in MDAnalysis 3.0.0. Please use " + "`results.bins` instead") + warnings.warn(wmsg, DeprecationWarning) + return self.results.bins + + @property + def rdf(self): + wmsg = ("The `rdf` attribute was deprecated in MDAnalysis 2.0.0 " + "and will be removed in MDAnalysis 3.0.0. Please use " + "`results.rdf` instead") + warnings.warn(wmsg, DeprecationWarning) + return self.results.rdf + + @property + def cdf(self): + wmsg = ("The `cdf` attribute was deprecated in MDAnalysis 2.0.0 " + "and will be removed in MDAnalysis 3.0.0. Please use " + "`results.cdf` instead") + warnings.warn(wmsg, DeprecationWarning) + return self.results.cdf diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf.py b/testsuite/MDAnalysisTests/analysis/test_rdf.py index df701b57a90..7853e94b188 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf.py @@ -22,6 +22,7 @@ # import pytest +from numpy.testing import assert_equal import MDAnalysis as mda from MDAnalysis.analysis.rdf import InterRDF @@ -56,8 +57,8 @@ def test_range(u): rmin, rmax = 1.0, 13.0 rdf = InterRDF(s1, s2, range=(rmin, rmax)).run() - assert rdf.results.edges[0] == rmin - assert rdf.results.edges[-1] == rmax + assert rdf.edges[0] == rmin + assert rdf.edges[-1] == rmax def test_count_sum(sels): @@ -65,14 +66,14 @@ def test_count_sum(sels): # should see 8 comparisons in count s1, s2 = sels rdf = InterRDF(s1, s2).run() - assert rdf.results.count.sum() == 8 + assert rdf.count.sum() == 8 def test_count(sels): # should see two distances with 4 counts each s1, s2 = sels rdf = InterRDF(s1, s2).run() - assert len(rdf.results.count[rdf.results.count == 4]) == 2 + assert len(rdf.count[rdf.count == 4]) == 2 def test_double_run(sels): @@ -80,11 +81,23 @@ def test_double_run(sels): s1, s2 = sels rdf = InterRDF(s1, s2).run() rdf.run() - assert len(rdf.results.count[rdf.results.count == 4]) == 2 + assert len(rdf.count[rdf.count == 4]) == 2 def test_exclusion(sels): # should see two distances with 4 counts each s1, s2 = sels rdf = InterRDF(s1, s2, exclusion_block=(1, 2)).run() - assert rdf.results.count.sum() == 4 + assert rdf.count.sum() == 4 + +def test_rdf_attr_warning(sels): + s1, s2 = sels + rdf = InterRDF(s1, s2).run() + + wmsg = "The `rdf` attribute was deprecated in MDAnalysis 2.0.0" + with pytest.warns(DeprecationWarning, match=wmsg): + assert_equal(rdf.rdf, rdf.results.rdf) + + wmsg = "The `bins` attribute was deprecated in MDAnalysis 2.0.0" + with pytest.warns(DeprecationWarning, match=wmsg): + assert_equal(rdf.bins, rdf.results.bins) diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py index 09824a10565..6c145645086 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py @@ -22,7 +22,7 @@ # import pytest -from numpy.testing import assert_almost_equal +from numpy.testing import assert_almost_equal, assert_equal import MDAnalysis as mda from MDAnalysis.analysis.rdf import InterRDF_s, InterRDF @@ -61,8 +61,8 @@ def test_range(u, sels): rmin, rmax = 1.0, 13.0 rdf = InterRDF_s(u, sels, range=(rmin, rmax)).run() - assert rdf.results.edges[0] == rmin - assert rdf.results.edges[-1] == rmax + assert rdf.edges[0] == rmin + assert rdf.edges[-1] == rmax def test_count_size(rdf): @@ -73,34 +73,34 @@ def test_count_size(rdf): # 2 elements in rdf.count[1] # 2 elements in rdf.count[1][0] # 2 elements in rdf.count[1][1] - assert len(rdf.results.count) == 2 - assert len(rdf.results.count[0]) == 1 - assert len(rdf.results.count[0][0]) == 2 - assert len(rdf.results.count[1]) == 2 - assert len(rdf.results.count[1][0]) == 2 - assert len(rdf.results.count[1][1]) == 2 + assert len(rdf.count) == 2 + assert len(rdf.count[0]) == 1 + assert len(rdf.count[0][0]) == 2 + assert len(rdf.count[1]) == 2 + assert len(rdf.count[1][0]) == 2 + assert len(rdf.count[1][1]) == 2 def test_count(rdf): # should see one distance with 5 counts in count[0][0][1] # should see one distance with 3 counts in count[1][1][0] - sel0 = rdf.results.count[0][0][1] == 5 - sel1 = rdf.results.count[1][1][0] == 3 - assert len(rdf.results.count[0][0][1][sel0]) == 1 - assert len(rdf.results.count[1][1][0][sel1]) == 1 + sel0 = rdf.count[0][0][1] == 5 + sel1 = rdf.count[1][1][0] == 3 + assert len(rdf.count[0][0][1][sel0]) == 1 + assert len(rdf.count[1][1][0][sel1]) == 1 def test_double_run(rdf): # running rdf twice should give the same result - sel0 = rdf.results.count[0][0][1] == 5 - sel1 = rdf.results.count[1][1][0] == 3 - assert len(rdf.results.count[0][0][1][sel0]) == 1 - assert len(rdf.results.count[1][1][0][sel1]) == 1 + sel0 = rdf.count[0][0][1] == 5 + sel1 = rdf.count[1][1][0] == 3 + assert len(rdf.count[0][0][1][sel0]) == 1 + assert len(rdf.count[1][1][0][sel1]) == 1 def test_cdf(rdf): rdf.get_cdf() - ref = rdf.results.count[0][0][0].sum()/rdf.n_frames + ref = rdf.count[0][0][0].sum()/rdf.n_frames assert rdf.results.cdf[0][0][0][-1] == ref @@ -118,3 +118,12 @@ def test_density(u, sels, density, value): 'name OD1 and resid 51 and sphzone 5.0 (resid 289)') rdf_ref = InterRDF(s1, s2).run() assert_almost_equal(rdf_ref.results.rdf, rdf.results.rdf[0][0][0]) + +def test_rdf_attr_warning(rdf): + wmsg = "The `rdf` attribute was deprecated in MDAnalysis 2.0.0" + with pytest.warns(DeprecationWarning, match=wmsg): + assert_equal(rdf.rdf, rdf.results.rdf) + + wmsg = "The `bins` attribute was deprecated in MDAnalysis 2.0.0" + with pytest.warns(DeprecationWarning, match=wmsg): + assert_equal(rdf.bins, rdf.results.bins) From 50780143b3714a0956cc3c6943dc0087630ef529 Mon Sep 17 00:00:00 2001 From: VOD555 Date: Thu, 6 May 2021 23:25:07 -0700 Subject: [PATCH 04/16] add test for cdf deprecationwarning --- testsuite/MDAnalysisTests/analysis/test_rdf_s.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py index 6c145645086..6f47e0e6019 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py @@ -127,3 +127,8 @@ def test_rdf_attr_warning(rdf): wmsg = "The `bins` attribute was deprecated in MDAnalysis 2.0.0" with pytest.warns(DeprecationWarning, match=wmsg): assert_equal(rdf.bins, rdf.results.bins) + + cdf.get_cdf() + wmsg = "The `bins` attribute was deprecated in MDAnalysis 2.0.0" + with pytest.warns(DeprecationWarning, match=wmsg): + assert_equal(rdf.cdf, rdf.results.cdf) From 1512c051cb25c7290ca73a94b97305d2b1a4aebe Mon Sep 17 00:00:00 2001 From: VOD555 Date: Thu, 6 May 2021 23:30:42 -0700 Subject: [PATCH 05/16] update docs --- package/MDAnalysis/analysis/rdf.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/package/MDAnalysis/analysis/rdf.py b/package/MDAnalysis/analysis/rdf.py index c0d7d1d6c43..5ba55ee2c06 100644 --- a/package/MDAnalysis/analysis/rdf.py +++ b/package/MDAnalysis/analysis/rdf.py @@ -95,6 +95,10 @@ :class:`numpy.ndarray` of the centers of the `nbins` histogram bins. + .. deprecated:: 2.0.0 + This attribute will be removed in 3.0.0. + Use :attr:`results.bins` instead. + .. attribute:: edges :class:`numpy.ndarray` of the `nbins + 1` edges of the histogram @@ -105,6 +109,10 @@ :class:`numpy.ndarray` of the :ref:`radial distribution function` values for the :attr:`bins`. + .. deprecated:: 2.0.0 + This attribute will be removed in 3.0.0. + Use :attr:`results.rdf` instead. + .. attribute:: count :class:`numpy.ndarray` representing the radial histogram, i.e., @@ -133,6 +141,10 @@ :class:`numpy.ndarray` of the centers of the `nbins` histogram bins; all individual site-specific RDFs have the same bins. + .. deprecated:: 2.0.0 + This attribute will be removed in 3.0.0. + Use :attr:`results.bins` instead. + .. attribute:: edges :class:`numpy.ndarray` of the `nbins + 1` edges of the histogram @@ -148,6 +160,10 @@ ``(len(A), len(B))``, i.e., a stack of RDFs. For example, ``rdf[i][0, 2]`` is the RDF between atoms ``A[0]`` and ``B[2]``. + .. deprecated:: 2.0.0 + This attribute will be removed in 3.0.0. + Use :attr:`results.rdf` instead. + .. attribute:: count :class:`list` of the site-specific radial histograms, i.e., the @@ -164,7 +180,9 @@ This attribute only exists after :meth:`get_cdf` has been run. - + .. deprecated:: 2.0.0 + This attribute will be removed in 3.0.0. + Use :attr:`results.cdf` instead. .. Not Implemented yet: From 1b9dbfe96e0dfdfdfaa7cabdb6dd7669828c9ee1 Mon Sep 17 00:00:00 2001 From: VOD555 Date: Fri, 7 May 2021 00:00:12 -0700 Subject: [PATCH 06/16] fix pep8 errors --- package/MDAnalysis/analysis/rdf.py | 5 ++--- testsuite/MDAnalysisTests/analysis/test_rdf.py | 1 + testsuite/MDAnalysisTests/analysis/test_rdf_s.py | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/package/MDAnalysis/analysis/rdf.py b/package/MDAnalysis/analysis/rdf.py index 5ba55ee2c06..fb19c8eaffb 100644 --- a/package/MDAnalysis/analysis/rdf.py +++ b/package/MDAnalysis/analysis/rdf.py @@ -448,7 +448,7 @@ def _single_frame(self): for j, (idx1, idx2) in enumerate(pairs): self.count[i][idx1, idx2, :] += np.histogram(dist[j], - **self.rdf_settings)[0] + **self.rdf_settings)[0] self.volume += self._ts.volume @@ -473,8 +473,7 @@ def _conclude(self): if self._density: rdf.append(self.count[i] / (vol * self.n_frames)) else: - rdf.append(self.count[i] / - (density * vol * self.n_frames)) + rdf.append(self.count[i] / (density * vol * self.n_frames)) self.results.rdf = rdf self.results.indices = indices diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf.py b/testsuite/MDAnalysisTests/analysis/test_rdf.py index 7853e94b188..e0f53f30e5c 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf.py @@ -90,6 +90,7 @@ def test_exclusion(sels): rdf = InterRDF(s1, s2, exclusion_block=(1, 2)).run() assert rdf.count.sum() == 4 + def test_rdf_attr_warning(sels): s1, s2 = sels rdf = InterRDF(s1, s2).run() diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py index 6f47e0e6019..0585a06c351 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py @@ -119,6 +119,7 @@ def test_density(u, sels, density, value): rdf_ref = InterRDF(s1, s2).run() assert_almost_equal(rdf_ref.results.rdf, rdf.results.rdf[0][0][0]) + def test_rdf_attr_warning(rdf): wmsg = "The `rdf` attribute was deprecated in MDAnalysis 2.0.0" with pytest.warns(DeprecationWarning, match=wmsg): @@ -128,7 +129,7 @@ def test_rdf_attr_warning(rdf): with pytest.warns(DeprecationWarning, match=wmsg): assert_equal(rdf.bins, rdf.results.bins) - cdf.get_cdf() + rdf.get_cdf() wmsg = "The `bins` attribute was deprecated in MDAnalysis 2.0.0" with pytest.warns(DeprecationWarning, match=wmsg): assert_equal(rdf.cdf, rdf.results.cdf) From 697b36f49e921eae72f54c88223e9c59e29a2d88 Mon Sep 17 00:00:00 2001 From: VOD555 Date: Fri, 7 May 2021 00:33:20 -0700 Subject: [PATCH 07/16] update cdf test --- testsuite/MDAnalysisTests/analysis/test_rdf_s.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py index 0585a06c351..c9b5a922141 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py @@ -130,6 +130,6 @@ def test_rdf_attr_warning(rdf): assert_equal(rdf.bins, rdf.results.bins) rdf.get_cdf() - wmsg = "The `bins` attribute was deprecated in MDAnalysis 2.0.0" + wmsg = "The `cdf` attribute was deprecated in MDAnalysis 2.0.0" with pytest.warns(DeprecationWarning, match=wmsg): assert_equal(rdf.cdf, rdf.results.cdf) From 8f9359b9c8c1525384850d2fa07292613db47cad Mon Sep 17 00:00:00 2001 From: VOD555 Date: Fri, 7 May 2021 13:17:00 -0700 Subject: [PATCH 08/16] use results.count and results.edges --- package/MDAnalysis/analysis/rdf.py | 68 +++++++++++++------ .../MDAnalysisTests/analysis/test_rdf.py | 20 ++++-- .../MDAnalysisTests/analysis/test_rdf_s.py | 54 ++++++++------- 3 files changed, 93 insertions(+), 49 deletions(-) diff --git a/package/MDAnalysis/analysis/rdf.py b/package/MDAnalysis/analysis/rdf.py index fb19c8eaffb..c47e2d182ef 100644 --- a/package/MDAnalysis/analysis/rdf.py +++ b/package/MDAnalysis/analysis/rdf.py @@ -269,8 +269,8 @@ def _prepare(self): count, edges = np.histogram([-1], **self.rdf_settings) count = count.astype(np.float64) count *= 0.0 - self.count = count - self.edges = edges + self.results.count = count + self.results.edges = edges self.results.bins = 0.5 * (edges[:-1] + edges[1:]) # Need to know average volume @@ -292,7 +292,7 @@ def _single_frame(self): count = np.histogram(dist, **self.rdf_settings)[0] - self.count += count + self.results.count += count self.volume += self._ts.volume @@ -309,17 +309,33 @@ def _conclude(self): N -= xA * xB * nblocks # Volume in each radial shell - vols = np.power(self.edges, 3) - vol = 4/3.0 * np.pi * (vols[1:] - vols[:-1]) + vols = np.power(self.results.edges, 3) + vol = 4/3 * np.pi * (vols[1:] - vols[:-1]) # Average number density box_vol = self.volume / self.n_frames density = N / box_vol - rdf = self.count / (density * vol * self.n_frames) + rdf = self.results.count / (density * vol * self.n_frames) self.results.rdf = rdf + @property + def edges(self): + wmsg = ("The `edges` attribute was deprecated in MDAnalysis 2.0.0 " + "and will be removed in MDAnalysis 3.0.0. Please use " + "`results.bins` instead") + warnings.warn(wmsg, DeprecationWarning) + return self.results.edges + + @property + def count(self): + wmsg = ("The `count` attribute was deprecated in MDAnalysis 2.0.0 " + "and will be removed in MDAnalysis 3.0.0. Please use " + "`results.bins` instead") + warnings.warn(wmsg, DeprecationWarning) + return self.results.count + @property def bins(self): wmsg = ("The `bins` attribute was deprecated in MDAnalysis 2.0.0 " @@ -426,19 +442,15 @@ def _prepare(self): # Empty list to store the RDF count_list = [] count, edges = np.histogram([-1], **self.rdf_settings) - l = len(count) - count_ini = [np.zeros((ag1.n_atoms, ag2.n_atoms, l), dtype=np.float64) - for ag1, ag2 in self.ags] - - self.count = count_ini - self.edges = edges + self.results.count = [np.zeros((ag1.n_atoms, ag2.n_atoms, len(count)), + dtype=np.float64) for ag1, ag2 in self.ags] + self.results.edges = edges self.results.bins = 0.5 * (edges[:-1] + edges[1:]) # Need to know average volume self.volume = 0.0 self._maxrange = self.rdf_settings['range'][1] - def _single_frame(self): for i, (ag1, ag2) in enumerate(self.ags): pairs, dist = distances.capped_distance(ag1.positions, @@ -447,16 +459,15 @@ def _single_frame(self): box=self.u.dimensions) for j, (idx1, idx2) in enumerate(pairs): - self.count[i][idx1, idx2, :] += np.histogram(dist[j], + self.results.count[i][idx1, idx2, :] += np.histogram(dist[j], **self.rdf_settings)[0] self.volume += self._ts.volume - def _conclude(self): # Volume in each radial shell - vols = np.power(self.edges, 3) - vol = 4/3.0 * np.pi * (vols[1:] - vols[:-1]) + vols = np.power(self.results.edges, 3) + vol = 4/3 * np.pi * (vols[1:] - vols[:-1]) # Empty lists to restore indices, RDF indices = [] @@ -471,9 +482,10 @@ def _conclude(self): density = 1 / box_vol if self._density: - rdf.append(self.count[i] / (vol * self.n_frames)) + rdf.append(self.results.count[i] / (vol * self.n_frames)) else: - rdf.append(self.count[i] / (density * vol * self.n_frames)) + rdf.append( + self.results.count[i] / (density * vol * self.n_frames)) self.results.rdf = rdf self.results.indices = indices @@ -498,7 +510,7 @@ def get_cdf(self): # Empty list to restore CDF cdf = [] - for count in self.count: + for count in self.results.count: cdf.append(np.cumsum(count, axis=2) / self.n_frames) # Results stored in self.cdf @@ -507,6 +519,22 @@ def get_cdf(self): return cdf + @property + def edges(self): + wmsg = ("The `edges` attribute was deprecated in MDAnalysis 2.0.0 " + "and will be removed in MDAnalysis 3.0.0. Please use " + "`results.bins` instead") + warnings.warn(wmsg, DeprecationWarning) + return self.results.edges + + @property + def count(self): + wmsg = ("The `count` attribute was deprecated in MDAnalysis 2.0.0 " + "and will be removed in MDAnalysis 3.0.0. Please use " + "`results.bins` instead") + warnings.warn(wmsg, DeprecationWarning) + return self.results.count + @property def bins(self): wmsg = ("The `bins` attribute was deprecated in MDAnalysis 2.0.0 " diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf.py b/testsuite/MDAnalysisTests/analysis/test_rdf.py index e0f53f30e5c..cda04877930 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf.py @@ -57,8 +57,8 @@ def test_range(u): rmin, rmax = 1.0, 13.0 rdf = InterRDF(s1, s2, range=(rmin, rmax)).run() - assert rdf.edges[0] == rmin - assert rdf.edges[-1] == rmax + assert rdf.results.edges[0] == rmin + assert rdf.results.edges[-1] == rmax def test_count_sum(sels): @@ -66,14 +66,14 @@ def test_count_sum(sels): # should see 8 comparisons in count s1, s2 = sels rdf = InterRDF(s1, s2).run() - assert rdf.count.sum() == 8 + assert rdf.results.count.sum() == 8 def test_count(sels): # should see two distances with 4 counts each s1, s2 = sels rdf = InterRDF(s1, s2).run() - assert len(rdf.count[rdf.count == 4]) == 2 + assert len(rdf.results.count[rdf.results.count == 4]) == 2 def test_double_run(sels): @@ -81,14 +81,14 @@ def test_double_run(sels): s1, s2 = sels rdf = InterRDF(s1, s2).run() rdf.run() - assert len(rdf.count[rdf.count == 4]) == 2 + assert len(rdf.results.count[rdf.results.count == 4]) == 2 def test_exclusion(sels): # should see two distances with 4 counts each s1, s2 = sels rdf = InterRDF(s1, s2, exclusion_block=(1, 2)).run() - assert rdf.count.sum() == 4 + assert rdf.results.count.sum() == 4 def test_rdf_attr_warning(sels): @@ -102,3 +102,11 @@ def test_rdf_attr_warning(sels): wmsg = "The `bins` attribute was deprecated in MDAnalysis 2.0.0" with pytest.warns(DeprecationWarning, match=wmsg): assert_equal(rdf.bins, rdf.results.bins) + + wmsg = "The `edges` attribute was deprecated in MDAnalysis 2.0.0" + with pytest.warns(DeprecationWarning, match=wmsg): + assert_equal(rdf.edges, rdf.results.edges) + + wmsg = "The `count` attribute was deprecated in MDAnalysis 2.0.0" + with pytest.warns(DeprecationWarning, match=wmsg): + assert_equal(rdf.count, rdf.results.count) diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py index c9b5a922141..e7e8b45b199 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py @@ -61,46 +61,46 @@ def test_range(u, sels): rmin, rmax = 1.0, 13.0 rdf = InterRDF_s(u, sels, range=(rmin, rmax)).run() - assert rdf.edges[0] == rmin - assert rdf.edges[-1] == rmax + assert rdf.results.edges[0] == rmin + assert rdf.results.edges[-1] == rmax def test_count_size(rdf): # ZND vs OD1 & OD2 - # should see 2 elements in rdf.count - # 1 element in rdf.count[0] - # 2 elements in rdf.count[0][0] - # 2 elements in rdf.count[1] - # 2 elements in rdf.count[1][0] - # 2 elements in rdf.count[1][1] - assert len(rdf.count) == 2 - assert len(rdf.count[0]) == 1 - assert len(rdf.count[0][0]) == 2 - assert len(rdf.count[1]) == 2 - assert len(rdf.count[1][0]) == 2 - assert len(rdf.count[1][1]) == 2 + # should see 2 elements in rdf.results.count + # 1 element in rdf.results.count[0] + # 2 elements in rdf.results.count[0][0] + # 2 elements in rdf.results.count[1] + # 2 elements in rdf.results.count[1][0] + # 2 elements in rdf.results.count[1][1] + assert len(rdf.results.count) == 2 + assert len(rdf.results.count[0]) == 1 + assert len(rdf.results.count[0][0]) == 2 + assert len(rdf.results.count[1]) == 2 + assert len(rdf.results.count[1][0]) == 2 + assert len(rdf.results.count[1][1]) == 2 def test_count(rdf): # should see one distance with 5 counts in count[0][0][1] # should see one distance with 3 counts in count[1][1][0] - sel0 = rdf.count[0][0][1] == 5 - sel1 = rdf.count[1][1][0] == 3 - assert len(rdf.count[0][0][1][sel0]) == 1 - assert len(rdf.count[1][1][0][sel1]) == 1 + sel0 = rdf.results.count[0][0][1] == 5 + sel1 = rdf.results.count[1][1][0] == 3 + assert len(rdf.results.count[0][0][1][sel0]) == 1 + assert len(rdf.results.count[1][1][0][sel1]) == 1 def test_double_run(rdf): # running rdf twice should give the same result - sel0 = rdf.count[0][0][1] == 5 - sel1 = rdf.count[1][1][0] == 3 - assert len(rdf.count[0][0][1][sel0]) == 1 - assert len(rdf.count[1][1][0][sel1]) == 1 + sel0 = rdf.results.count[0][0][1] == 5 + sel1 = rdf.results.count[1][1][0] == 3 + assert len(rdf.results.count[0][0][1][sel0]) == 1 + assert len(rdf.results.count[1][1][0][sel1]) == 1 def test_cdf(rdf): rdf.get_cdf() - ref = rdf.count[0][0][0].sum()/rdf.n_frames + ref = rdf.results.count[0][0][0].sum()/rdf.n_frames assert rdf.results.cdf[0][0][0][-1] == ref @@ -129,6 +129,14 @@ def test_rdf_attr_warning(rdf): with pytest.warns(DeprecationWarning, match=wmsg): assert_equal(rdf.bins, rdf.results.bins) + wmsg = "The `edges` attribute was deprecated in MDAnalysis 2.0.0" + with pytest.warns(DeprecationWarning, match=wmsg): + assert_equal(rdf.edges, rdf.results.edges) + + wmsg = "The `count` attribute was deprecated in MDAnalysis 2.0.0" + with pytest.warns(DeprecationWarning, match=wmsg): + assert_equal(rdf.count, rdf.results.count) + rdf.get_cdf() wmsg = "The `cdf` attribute was deprecated in MDAnalysis 2.0.0" with pytest.warns(DeprecationWarning, match=wmsg): From 2c5092e7e2ad50dd16e670052d867cf5dea9d254 Mon Sep 17 00:00:00 2001 From: VOD555 Date: Fri, 7 May 2021 15:22:27 -0700 Subject: [PATCH 09/16] update docs with new attributes --- package/MDAnalysis/analysis/rdf.py | 134 +++++++++++++++++++++-------- 1 file changed, 98 insertions(+), 36 deletions(-) diff --git a/package/MDAnalysis/analysis/rdf.py b/package/MDAnalysis/analysis/rdf.py index c47e2d182ef..7bc40e295d3 100644 --- a/package/MDAnalysis/analysis/rdf.py +++ b/package/MDAnalysis/analysis/rdf.py @@ -90,34 +90,59 @@ :members: :inherited-members: + .. attribute:: results.bins + + :class:`numpy.ndarray` of the centers of the `nbins` histogram + bins. + + .. versionadded:: 2.0.0 + .. attribute:: bins - :class:`numpy.ndarray` of the centers of the `nbins` histogram - bins. + Alias to the :attr:`results.bins` attribute. .. deprecated:: 2.0.0 This attribute will be removed in 3.0.0. Use :attr:`results.bins` instead. - .. attribute:: edges + .. attribute:: results.edges :class:`numpy.ndarray` of the `nbins + 1` edges of the histogram bins. - .. attribute:: rdf + .. attribute:: edges + + Alias to the :attr:`results.edges` attribute. + + .. deprecated:: 2.0.0 + This attribute will be removed in 3.0.0. + Use :attr:`results.edges` instead. + + .. attribute:: results.rdf :class:`numpy.ndarray` of the :ref:`radial distribution - function` values for the :attr:`bins`. + function` values for the :attr:`results.bins`. + + .. attribute:: rdf - .. deprecated:: 2.0.0 - This attribute will be removed in 3.0.0. - Use :attr:`results.rdf` instead. + Alias to the :attr:`results.rdf` attribute. - .. attribute:: count + .. deprecated:: 2.0.0 + This attribute will be removed in 3.0.0. + Use :attr:`results.rdf` instead. + + .. attribute:: results.count :class:`numpy.ndarray` representing the radial histogram, i.e., - the raw counts, for all :attr:`bins`. + the raw counts, for all :attr:`results.bins`. + + .. attribute:: count + Alias to the :attr:`results.count` attribute. + + .. deprecated:: 2.0.0 + This attribute will be removed in 3.0.0. + Use :attr:`results.count` instead. Site-specific radial distribution function ------------------------------------------ @@ -136,21 +161,33 @@ :members: :inherited-members: - .. attribute:: bins + .. attribute:: results.bins :class:`numpy.ndarray` of the centers of the `nbins` histogram bins; all individual site-specific RDFs have the same bins. - .. deprecated:: 2.0.0 - This attribute will be removed in 3.0.0. - Use :attr:`results.bins` instead. + .. attribute:: bins - .. attribute:: edges + Alias to the :attr:`results.bins` attribute. + + .. deprecated:: 2.0.0 + This attribute will be removed in 3.0.0. + Use :attr:`results.bins` instead. + + .. attribute:: results.edges :class:`numpy.ndarray` of the `nbins + 1` edges of the histogram bins; all individual site-specific RDFs have the same bins. - .. attribute:: rdf + .. attribute:: edges + + Alias to the :attr:`results.edges` attribute. + + .. deprecated:: 2.0.0 + This attribute will be removed in 3.0.0. + Use :attr:`results.edges` instead. + + .. attribute:: results.rdf :class:`list` of the site-specific :ref:`radial distribution functions` or :ref:`density @@ -158,32 +195,48 @@ ``len(ags)`` entries. Each entry for the ``i``-th pair ``[A, B] = ags[i]`` in `ags` is a :class:`numpy.ndarray` with shape ``(len(A), len(B))``, i.e., a stack of RDFs. For example, - ``rdf[i][0, 2]`` is the RDF between atoms ``A[0]`` and ``B[2]``. + ``results.rdf[i][0, 2]`` is the RDF between atoms ``A[0]`` + and ``B[2]``. - .. deprecated:: 2.0.0 - This attribute will be removed in 3.0.0. - Use :attr:`results.rdf` instead. + .. attribute:: rdf - .. attribute:: count + Alias to the :attr:`results.rdf` attribute. + + .. deprecated:: 2.0.0 + This attribute will be removed in 3.0.0. + Use :attr:`results.rdf` instead. + + .. attribute:: results.count :class:`list` of the site-specific radial histograms, i.e., the - raw counts, for all :attr:`bins`. The data have the same - structure as :attr:`rdf` except that the arrays contain the raw - counts. + raw counts, for all :attr:`results.bins`. The data have the same + structure as :attr:`results.rdf` except that the arrays contain + the raw counts. - .. attribute:: cdf + .. attribute:: count + + Alias to the :attr:`results.count` attribute. + + .. deprecated:: 2.0.0 + This attribute will be removed in 3.0.0. + Use :attr:`results.count` instead. + + .. attribute:: results.cdf :class:`list` of the site-specific :ref:`cumulative - counts`, for all :attr:`bins`. The data have the same - structure as :attr:`rdf` except that the arrays contain the cumulative - counts. + counts`, for all :attr:`results.bins`. The data + have the same structure as :attr:`results.rdf` except that the arrays + contain the cumulative counts. This attribute only exists after :meth:`get_cdf` has been run. - .. deprecated:: 2.0.0 - This attribute will be removed in 3.0.0. - Use :attr:`results.cdf` instead. + .. attribute:: cdf + Alias to the :attr:`results.cdf` attribute. + + .. deprecated:: 2.0.0 + This attribute will be removed in 3.0.0. + Use :attr:`results.cdf` instead. .. Not Implemented yet: .. - Structure factor? @@ -235,10 +288,10 @@ class InterRDF(AnalysisBase): rdf = InterRDF(ag1, ag2) rdf.run() - Results are available through the :attr:`bins` and :attr:`rdf` - attributes:: + Results are available through the :attr:`results.bins` and + :attr:`results.rdf` attributes:: - plt.plot(rdf.bins, rdf.rdf) + plt.plot(rdf.results.bins, rdf.results.rdf) The `exclusion_block` keyword allows the masking of pairs from within the same molecule. For example, if there are 7 of each @@ -251,6 +304,10 @@ class InterRDF(AnalysisBase): Support for the ``start``, ``stop``, and ``step`` keywords has been removed. These should instead be passed to :meth:`InterRDF.run`. + .. versionchanged:: 2.0.0 + Use :class:`~MDAnalysis.analysis.AnalysisBase` as parent class and + store results as attributes ``bins``, ``edges``, ``rdf`` and ``count`` + of the ``results`` attribute. """ def __init__(self, g1, g2, nbins=75, range=(0.0, 15.0), exclusion_block=None, @@ -399,7 +456,8 @@ class InterRDF_s(AnalysisBase): rdf = InterRDF_s(u, ags) rdf.run() - Results are available through the :attr:`bins` and :attr:`rdf` attributes:: + Results are available through the :attr:`results.bins` + and :attr:`results.rdf` attributes:: plt.plot(rdf.results.bins, rdf.results.rdf[0][0, 0]) @@ -412,7 +470,7 @@ class InterRDF_s(AnalysisBase): cdf = rdf.get_cdf() - Results are available through the :attr:`cdf` attribute:: + Results are available through the :attr:`results.cdf` attribute:: plt.plot(rdf.results.bins, rdf.results.cdf[0][0, 0]) @@ -426,6 +484,10 @@ class InterRDF_s(AnalysisBase): Support for the ``start``, ``stop``, and ``step`` keywords has been removed. These should instead be passed to :meth:`InterRDF_s.run`. + .. versionchanged:: 2.0.0 + Use :class:`~MDAnalysis.analysis.AnalysisBase` as parent class and + store results as attributes ``bins``, ``edges``, ``rdf``, ``count`` + and ``cdf`` of the ``results`` attribute. """ def __init__(self, u, ags, nbins=75, range=(0.0, 15.0), density=False, **kwargs): From 8a5a7d4f5c9b96067f5422ceaa0970b5b1e28baa Mon Sep 17 00:00:00 2001 From: VOD555 Date: Fri, 7 May 2021 15:54:11 -0700 Subject: [PATCH 10/16] squash code for warning tests --- package/MDAnalysis/analysis/rdf.py | 8 +++--- .../MDAnalysisTests/analysis/test_rdf.py | 20 +++----------- .../MDAnalysisTests/analysis/test_rdf_s.py | 26 +++++-------------- 3 files changed, 14 insertions(+), 40 deletions(-) diff --git a/package/MDAnalysis/analysis/rdf.py b/package/MDAnalysis/analysis/rdf.py index 7bc40e295d3..49a11c41bf7 100644 --- a/package/MDAnalysis/analysis/rdf.py +++ b/package/MDAnalysis/analysis/rdf.py @@ -559,13 +559,13 @@ def get_cdf(self): radius, i.e., :math:`N_{ab}(r)`. The result is returned and also stored in the attribute - :attr:`cdf`. + :attr:`results.cdf`. Returns ------- cdf : list - list of arrays with the same structure as :attr:`rdf` + list of arrays with the same structure as :attr:`results.rdf` """ # Calculate cumulative distribution function @@ -575,8 +575,8 @@ def get_cdf(self): for count in self.results.count: cdf.append(np.cumsum(count, axis=2) / self.n_frames) - # Results stored in self.cdf - # self.cdf is a list of cdf between pairs of AtomGroups in ags + # Results stored in self.results.cdf + # self.results.cdf is a list of cdf between pairs of AtomGroups in ags self.results.cdf = cdf return cdf diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf.py b/testsuite/MDAnalysisTests/analysis/test_rdf.py index cda04877930..2579d5f619b 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf.py @@ -91,22 +91,10 @@ def test_exclusion(sels): assert rdf.results.count.sum() == 4 -def test_rdf_attr_warning(sels): +@pytest.mark.parametrize("attr", ("rdf", "bins", "edges", "count")) +def test_rdf_attr_warning(sels, attr): s1, s2 = sels rdf = InterRDF(s1, s2).run() - - wmsg = "The `rdf` attribute was deprecated in MDAnalysis 2.0.0" - with pytest.warns(DeprecationWarning, match=wmsg): - assert_equal(rdf.rdf, rdf.results.rdf) - - wmsg = "The `bins` attribute was deprecated in MDAnalysis 2.0.0" - with pytest.warns(DeprecationWarning, match=wmsg): - assert_equal(rdf.bins, rdf.results.bins) - - wmsg = "The `edges` attribute was deprecated in MDAnalysis 2.0.0" - with pytest.warns(DeprecationWarning, match=wmsg): - assert_equal(rdf.edges, rdf.results.edges) - - wmsg = "The `count` attribute was deprecated in MDAnalysis 2.0.0" + wmsg = f"The `{attr}` attribute was deprecated in MDAnalysis 2.0.0" with pytest.warns(DeprecationWarning, match=wmsg): - assert_equal(rdf.count, rdf.results.count) + getattr(rdf, attr) is rdf.results[attr] diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py index e7e8b45b199..4855b6c9352 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py @@ -120,24 +120,10 @@ def test_density(u, sels, density, value): assert_almost_equal(rdf_ref.results.rdf, rdf.results.rdf[0][0][0]) -def test_rdf_attr_warning(rdf): - wmsg = "The `rdf` attribute was deprecated in MDAnalysis 2.0.0" +@pytest.mark.parametrize("attr", ("rdf", "bins", "edges", "count", "cdf")) +def test_rdf_attr_warning(rdf, attr): + if attr == "cdf": + rdf.get_cdf() + wmsg = f"The `{attr}` attribute was deprecated in MDAnalysis 2.0.0" with pytest.warns(DeprecationWarning, match=wmsg): - assert_equal(rdf.rdf, rdf.results.rdf) - - wmsg = "The `bins` attribute was deprecated in MDAnalysis 2.0.0" - with pytest.warns(DeprecationWarning, match=wmsg): - assert_equal(rdf.bins, rdf.results.bins) - - wmsg = "The `edges` attribute was deprecated in MDAnalysis 2.0.0" - with pytest.warns(DeprecationWarning, match=wmsg): - assert_equal(rdf.edges, rdf.results.edges) - - wmsg = "The `count` attribute was deprecated in MDAnalysis 2.0.0" - with pytest.warns(DeprecationWarning, match=wmsg): - assert_equal(rdf.count, rdf.results.count) - - rdf.get_cdf() - wmsg = "The `cdf` attribute was deprecated in MDAnalysis 2.0.0" - with pytest.warns(DeprecationWarning, match=wmsg): - assert_equal(rdf.cdf, rdf.results.cdf) + getattr(rdf, attr) is rdf.results[attr] From 80b87c460dc578721bbf23236b0ab0239af37467 Mon Sep 17 00:00:00 2001 From: VOD555 Date: Fri, 7 May 2021 17:08:17 -0700 Subject: [PATCH 11/16] add version info for new attributes --- package/MDAnalysis/analysis/rdf.py | 62 +++++++++++++++++++----------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/package/MDAnalysis/analysis/rdf.py b/package/MDAnalysis/analysis/rdf.py index 49a11c41bf7..364187bab3e 100644 --- a/package/MDAnalysis/analysis/rdf.py +++ b/package/MDAnalysis/analysis/rdf.py @@ -110,6 +110,8 @@ :class:`numpy.ndarray` of the `nbins + 1` edges of the histogram bins. + .. versionadded:: 2.0.0 + .. attribute:: edges Alias to the :attr:`results.edges` attribute. @@ -123,6 +125,8 @@ :class:`numpy.ndarray` of the :ref:`radial distribution function` values for the :attr:`results.bins`. + .. versionadded:: 2.0.0 + .. attribute:: rdf Alias to the :attr:`results.rdf` attribute. @@ -136,6 +140,8 @@ :class:`numpy.ndarray` representing the radial histogram, i.e., the raw counts, for all :attr:`results.bins`. + .. versionadded:: 2.0.0 + .. attribute:: count Alias to the :attr:`results.count` attribute. @@ -166,6 +172,8 @@ :class:`numpy.ndarray` of the centers of the `nbins` histogram bins; all individual site-specific RDFs have the same bins. + .. versionadded:: 2.0.0 + .. attribute:: bins Alias to the :attr:`results.bins` attribute. @@ -179,6 +187,8 @@ :class:`numpy.ndarray` of the `nbins + 1` edges of the histogram bins; all individual site-specific RDFs have the same bins. + .. versionadded:: 2.0.0 + .. attribute:: edges Alias to the :attr:`results.edges` attribute. @@ -189,14 +199,16 @@ .. attribute:: results.rdf - :class:`list` of the site-specific :ref:`radial distribution - functions` or :ref:`density - functions` for the :attr:`bins`. The list contains - ``len(ags)`` entries. Each entry for the ``i``-th pair ``[A, B] - = ags[i]`` in `ags` is a :class:`numpy.ndarray` with shape - ``(len(A), len(B))``, i.e., a stack of RDFs. For example, - ``results.rdf[i][0, 2]`` is the RDF between atoms ``A[0]`` - and ``B[2]``. + :class:`list` of the site-specific :ref:`radial distribution + functions` or :ref:`density + functions` for the :attr:`bins`. The list contains + ``len(ags)`` entries. Each entry for the ``i``-th pair ``[A, B] + = ags[i]`` in `ags` is a :class:`numpy.ndarray` with shape + ``(len(A), len(B))``, i.e., a stack of RDFs. For example, + ``results.rdf[i][0, 2]`` is the RDF between atoms ``A[0]`` + and ``B[2]``. + + .. versionadded:: 2.0.0 .. attribute:: rdf @@ -208,10 +220,12 @@ .. attribute:: results.count - :class:`list` of the site-specific radial histograms, i.e., the - raw counts, for all :attr:`results.bins`. The data have the same - structure as :attr:`results.rdf` except that the arrays contain - the raw counts. + :class:`list` of the site-specific radial histograms, i.e., the + raw counts, for all :attr:`results.bins`. The data have the same + structure as :attr:`results.rdf` except that the arrays contain + the raw counts. + + .. versionadded:: 2.0.0 .. attribute:: count @@ -223,12 +237,14 @@ .. attribute:: results.cdf - :class:`list` of the site-specific :ref:`cumulative - counts`, for all :attr:`results.bins`. The data - have the same structure as :attr:`results.rdf` except that the arrays - contain the cumulative counts. + :class:`list` of the site-specific :ref:`cumulative + counts`, for all :attr:`results.bins`. The data + have the same structure as :attr:`results.rdf` except that the arrays + contain the cumulative counts. - This attribute only exists after :meth:`get_cdf` has been run. + This attribute only exists after :meth:`get_cdf` has been run. + + .. versionadded:: 2.0.0 .. attribute:: cdf @@ -305,9 +321,9 @@ class InterRDF(AnalysisBase): removed. These should instead be passed to :meth:`InterRDF.run`. .. versionchanged:: 2.0.0 - Use :class:`~MDAnalysis.analysis.AnalysisBase` as parent class and - store results as attributes ``bins``, ``edges``, ``rdf`` and ``count`` - of the ``results`` attribute. + Store results as attributes ``bins``, ``edges``, ``rdf`` and ``count`` + of the ``results`` attribute of + :class:`~MDAnalysis.analysis.AnalysisBase`. """ def __init__(self, g1, g2, nbins=75, range=(0.0, 15.0), exclusion_block=None, @@ -485,9 +501,9 @@ class InterRDF_s(AnalysisBase): removed. These should instead be passed to :meth:`InterRDF_s.run`. .. versionchanged:: 2.0.0 - Use :class:`~MDAnalysis.analysis.AnalysisBase` as parent class and - store results as attributes ``bins``, ``edges``, ``rdf``, ``count`` - and ``cdf`` of the ``results`` attribute. + Store results as attributes ``bins``, ``edges``, ``rdf``, ``count`` + and ``cdf`` of the ``results`` attribute + of :class:`~MDAnalysis.analysis.AnalysisBase`. """ def __init__(self, u, ags, nbins=75, range=(0.0, 15.0), density=False, **kwargs): From 36de73a22ad3472d54da7b19cb41407e4d5fbecf Mon Sep 17 00:00:00 2001 From: VOD555 Date: Fri, 7 May 2021 17:14:22 -0700 Subject: [PATCH 12/16] update CHANGELOG --- package/CHANGELOG | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/package/CHANGELOG b/package/CHANGELOG index 80b613196df..d679adf5c57 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -175,6 +175,9 @@ Enhancements checking if it can be used in parallel analysis. (Issue #2996, PR #2950) Changes + * `analysis.rdf.InterRDF` and `analysis.rdf.InterRDF_s` now store + their result attributes using the `analysis.base.Results` class + (Issue #3276, #3261) * `helix_analysis.HELANAL` now uses the `analysis.base.Results` class to store results attributes (Issue #3261, #3267) * `analysis.align.AlignTraj` and `analysis.align.AverageStructure` now store @@ -199,7 +202,7 @@ Changes analysis.hydrogenbonds.hbond_analysis (Issues #2739, #2746) * `GNMAnalysis`, `LinearDensity`, `PersistenceLength` and `AnalysisFromFunction` use the `results` attribute. - * Fixed inaccurate docstring inside the RMSD class (Issue #2796, PR #3134) + * Fixed inaccurate docstring inside the RMSD class (Issue #2796, PR #3134) * TPRParser now loads TPR files with `tpr_resid_from_one=True` by default, which starts TPR resid indexing from 1 (instead of 0 as in 1.x) (Issue #2364, PR #3152) * Introduces encore specific C compiler arguments to allow for lowering of @@ -243,6 +246,11 @@ Changes * Added OpenMM coordinate and topology converters (Issue #2863, PR #2917) Deprecations + * The `bins`, `edges`, `count`, `rdf` attributes for `analysis.rdf.InterRDF` + and `analysis.rdf.InterRDF_s`, and `cdf` attributes for + `analysis.rdf.InterRDF_s` are now deprecated in favour of `results.bins`, + `results.edges`, `results.count`, `results.rdf` and `results.cdf` + (Issue #3276, #3261) * The `analysis.align.AlignTraj.rmsd` attribute is now deprecated in favour of `analysis.align.AlignTraj.results.rmsd` (Issue #3278, #3261) * The `universe`, `positions`, and `rmsd` attributes of @@ -259,7 +267,7 @@ Deprecations * The `angles` attribute for the `dihedrals` classes (Dihedral, Ramachandran, Janin) is now deprecated in favour of `results.angles`. It will be removed in 3.0.0 (Issue #3261) - * The `analysis.Contacts.timeseries` attribute is now deprecated in favour of + * The `analysis.Contacts.timeseries` attribute is now deprecated in favour of `analysis.Contacts.results.timeseries`. It will be removed in 3.0.0 (Issue #3261) * The `density` attribute of `analysis.density.DensityAnalysis` is now From 931b52017577ca7329eb4202ab7f1aeae216c4b8 Mon Sep 17 00:00:00 2001 From: Oliver Beckstein Date: Sat, 8 May 2021 05:20:48 -0700 Subject: [PATCH 13/16] removed duplicate entry from CHANGELOG --- package/CHANGELOG | 2 -- 1 file changed, 2 deletions(-) diff --git a/package/CHANGELOG b/package/CHANGELOG index 77353a0e03f..f2f639b4497 100644 --- a/package/CHANGELOG +++ b/package/CHANGELOG @@ -183,8 +183,6 @@ Changes (Issues #3289, #3291) * `analysis.hole2.HoleAnalysis` now stores ``sphpdbs``, ``outfiles`` and ``profiles`` in the `analysis.base.Results` class (Issues #3261, #3269) - * `helix_analysis.HELANAL` now uses the `analysis.base.Results` class to - store results attributes (Issue #3261, #3267) * `analysis.diffusionmap.DistanceMatrix` class now stores `dist_matrix` using the `analysis.base.Results` class (Issues #3288, #3290) * `helix_analysis.HELANAL` now uses the `analysis.base.Results` class to From ac760ce432ca5fe157777e81f676c484a5871a44 Mon Sep 17 00:00:00 2001 From: VOD555 Date: Sat, 8 May 2021 07:41:58 -0700 Subject: [PATCH 14/16] modify indentation --- package/MDAnalysis/analysis/rdf.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package/MDAnalysis/analysis/rdf.py b/package/MDAnalysis/analysis/rdf.py index 364187bab3e..68c8708280d 100644 --- a/package/MDAnalysis/analysis/rdf.py +++ b/package/MDAnalysis/analysis/rdf.py @@ -358,7 +358,7 @@ def _single_frame(self): box=self.u.dimensions) # Maybe exclude same molecule distances if self._exclusion_block is not None: - idxA = pairs[:, 0]//self._exclusion_block[0], + idxA = pairs[:, 0]//self._exclusion_block[0] idxB = pairs[:, 1]//self._exclusion_block[1] mask = np.where(idxA != idxB)[0] dist = dist[mask] @@ -521,7 +521,7 @@ def _prepare(self): count_list = [] count, edges = np.histogram([-1], **self.rdf_settings) self.results.count = [np.zeros((ag1.n_atoms, ag2.n_atoms, len(count)), - dtype=np.float64) for ag1, ag2 in self.ags] + dtype=np.float64) for ag1, ag2 in self.ags] self.results.edges = edges self.results.bins = 0.5 * (edges[:-1] + edges[1:]) @@ -538,7 +538,7 @@ def _single_frame(self): for j, (idx1, idx2) in enumerate(pairs): self.results.count[i][idx1, idx2, :] += np.histogram(dist[j], - **self.rdf_settings)[0] + **self.rdf_settings)[0] self.volume += self._ts.volume From 713a1cee35b40ee69ae314b0a0216751d252579c Mon Sep 17 00:00:00 2001 From: VOD555 Date: Sat, 8 May 2021 07:42:29 -0700 Subject: [PATCH 15/16] remove import assert_equal --- testsuite/MDAnalysisTests/analysis/test_rdf.py | 1 - testsuite/MDAnalysisTests/analysis/test_rdf_s.py | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf.py b/testsuite/MDAnalysisTests/analysis/test_rdf.py index 2579d5f619b..16f0e326ec3 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf.py @@ -22,7 +22,6 @@ # import pytest -from numpy.testing import assert_equal import MDAnalysis as mda from MDAnalysis.analysis.rdf import InterRDF diff --git a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py index 4855b6c9352..f3aee0a3fcb 100644 --- a/testsuite/MDAnalysisTests/analysis/test_rdf_s.py +++ b/testsuite/MDAnalysisTests/analysis/test_rdf_s.py @@ -22,7 +22,7 @@ # import pytest -from numpy.testing import assert_almost_equal, assert_equal +from numpy.testing import assert_almost_equal import MDAnalysis as mda from MDAnalysis.analysis.rdf import InterRDF_s, InterRDF From 022728ee7d36f59d46d8da0e31aa863f00de1513 Mon Sep 17 00:00:00 2001 From: VOD555 Date: Sat, 8 May 2021 23:41:58 -0700 Subject: [PATCH 16/16] use np.diff to calculate shell volume --- package/MDAnalysis/analysis/rdf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/MDAnalysis/analysis/rdf.py b/package/MDAnalysis/analysis/rdf.py index 68c8708280d..6a63191f348 100644 --- a/package/MDAnalysis/analysis/rdf.py +++ b/package/MDAnalysis/analysis/rdf.py @@ -383,7 +383,7 @@ def _conclude(self): # Volume in each radial shell vols = np.power(self.results.edges, 3) - vol = 4/3 * np.pi * (vols[1:] - vols[:-1]) + vol = 4/3 * np.pi * np.diff(vols) # Average number density box_vol = self.volume / self.n_frames @@ -545,7 +545,7 @@ def _single_frame(self): def _conclude(self): # Volume in each radial shell vols = np.power(self.results.edges, 3) - vol = 4/3 * np.pi * (vols[1:] - vols[:-1]) + vol = 4/3 * np.pi * np.diff(vols) # Empty lists to restore indices, RDF indices = []