chemparseplot 1.6.0__tar.gz → 1.7.0__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 (64) hide show
  1. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/PKG-INFO +1 -1
  2. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/_version.py +2 -2
  3. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/__init__.py +2 -0
  4. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/__init__.py +2 -0
  5. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/eon/dimer_trajectory.py +3 -1
  6. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/eon/saddle_search.py +9 -4
  7. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/orca/__init__.py +2 -0
  8. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/orca/neb/interp.py +2 -2
  9. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/orca/neb/opi_parser.py +2 -1
  10. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/sella/saddle_search.py +7 -2
  11. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/trajectory/__init__.py +2 -0
  12. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/plot/__init__.py +9 -0
  13. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/plot/chemgp.py +1 -2
  14. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/plot/geomscan.py +2 -1
  15. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/plot/neb.py +7 -7
  16. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/plot/structs.py +2 -1
  17. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/pyproject.toml +2 -0
  18. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/conftest.py +1 -1
  19. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/parse/orca/test_interp.py +8 -0
  20. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/test_coverage_batch.py +4 -0
  21. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/test_full_coverage.py +7 -2
  22. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/tutorials/test_chemparseplot.py +6 -0
  23. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/.gitignore +0 -0
  24. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/LICENSE +0 -0
  25. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/chemgp_hdf5.py +0 -0
  26. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/chemgp_jsonl.py +0 -0
  27. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/converter.py +0 -0
  28. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/eon/__init__.py +0 -0
  29. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/eon/gprd.py +0 -0
  30. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/eon/min_trajectory.py +0 -0
  31. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/eon/minimization.py +0 -0
  32. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/eon/neb.py +0 -0
  33. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/file_.py +0 -0
  34. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/neb_utils.py +0 -0
  35. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/orca/geomscan.py +0 -0
  36. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/orca/neb/__init__.py +0 -0
  37. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/patterns.py +0 -0
  38. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/plumed.py +0 -0
  39. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/projection.py +0 -0
  40. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/trajectory/hdf5.py +0 -0
  41. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/parse/trajectory/neb.py +0 -0
  42. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/plot/optimization.py +0 -0
  43. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/plot/plumed.py +0 -0
  44. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/plot/theme.py +0 -0
  45. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/units.py +0 -0
  46. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/chemparseplot/util.py +0 -0
  47. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/readme.md +0 -0
  48. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/parse/orca/test_geomscan.py +0 -0
  49. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/parse/test_chemgp_hdf5.py +0 -0
  50. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/parse/test_converter.py +0 -0
  51. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/parse/test_dimer_trajectory.py +0 -0
  52. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/parse/test_min_trajectory.py +0 -0
  53. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/parse/test_neb_utils.py +0 -0
  54. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/parse/test_patterns.py +0 -0
  55. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/parse/test_plumed.py +0 -0
  56. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/parse/test_projection.py +0 -0
  57. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/parse/test_trajectory_hdf5.py +0 -0
  58. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/parse/test_trajectory_neb.py +0 -0
  59. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/plot/__init__.py +0 -0
  60. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/plot/test_chemgp_utils.py +0 -0
  61. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/plot/test_neb_renderers.py +0 -0
  62. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/plot/test_optimization.py +0 -0
  63. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/plot/test_projection_refactor.py +0 -0
  64. {chemparseplot-1.6.0 → chemparseplot-1.7.0}/tests/plot/test_strip_rendering.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chemparseplot
3
- Version: 1.6.0
3
+ Version: 1.7.0
4
4
  Summary: Parsers and plotting tools for computational chemistry
5
5
  Project-URL: Documentation, https://chemparseplot.rgoswami.me
6
6
  Project-URL: Issues, https://github.com/HaoZeke/chemparseplot/issues
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '1.6.0'
22
- __version_tuple__ = version_tuple = (1, 6, 0)
21
+ __version__ = version = '1.7.0'
22
+ __version_tuple__ = version_tuple = (1, 7, 0)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -3,3 +3,5 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
 
5
5
  from chemparseplot import parse, units
6
+
7
+ __all__ = ["parse", "units"]
@@ -4,6 +4,8 @@
4
4
 
5
5
  from chemparseplot.parse import eon, orca, patterns
6
6
 
7
+ __all__ = ["eon", "orca", "patterns"]
8
+
7
9
  # Lazy imports for modules with optional heavy deps (h5py, pandas)
8
10
  # Import directly: from chemparseplot.parse.chemgp_hdf5 import read_h5_table
9
11
  # Or: from chemparseplot.parse import plumed, projection
@@ -140,7 +140,9 @@ def load_dimer_trajectory(job_dir: Path) -> DimerTrajectoryData:
140
140
  initial = atoms_list[0]
141
141
 
142
142
  saddle_path = job_dir / "saddle.con"
143
- saddle = readcon.read_con_as_ase(str(saddle_path))[0] if saddle_path.exists() else None
143
+ saddle = (
144
+ readcon.read_con_as_ase(str(saddle_path))[0] if saddle_path.exists() else None
145
+ )
144
146
 
145
147
  mode = _load_mode_dat(job_dir / "mode.dat")
146
148
 
@@ -7,10 +7,15 @@ from enum import Enum
7
7
  from pathlib import Path
8
8
 
9
9
  import numpy as np
10
- from rgpycrumbs.basetypes import DimerOpt, MolGeom, SaddleMeasure, SpinID
11
- from rgpycrumbs.parsers.bless import BLESS_LOG
12
- from rgpycrumbs.parsers.common import _NUM
13
- from rgpycrumbs.search.helpers import tail
10
+
11
+ try:
12
+ from rgpycrumbs.basetypes import DimerOpt, MolGeom, SaddleMeasure, SpinID
13
+ from rgpycrumbs.parsers.bless import BLESS_LOG
14
+ from rgpycrumbs.parsers.common import _NUM
15
+ from rgpycrumbs.search.helpers import tail
16
+ except ImportError:
17
+ DimerOpt = MolGeom = SaddleMeasure = SpinID = None
18
+ BLESS_LOG = _NUM = tail = None
14
19
 
15
20
  log = logging.getLogger(__name__)
16
21
 
@@ -3,3 +3,5 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
 
5
5
  from chemparseplot.parse.orca import geomscan
6
+
7
+ __all__ = ["geomscan"]
@@ -17,8 +17,6 @@ end
17
17
 
18
18
  import re
19
19
 
20
- from rgpycrumbs.basetypes import nebiter, nebpath
21
-
22
20
  import chemparseplot.parse.converter as conv
23
21
  import chemparseplot.parse.patterns as pat
24
22
  from chemparseplot.units import Q_
@@ -38,6 +36,8 @@ def extract_interp_points(text: str) -> list[int, Q_, Q_]:
38
36
  ```{versionadded} 0.0.2
39
37
  ```
40
38
  """
39
+ from rgpycrumbs.basetypes import nebiter, nebpath
40
+
41
41
  data = []
42
42
  for match in re.finditer(INTERP_PAT, text, re.DOTALL):
43
43
  iteration = int(match.group("iteration"))
@@ -17,7 +17,6 @@ from pathlib import Path
17
17
  from typing import Any
18
18
 
19
19
  import numpy as np
20
- from rgpycrumbs._aux import ensure_import
21
20
 
22
21
  # Lazy import - will be loaded on first use
23
22
  _opi_output = None
@@ -27,6 +26,8 @@ def _get_opi_output():
27
26
  """Get OPI Output class, installing if needed."""
28
27
  global _opi_output
29
28
  if _opi_output is None:
29
+ from rgpycrumbs._aux import ensure_import
30
+
30
31
  _opi_output = ensure_import("opi.output.core").Output
31
32
  return _opi_output
32
33
 
@@ -8,8 +8,13 @@ from pathlib import Path
8
8
  import ase
9
9
  import numpy as np
10
10
  from ase.io import read
11
- from rgpycrumbs.basetypes import SaddleMeasure, SpinID
12
- from rgpycrumbs.time.helpers import one_day_tdelta
11
+
12
+ try:
13
+ from rgpycrumbs.basetypes import SaddleMeasure, SpinID
14
+ from rgpycrumbs.time.helpers import one_day_tdelta
15
+ except ImportError:
16
+ SaddleMeasure = SpinID = None
17
+ one_day_tdelta = None
13
18
 
14
19
  log = logging.getLogger(__name__)
15
20
 
@@ -3,3 +3,5 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
 
5
5
  from chemparseplot.parse.trajectory import hdf5, neb
6
+
7
+ __all__ = ["hdf5", "neb"]
@@ -11,6 +11,15 @@ from chemparseplot.plot.theme import (
11
11
  setup_publication_theme,
12
12
  )
13
13
 
14
+ __all__ = [
15
+ "RUHI_COLORS",
16
+ "RUHI_THEME",
17
+ "PlotTheme",
18
+ "get_theme",
19
+ "setup_global_theme",
20
+ "setup_publication_theme",
21
+ ]
22
+
14
23
 
15
24
  # Lazy imports for submodules with heavy deps (cmcrameri, pint, etc.)
16
25
  def __getattr__(name):
@@ -1,5 +1,3 @@
1
- from functools import lru_cache
2
-
3
1
  """ChemGP visualization functions.
4
2
 
5
3
  Mixed plotnine (for 1D line charts) and matplotlib (for 2D
@@ -15,6 +13,7 @@ for ggplot2 grammar.
15
13
  """
16
14
 
17
15
  import logging
16
+ from functools import lru_cache
18
17
 
19
18
  import matplotlib.patheffects as mpe
20
19
  import matplotlib.pyplot as plt
@@ -1,7 +1,6 @@
1
1
  from typing import Any
2
2
 
3
3
  import matplotlib.pyplot as plt
4
- from rgpycrumbs.interpolation import spline_interp
5
4
 
6
5
  from chemparseplot.plot.structs import BasePlotter
7
6
 
@@ -24,6 +23,8 @@ def plot_energy_paths(
24
23
  distance_values = path.distance.to(units["distance"])
25
24
  energy_values = path.energy.to(units["energy"])
26
25
 
26
+ from rgpycrumbs.interpolation import spline_interp
27
+
27
28
  distance_fine, energy_fine = spline_interp(distance_values.m, energy_values.m)
28
29
 
29
30
  # Determine the color for each path using the colormap
@@ -8,7 +8,6 @@ from dataclasses import dataclass
8
8
  from pathlib import Path
9
9
  from typing import Any
10
10
 
11
- import matplotlib.patheffects as path_effects
12
11
  import matplotlib.pyplot as plt
13
12
  import numpy as np
14
13
  from ase.io import write as ase_write
@@ -16,12 +15,6 @@ from matplotlib import tri
16
15
  from matplotlib.collections import LineCollection
17
16
  from matplotlib.offsetbox import AnnotationBbox, OffsetImage
18
17
  from matplotlib.patches import ArrowStyle
19
- from rgpycrumbs.surfaces import (
20
- NYSTROM_N_INDUCING_DEFAULT,
21
- NYSTROM_THRESHOLD,
22
- get_surface_model,
23
- nystrom_paths_needed,
24
- )
25
18
  from scipy import ndimage
26
19
  from scipy.interpolate import (
27
20
  CubicHermiteSpline,
@@ -813,6 +806,13 @@ def plot_landscape_surface(
813
806
  Added the *project_path* parameter for reaction-valley coordinate projection.
814
807
  ```
815
808
  """
809
+ from rgpycrumbs.surfaces import (
810
+ NYSTROM_N_INDUCING_DEFAULT,
811
+ NYSTROM_THRESHOLD,
812
+ get_surface_model,
813
+ nystrom_paths_needed,
814
+ )
815
+
816
816
  log.info(f"Generating 2D surface using {method} (Projected: {project_path})...")
817
817
 
818
818
  if basis is None and project_path:
@@ -2,7 +2,6 @@ from collections import namedtuple
2
2
 
3
3
  import matplotlib.pyplot as plt
4
4
  from cmcrameri import cm
5
- from rgpycrumbs.interpolation import spline_interp
6
5
 
7
6
  # Define a namedtuple for energy paths
8
7
  EnergyPath = namedtuple("EnergyPath", ["label", "distance", "energy"])
@@ -77,6 +76,8 @@ class TwoDimPlot(BasePlotter):
77
76
  for idx, xy_data in enumerate(self.data):
78
77
  x_values = xy_data.x.to(self.x_unit).m
79
78
  y_values = xy_data.y.to(self.y_unit).m
79
+ from rgpycrumbs.interpolation import spline_interp
80
+
80
81
  distance_fine, y_fine = spline_interp(x_values, y_values)
81
82
 
82
83
  color = self.colormap(idx / len(self.data))
@@ -182,6 +182,8 @@ ban-relative-imports = "all"
182
182
  "FBT002",
183
183
  "PLW2901",
184
184
  ]
185
+ "chemparseplot/plot/structs.py" = ["PLC0415"]
186
+ "chemparseplot/plot/geomscan.py" = ["PLC0415"]
185
187
  "chemparseplot/plot/neb.py" = ["PLR2004", "PLC0415", "C408"]
186
188
  "chemparseplot/parse/orca/neb/opi_parser.py" = [
187
189
  "PLC0415", # late imports for optional deps (ase)
@@ -8,7 +8,7 @@ import pytest
8
8
  # Define the requirements for each suite/marker
9
9
  ENVIRONMENT_REQUIREMENTS = {
10
10
  "pure": ["numpy"],
11
- "neb": ["numpy", "polars", "ase", "h5py", "scipy", "matplotlib"],
11
+ "neb": ["numpy", "polars", "ase", "h5py", "scipy", "matplotlib", "rgpycrumbs"],
12
12
  }
13
13
 
14
14
 
@@ -1,11 +1,19 @@
1
1
  # SPDX-FileCopyrightText: 2023-present Rohit Goswami <rog32@hi.is>
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
+ import pytest
5
+
6
+ from tests.conftest import skip_if_not_env
7
+
8
+ skip_if_not_env("neb")
9
+
4
10
  from rgpycrumbs.basetypes import nebiter
5
11
 
6
12
  from chemparseplot.parse.orca.neb.interp import extract_interp_points
7
13
  from chemparseplot.units import ureg
8
14
 
15
+ pytestmark = pytest.mark.neb
16
+
9
17
 
10
18
  def test_extract_interp_points_valid_input():
11
19
  # Example valid text input
@@ -191,6 +191,10 @@ class TestPlotLazyImports:
191
191
  # ============================================================
192
192
  # chemparseplot.parse.neb_utils (calculate_landscape_coords)
193
193
  # ============================================================
194
+ @pytest.mark.skipif(
195
+ importlib.util.find_spec("rgpycrumbs") is None,
196
+ reason="rgpycrumbs not installed",
197
+ )
194
198
  class TestCalculateLandscapeCoords:
195
199
  def test_with_mock_ira(self):
196
200
  """Test with a mock IRA that returns identity RMSD."""
@@ -32,6 +32,8 @@ try:
32
32
  except ImportError:
33
33
  _HAS_CMCRAMERI = False
34
34
 
35
+ _HAS_RGPYCRUMBS = importlib.util.find_spec("rgpycrumbs") is not None
36
+
35
37
 
36
38
  # ============================================================
37
39
  # chemparseplot.parse.chemgp_hdf5
@@ -773,7 +775,8 @@ _PY310 = sys.version_info < (3, 11)
773
775
 
774
776
 
775
777
  @pytest.mark.skipif(
776
- not _HAS_CMCRAMERI or _PY310, reason="cmcrameri required, py3.10 has recursion issue"
778
+ not _HAS_CMCRAMERI or _PY310 or not _HAS_RGPYCRUMBS,
779
+ reason="cmcrameri + rgpycrumbs required, py3.10 has recursion issue",
777
780
  )
778
781
  class TestGeomscanPlot:
779
782
  def test_plot_energy_paths(self):
@@ -794,7 +797,7 @@ class TestGeomscanPlot:
794
797
  units = {"distance": "angstrom", "energy": "eV"}
795
798
 
796
799
  with patch(
797
- "chemparseplot.plot.geomscan.spline_interp",
800
+ "rgpycrumbs.interpolation.spline_interp",
798
801
  return_value=(np.linspace(0, 3, 100), np.sin(np.linspace(0, 3, 100))),
799
802
  ):
800
803
  from chemparseplot.plot.geomscan import plot_energy_paths
@@ -1274,6 +1277,7 @@ class TestNebPlotSurface:
1274
1277
  # ============================================================
1275
1278
  # chemparseplot.parse.trajectory.hdf5 (lines 253-294)
1276
1279
  # ============================================================
1280
+ @pytest.mark.skipif(not _HAS_RGPYCRUMBS, reason="rgpycrumbs required")
1277
1281
  class TestTrajectoryHdf5:
1278
1282
  def _make_h5_result(self, tmp_path, n_images=5, n_atoms=3):
1279
1283
  """Create a minimal neb_result.h5 file."""
@@ -1414,6 +1418,7 @@ class TestTrajectoryHdf5:
1414
1418
  # ============================================================
1415
1419
  # chemparseplot.parse.trajectory.neb (fallback paths)
1416
1420
  # ============================================================
1421
+ @pytest.mark.skipif(not _HAS_RGPYCRUMBS, reason="rgpycrumbs required")
1417
1422
  class TestTrajectoryNeb:
1418
1423
  def test_get_energy_from_calc(self):
1419
1424
  from ase import Atoms
@@ -6,6 +6,12 @@ Verifies that tutorial code examples work correctly.
6
6
  Run with: cd chemparseplot && uv run python tests/tutorials/test_chemparseplot.py
7
7
  """
8
8
 
9
+ import pytest
10
+
11
+ from tests.conftest import skip_if_not_env
12
+
13
+ skip_if_not_env("neb")
14
+
9
15
  import sys
10
16
  from pathlib import Path
11
17
 
File without changes
File without changes
File without changes