qdiffusivity 0.2.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/PKG-INFO +1 -1
  2. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/density.py +8 -11
  3. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/diffusivity.py +10 -15
  4. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/tests/test_binned.py +9 -13
  5. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/tests/test_density.py +8 -16
  6. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/tests/test_diffusivity.py +9 -14
  7. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity.egg-info/PKG-INFO +1 -1
  8. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/AUTHORS.md +0 -0
  9. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/CHANGELOG.md +0 -0
  10. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/CODE_OF_CONDUCT.md +0 -0
  11. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/LICENSE +0 -0
  12. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/MANIFEST.in +0 -0
  13. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/README.md +0 -0
  14. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/pyproject.toml +0 -0
  15. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/__init__.py +0 -0
  16. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/binned.py +0 -0
  17. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/data/README.md +0 -0
  18. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/data/__init__.py +0 -0
  19. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/data/files.py +0 -0
  20. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/data/mda.txt +0 -0
  21. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/example_api.py +0 -0
  22. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/tests/__init__.py +0 -0
  23. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/tests/conftest.py +0 -0
  24. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/tests/test_qdiffusivity.py +0 -0
  25. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity/tests/utils.py +0 -0
  26. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity.egg-info/SOURCES.txt +0 -0
  27. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity.egg-info/dependency_links.txt +0 -0
  28. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity.egg-info/requires.txt +0 -0
  29. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/qdiffusivity.egg-info/top_level.txt +0 -0
  30. {qdiffusivity-0.2.0 → qdiffusivity-0.2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qdiffusivity
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Quantile-based estimation of local diffusivities in molecular dynamics simulations of nanoconfined liquids
5
5
  Author-email: Shern Ren Tee <shernren@gmail.com>
6
6
  Maintainer-email: Shern Ren Tee <shernren@gmail.com>
@@ -74,6 +74,9 @@ import numpy as np
74
74
  from MDAnalysis.analysis.base import AnalysisBase
75
75
  from MDAnalysis.units import constants
76
76
 
77
+ # Trapezoidal integration: np.trapezoid (NumPy >= 2.0) or np.trapz (older).
78
+ _trapezoid = getattr(np, "trapezoid", None) or np.trapz
79
+
77
80
  # Epanechnikov kernel constants used by the Sheather-Jones plug-in.
78
81
  # ||K||^2 = int K(u)^2 du = 3/5
79
82
  # mu_2(K) = int u^2 K(u) du = 1/5
@@ -169,7 +172,7 @@ def sheather_jones_bw(z_data, z_lo, z_hi):
169
172
  kernel = np.where(np.abs(s) < 1.0, 0.75 * (1.0 - s * s) / h0, 0.0)
170
173
  f_pilot = kernel @ f_pilot_raw
171
174
 
172
- integral = np.trapezoid(f_pilot, z_fine)
175
+ integral = _trapezoid(f_pilot, z_fine)
173
176
  if integral > 0:
174
177
  f_pilot = f_pilot / integral
175
178
 
@@ -178,7 +181,7 @@ def sheather_jones_bw(z_data, z_lo, z_hi):
178
181
  f_pp[0] = f_pp[1]
179
182
  f_pp[-1] = f_pp[-2]
180
183
 
181
- int_fpp_sq = np.trapezoid(f_pp**2, z_fine)
184
+ int_fpp_sq = _trapezoid(f_pp**2, z_fine)
182
185
 
183
186
  if int_fpp_sq <= 0 or not np.isfinite(int_fpp_sq):
184
187
  return h_silver
@@ -406,8 +409,7 @@ class _TransverseDensityQKDEBase(AnalysisBase):
406
409
  "silverman",
407
410
  ):
408
411
  raise ValueError(
409
- f"bandwidth must be 'auto', 'silverman' or "
410
- f"a float, got {bandwidth!r}"
412
+ f"bandwidth must be 'auto', 'silverman' or a float, got {bandwidth!r}"
411
413
  )
412
414
  self._bandwidth = bandwidth
413
415
  self._chunk_size = int(chunk_size)
@@ -416,9 +418,7 @@ class _TransverseDensityQKDEBase(AnalysisBase):
416
418
  self._masses = self._ag.masses.astype(np.float64)
417
419
  if self._grouping == "residues":
418
420
  residx = self._ag.resindices
419
- self._res_unique, self._res_inv = np.unique(
420
- residx, return_inverse=True
421
- )
421
+ self._res_unique, self._res_inv = np.unique(residx, return_inverse=True)
422
422
  self._n_res = self._res_unique.size
423
423
  self._res_mass = np.zeros(self._n_res, dtype=np.float64)
424
424
  np.add.at(self._res_mass, self._res_inv, self._masses)
@@ -458,10 +458,7 @@ class _TransverseDensityQKDEBase(AnalysisBase):
458
458
  z_bot = 0.0 if self._z_bot_user is None else float(self._z_bot_user)
459
459
  z_top = L if self._z_top_user is None else float(self._z_top_user)
460
460
  if z_top <= z_bot:
461
- raise ValueError(
462
- f"z_top ({z_top}) must be greater than "
463
- f"z_bot ({z_bot})"
464
- )
461
+ raise ValueError(f"z_top ({z_top}) must be greater than z_bot ({z_bot})")
465
462
 
466
463
  M = self._n_points
467
464
  self.z_eval = z_bot + (np.arange(M) + 0.5) * (z_top - z_bot) / M
@@ -86,6 +86,9 @@ from MDAnalysis.analysis.base import AnalysisBase
86
86
 
87
87
  from .density import epanechnikov_kernel
88
88
 
89
+ # Trapezoidal integration: np.trapezoid (NumPy >= 2.0) or np.trapz (older).
90
+ _trapezoid = getattr(np, "trapezoid", None) or np.trapz
91
+
89
92
  # Gaussian-kernel constants for the Sheather-Jones plug-in.
90
93
  # ||K||_2^2 = 1 / (2*sqrt(pi)), mu_2(K) = 1
91
94
  _GAU_KERNEL_NORM_SQ = 1.0 / (2.0 * np.sqrt(np.pi))
@@ -131,10 +134,7 @@ def _kernel(name):
131
134
  _EPA_KERNEL_NORM_SQ,
132
135
  _EPA_KERNEL_MU2_SQ,
133
136
  )
134
- raise ValueError(
135
- f"kernel must be 'gaussian' or 'epanechnikov', "
136
- f"got {name!r}"
137
- )
137
+ raise ValueError(f"kernel must be 'gaussian' or 'epanechnikov', got {name!r}")
138
138
 
139
139
 
140
140
  def silverman_bw(u_data):
@@ -218,7 +218,7 @@ def sheather_jones_bw(u_data, kernel="gaussian"):
218
218
  kernel_vals = kernel_fn(diff, h0)
219
219
  f_pilot = kernel_vals @ f_pilot_raw
220
220
 
221
- integral = np.trapezoid(f_pilot, u_fine)
221
+ integral = _trapezoid(f_pilot, u_fine)
222
222
  if integral > 0:
223
223
  f_pilot = f_pilot / integral
224
224
 
@@ -227,7 +227,7 @@ def sheather_jones_bw(u_data, kernel="gaussian"):
227
227
  f_pp[0] = f_pp[1]
228
228
  f_pp[-1] = f_pp[-2]
229
229
 
230
- int_fpp_sq = np.trapezoid(f_pp**2, u_fine)
230
+ int_fpp_sq = _trapezoid(f_pp**2, u_fine)
231
231
 
232
232
  if int_fpp_sq <= 0 or not np.isfinite(int_fpp_sq):
233
233
  return h_silver
@@ -340,7 +340,7 @@ def build_cdf(z_pooled):
340
340
  kernel /= kernel.sum()
341
341
  rho_smooth = np.convolve(rho_padded, kernel, mode="same")[n_pad:-n_pad]
342
342
 
343
- integral = np.trapezoid(rho_smooth, centers)
343
+ integral = _trapezoid(rho_smooth, centers)
344
344
  if integral > 0:
345
345
  rho_smooth = rho_smooth / integral
346
346
 
@@ -350,9 +350,7 @@ def build_cdf(z_pooled):
350
350
  # precedes the differencing, so the derivative is not dominated by
351
351
  # Poisson noise from the histogram bins).
352
352
  rho_prime_smooth = np.empty_like(rho_smooth)
353
- rho_prime_smooth[1:-1] = (
354
- rho_smooth[2:] - rho_smooth[:-2]
355
- ) / (2.0 * bin_width)
353
+ rho_prime_smooth[1:-1] = (rho_smooth[2:] - rho_smooth[:-2]) / (2.0 * bin_width)
356
354
  rho_prime_smooth[0] = rho_prime_smooth[1]
357
355
  rho_prime_smooth[-1] = rho_prime_smooth[-2]
358
356
 
@@ -631,12 +629,9 @@ class LocalDiffusivityQKDE(AnalysisBase):
631
629
  self._dim = dim
632
630
  self._para_dims = tuple(i for i in (0, 1, 2) if i != dim)
633
631
  self._n_points = int(n_points)
634
- if isinstance(bandwidth, str) and bandwidth not in (
635
- "auto", "silverman"
636
- ):
632
+ if isinstance(bandwidth, str) and bandwidth not in ("auto", "silverman"):
637
633
  raise ValueError(
638
- f"bandwidth must be 'auto', 'silverman' or a float, "
639
- f"got {bandwidth!r}"
634
+ f"bandwidth must be 'auto', 'silverman' or a float, got {bandwidth!r}"
640
635
  )
641
636
  self._bandwidth = bandwidth
642
637
  if kernel not in ("gaussian", "epanechnikov"):
@@ -11,6 +11,8 @@ from qdiffusivity.binned import (
11
11
  resolve_bins,
12
12
  )
13
13
 
14
+ _trapezoid = getattr(np, "trapezoid", None) or np.trapz
15
+
14
16
 
15
17
  def test_resolve_bins():
16
18
  """int, 'quantile', explicit edges (padded/full), and invalid specs."""
@@ -132,12 +134,8 @@ def test_diffusivity_binned(diff_universe, bins, expected_n):
132
134
  assert binned.dt == pytest.approx(1.0)
133
135
  bulk = (binned.z_centers > 20) & (binned.z_centers < 40)
134
136
  valid = binned.n_eff_perp > 5
135
- assert np.median(
136
- binned.D_perp[bulk & valid]
137
- ) == pytest.approx(D_perp_true, rel=0.3)
138
- assert np.median(
139
- binned.D_para[bulk & valid]
140
- ) == pytest.approx(D_para_true, rel=0.3)
137
+ assert np.median(binned.D_perp[bulk & valid]) == pytest.approx(D_perp_true, rel=0.3)
138
+ assert np.median(binned.D_para[bulk & valid]) == pytest.approx(D_para_true, rel=0.3)
141
139
 
142
140
 
143
141
  @pytest.mark.parametrize(
@@ -149,9 +147,7 @@ def test_diffusivity_binned(diff_universe, bins, expected_n):
149
147
  (LocalDiffusivityQBinned, {"dim": 5}, True),
150
148
  ],
151
149
  )
152
- def test_binned_validation(
153
- density_universe, diff_universe, cls, kwargs, use_diff
154
- ):
150
+ def test_binned_validation(density_universe, diff_universe, cls, kwargs, use_diff):
155
151
  if use_diff:
156
152
  u = diff_universe(n_atoms=10, n_frames=3, Lz=10.0)
157
153
  else:
@@ -171,7 +167,9 @@ def test_diffusivity_binned_explicit_dt(diff_universe):
171
167
  u = diff_universe(n_atoms=50, n_frames=5, Lz=40.0, seed=68)
172
168
  binned = LocalDiffusivityQBinned(
173
169
  u.select_atoms("all"),
174
- dim=2, bins=10, dt=2.0,
170
+ dim=2,
171
+ bins=10,
172
+ dt=2.0,
175
173
  )
176
174
  binned.run()
177
175
  assert binned.dt == pytest.approx(2.0)
@@ -183,9 +181,7 @@ def test_diffusivity_binned_ito(diff_universe, ito):
183
181
  on D_para."""
184
182
  u = diff_universe(n_atoms=200, n_frames=20, Lz=60.0, seed=66)
185
183
  ag = u.select_atoms("all")
186
- binned = LocalDiffusivityQBinned(
187
- ag, dim=2, bins=15, ito_correction=ito
188
- )
184
+ binned = LocalDiffusivityQBinned(ag, dim=2, bins=15, ito_correction=ito)
189
185
  binned.run()
190
186
  if not ito:
191
187
  assert binned.ito_bias is None
@@ -12,17 +12,15 @@ from qdiffusivity.density import (
12
12
  silverman_bw,
13
13
  )
14
14
 
15
+ _trapezoid = getattr(np, "trapezoid", None) or np.trapz
16
+
15
17
 
16
18
  def test_epanechnikov_kernel():
17
19
  """Normalised, compact support, non-negative, peak at zero."""
18
20
  x = np.linspace(-3.0, 3.0, 200_001)
19
- assert np.trapezoid(epanechnikov_kernel(x, 1.0), x) == pytest.approx(
20
- 1.0, abs=1e-4
21
- )
21
+ assert _trapezoid(epanechnikov_kernel(x, 1.0), x) == pytest.approx(1.0, abs=1e-4)
22
22
  assert epanechnikov_kernel(np.array([1.6]), 1.5)[0] == 0.0
23
- assert epanechnikov_kernel(np.array([0.0]), 1.5)[0] == pytest.approx(
24
- 0.75 / 1.5
25
- )
23
+ assert epanechnikov_kernel(np.array([0.0]), 1.5)[0] == pytest.approx(0.75 / 1.5)
26
24
  assert np.all(epanechnikov_kernel(x, 2.0) >= 0.0)
27
25
 
28
26
 
@@ -49,7 +47,7 @@ def test_kde_1d():
49
47
  z = rng.normal(50.0, 5.0, size=20_000)
50
48
  z_eval = np.linspace(20.0, 80.0, 2001)
51
49
  rho, n_eff = kde_1d(z, z_eval, 0.5, 0.0, 100.0)
52
- assert np.trapezoid(rho, z_eval) == pytest.approx(1.0, abs=0.02)
50
+ assert _trapezoid(rho, z_eval) == pytest.approx(1.0, abs=0.02)
53
51
  interior = (z_eval > 40) & (z_eval < 60)
54
52
  assert np.all(n_eff[interior] > 0)
55
53
  assert np.all(n_eff <= z.size)
@@ -59,9 +57,7 @@ def test_kde_1d():
59
57
  assert np.all(rho_e == 0.0) and np.all(n_eff_e == 0.0)
60
58
 
61
59
 
62
- @pytest.mark.parametrize(
63
- "cls", [TransverseNumDensityQKDE, TransverseMassDensityQKDE]
64
- )
60
+ @pytest.mark.parametrize("cls", [TransverseNumDensityQKDE, TransverseMassDensityQKDE])
65
61
  @pytest.mark.parametrize("grouping", ["atoms", "residues"])
66
62
  def test_density_qkde(density_universe, cls, grouping):
67
63
  """Run, attributes, density positive, auto bandwidth."""
@@ -142,9 +138,7 @@ def test_density_qkde_auto_boundaries(density_universe):
142
138
  assert kde.z_eval[-1] < 40.0
143
139
 
144
140
 
145
- @pytest.mark.parametrize(
146
- "cls", [TransverseNumDensityQKDE, TransverseMassDensityQKDE]
147
- )
141
+ @pytest.mark.parametrize("cls", [TransverseNumDensityQKDE, TransverseMassDensityQKDE])
148
142
  @pytest.mark.parametrize(
149
143
  "kwargs",
150
144
  [{"dim": 5}, {"grouping": "molecules"}, {"bandwidth": "bogus"}],
@@ -155,9 +149,7 @@ def test_density_qkde_validation(density_universe, cls, kwargs):
155
149
  cls(u.select_atoms("all"), **kwargs)
156
150
 
157
151
 
158
- @pytest.mark.parametrize(
159
- "cls", [TransverseNumDensityQKDE, TransverseMassDensityQKDE]
160
- )
152
+ @pytest.mark.parametrize("cls", [TransverseNumDensityQKDE, TransverseMassDensityQKDE])
161
153
  def test_density_qkde_inverted_boundaries(density_universe, cls):
162
154
  u = density_universe(n_atoms=10, n_res=2, n_frames=1, Lz=10.0)
163
155
  kde = cls(
@@ -12,13 +12,13 @@ from qdiffusivity.diffusivity import (
12
12
  select_diff_bandwidth,
13
13
  )
14
14
 
15
+ _trapezoid = getattr(np, "trapezoid", None) or np.trapz
16
+
15
17
 
16
18
  def test_gaussian_kernel():
17
19
  """Normalised, symmetric, peak at zero."""
18
20
  x = np.linspace(-10.0, 10.0, 200_001)
19
- assert np.trapezoid(
20
- gaussian_kernel(x, 1.0), x
21
- ) == pytest.approx(1.0, abs=1e-4)
21
+ assert _trapezoid(gaussian_kernel(x, 1.0), x) == pytest.approx(1.0, abs=1e-4)
22
22
  k = gaussian_kernel(np.array([-3, -1, 0, 1, 3.0]), 1.5)
23
23
  assert k[0] == pytest.approx(k[-1])
24
24
  assert k[2] > k[1] > k[0]
@@ -56,7 +56,7 @@ def test_build_cdf():
56
56
  assert np.allclose(z_back, z_grid, atol=0.1)
57
57
  rho_vals = rho(z_grid)
58
58
  assert np.all(rho_vals >= 0)
59
- assert np.trapezoid(rho_vals, z_grid) == pytest.approx(1.0, abs=0.1)
59
+ assert _trapezoid(rho_vals, z_grid) == pytest.approx(1.0, abs=0.1)
60
60
  rho_p = rho_prime(np.array([45.0, 50.0, 55.0]))
61
61
  assert rho_p[0] > 0 and rho_p[2] < 0
62
62
  assert rho_p[1] == pytest.approx(0.0, abs=2e-3)
@@ -130,12 +130,8 @@ def test_diffusivity_qkde(diff_universe, kernel):
130
130
  assert np.all(kde.D_perp >= 0)
131
131
  bulk = (kde.z_eval > 20) & (kde.z_eval < 40)
132
132
  valid = kde.n_eff_perp > 5
133
- assert np.median(
134
- kde.D_perp[bulk & valid]
135
- ) == pytest.approx(D_perp_true, rel=0.3)
136
- assert np.median(
137
- kde.D_para[bulk & valid]
138
- ) == pytest.approx(D_para_true, rel=0.3)
133
+ assert np.median(kde.D_perp[bulk & valid]) == pytest.approx(D_perp_true, rel=0.3)
134
+ assert np.median(kde.D_para[bulk & valid]) == pytest.approx(D_para_true, rel=0.3)
139
135
 
140
136
 
141
137
  @pytest.mark.parametrize(
@@ -151,7 +147,8 @@ def test_diffusivity_qkde_single_frame_raises(diff_universe):
151
147
  u = diff_universe(n_atoms=10, n_frames=1, Lz=10.0)
152
148
  kde = LocalDiffusivityQKDE(
153
149
  u.select_atoms("all"),
154
- n_points=10, bandwidth=0.1,
150
+ n_points=10,
151
+ bandwidth=0.1,
155
152
  )
156
153
  with pytest.raises(ValueError):
157
154
  kde.run()
@@ -204,9 +201,7 @@ def test_ito_correction(diff_universe, ito):
204
201
  kde2.run()
205
202
  bulk2 = (kde2.z_eval > 20) & (kde2.z_eval < 40)
206
203
  valid2 = kde2.n_eff_perp > 5
207
- assert np.median(
208
- kde2.D_perp[bulk2 & valid2]
209
- ) == pytest.approx(0.05, rel=0.3)
204
+ assert np.median(kde2.D_perp[bulk2 & valid2]) == pytest.approx(0.05, rel=0.3)
210
205
 
211
206
 
212
207
  def test_package_exports():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qdiffusivity
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Quantile-based estimation of local diffusivities in molecular dynamics simulations of nanoconfined liquids
5
5
  Author-email: Shern Ren Tee <shernren@gmail.com>
6
6
  Maintainer-email: Shern Ren Tee <shernren@gmail.com>
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes