chemparseplot 1.9.1__tar.gz → 1.9.3__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 (85) hide show
  1. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/PKG-INFO +1 -1
  2. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/_version.py +2 -2
  3. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/plot/neb.py +100 -18
  4. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/.gitignore +0 -0
  5. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/LICENSE +0 -0
  6. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/__init__.py +0 -0
  7. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/__init__.py +0 -0
  8. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/chemgp_hdf5.py +0 -0
  9. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/chemgp_jsonl.py +0 -0
  10. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/converter.py +0 -0
  11. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/eon/__init__.py +0 -0
  12. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/eon/_trajectory_common.py +0 -0
  13. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/eon/con_io.py +0 -0
  14. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/eon/dimer_trajectory.py +0 -0
  15. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/eon/gprd.py +0 -0
  16. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/eon/min_trajectory.py +0 -0
  17. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/eon/minimization.py +0 -0
  18. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/eon/neb.py +0 -0
  19. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/eon/saddle_search.py +0 -0
  20. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/eon/stitch.py +0 -0
  21. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/file_.py +0 -0
  22. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/neb_utils.py +0 -0
  23. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/orca/__init__.py +0 -0
  24. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/orca/geomscan.py +0 -0
  25. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/orca/neb/__init__.py +0 -0
  26. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/orca/neb/interp.py +0 -0
  27. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/orca/neb/opi_parser.py +0 -0
  28. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/patterns.py +0 -0
  29. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/plumed.py +0 -0
  30. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/projection.py +0 -0
  31. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/sella/saddle_search.py +0 -0
  32. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/trajectory/__init__.py +0 -0
  33. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/trajectory/hdf5.py +0 -0
  34. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/trajectory/neb.py +0 -0
  35. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/parse/types.py +0 -0
  36. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/plot/__init__.py +0 -0
  37. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/plot/chemgp.py +0 -0
  38. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/plot/geomscan.py +0 -0
  39. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/plot/optimization.py +0 -0
  40. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/plot/plumed.py +0 -0
  41. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/plot/structs.py +0 -0
  42. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/plot/theme.py +0 -0
  43. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/units.py +0 -0
  44. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/chemparseplot/util.py +0 -0
  45. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/pyproject.toml +0 -0
  46. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/readme.md +0 -0
  47. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/__init__.py +0 -0
  48. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/_optional_imports.py +0 -0
  49. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/conftest.py +0 -0
  50. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/__init__.py +0 -0
  51. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/_con_fixtures.py +0 -0
  52. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/orca/test_geomscan.py +0 -0
  53. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/orca/test_interp.py +0 -0
  54. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_chemgp_hdf5.py +0 -0
  55. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_chemgp_jsonl_types.py +0 -0
  56. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_con_io.py +0 -0
  57. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_converter.py +0 -0
  58. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_dimer_trajectory.py +0 -0
  59. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_eon_neb_types.py +0 -0
  60. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_eon_trajectory_common.py +0 -0
  61. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_min_trajectory.py +0 -0
  62. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_minimization_result.py +0 -0
  63. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_neb_stitch.py +0 -0
  64. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_neb_utils.py +0 -0
  65. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_parser_types.py +0 -0
  66. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_patterns.py +0 -0
  67. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_plumed.py +0 -0
  68. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_projection.py +0 -0
  69. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_readcon_boundary.py +0 -0
  70. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_saddle_results.py +0 -0
  71. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_sella_saddle.py +0 -0
  72. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_trajectory_hdf5.py +0 -0
  73. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/parse/test_trajectory_neb.py +0 -0
  74. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/plot/__init__.py +0 -0
  75. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/plot/test_chemgp_utils.py +0 -0
  76. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/plot/test_neb_helpers.py +0 -0
  77. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/plot/test_neb_renderers.py +0 -0
  78. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/plot/test_optimization.py +0 -0
  79. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/plot/test_orca_neb_payload.py +0 -0
  80. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/plot/test_projection_refactor.py +0 -0
  81. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/plot/test_strip_rendering.py +0 -0
  82. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/plot/test_structs_units.py +0 -0
  83. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/test_coverage_batch.py +0 -0
  84. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/test_full_coverage.py +0 -0
  85. {chemparseplot-1.9.1 → chemparseplot-1.9.3}/tests/tutorials/test_chemparseplot.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chemparseplot
3
- Version: 1.9.1
3
+ Version: 1.9.3
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.9.1'
22
- __version_tuple__ = version_tuple = (1, 9, 1)
21
+ __version__ = version = '1.9.3'
22
+ __version_tuple__ = version_tuple = (1, 9, 3)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -1577,27 +1577,102 @@ def landscape_projection_basis(global_basis, final_r, final_p):
1577
1577
  return compute_projection_basis(final_r, final_p)
1578
1578
 
1579
1579
 
1580
- def landscape_half_span(x_limits, final_r, final_p, additional_atoms_data, global_basis):
1581
- """Expand the symmetric landscape half-span to keep extra markers visible."""
1580
+ def landscape_half_span(
1581
+ x_limits,
1582
+ final_r,
1583
+ final_p,
1584
+ additional_atoms_data,
1585
+ global_basis,
1586
+ *,
1587
+ path_pad: float = 1.15,
1588
+ min_half: float = 0.02,
1589
+ ):
1590
+ """Symmetric |d| half-span from the path (and optional overlays), not s/2.
1582
1591
 
1583
- half_span = (x_limits[1] - x_limits[0]) / 2
1584
- if not additional_atoms_data:
1585
- return half_span
1592
+ Using the reaction-progress half-width as the default forced a near-square
1593
+ frame and large empty bands above/below paths that stay near ``d=0``.
1594
+ """
1586
1595
 
1587
1596
  basis = landscape_projection_basis(global_basis, final_r, final_p)
1588
- for overlay in additional_atoms_data:
1589
- _, add_d = project_to_sd(np.array([overlay.r]), np.array([overlay.p]), basis)
1590
- half_span = max(half_span, abs(float(add_d[0])) * 1.15)
1591
- return half_span
1597
+ _s, _d = project_to_sd(np.asarray(final_r), np.asarray(final_p), basis)
1598
+ half_span = max(abs(float(_d.max())), abs(float(_d.min())), min_half) * path_pad
1599
+ for overlay in additional_atoms_data or []:
1600
+ _, add_d = project_to_sd(
1601
+ np.array([overlay.r]), np.array([overlay.p]), basis
1602
+ )
1603
+ half_span = max(half_span, abs(float(add_d[0])) * path_pad)
1604
+ # Tiny floor only (absolute), never a fraction of s — that reintroduced the
1605
+ # empty top/bottom bands on near-linear paths.
1606
+ del x_limits # reserved for future asymmetric s handling
1607
+ return max(half_span, min_half)
1592
1608
 
1593
1609
 
1594
- def save_plot(output_file, dpi, *, has_strip):
1595
- """Save plots without tight-bbox strip overflow."""
1610
+ def mark_saddle_point(
1611
+ ax,
1612
+ x,
1613
+ y,
1614
+ *,
1615
+ label: str = "SP",
1616
+ font_size: float = 12.0,
1617
+ vline: bool = False,
1618
+ annotate: bool = True,
1619
+ ):
1620
+ """Draw a high-contrast saddle marker (gold star) on a profile or landscape."""
1596
1621
 
1597
- save_kwargs = {"transparent": False, "pad_inches": 0.1, "dpi": dpi}
1598
- if not has_strip:
1599
- save_kwargs["bbox_inches"] = "tight"
1600
- plt.savefig(output_file, **save_kwargs)
1622
+ ax.scatter(
1623
+ float(x),
1624
+ float(y),
1625
+ marker="*",
1626
+ s=max(280, int(font_size**2 * 3.2)),
1627
+ c="#FFD700",
1628
+ edgecolors="black",
1629
+ linewidths=1.8,
1630
+ zorder=100,
1631
+ label=label,
1632
+ )
1633
+ if vline:
1634
+ ax.axvline(
1635
+ float(x),
1636
+ color="black",
1637
+ linestyle="--",
1638
+ linewidth=1.4,
1639
+ alpha=0.75,
1640
+ zorder=50,
1641
+ )
1642
+ if annotate:
1643
+ ax.annotate(
1644
+ label,
1645
+ xy=(float(x), float(y)),
1646
+ xytext=(10, 14),
1647
+ textcoords="offset points",
1648
+ fontsize=int(font_size * 1.05),
1649
+ fontweight="bold",
1650
+ color="black",
1651
+ zorder=101,
1652
+ bbox={
1653
+ "boxstyle": "round,pad=0.2",
1654
+ "facecolor": "white",
1655
+ "edgecolor": "black",
1656
+ "linewidth": 0.8,
1657
+ "alpha": 0.92,
1658
+ },
1659
+ )
1660
+
1661
+
1662
+ def save_plot(output_file, dpi, *, has_strip):
1663
+ """Save plots, cropping unused figure canvas (including strip layouts)."""
1664
+
1665
+ # Strips use imshow+Text (not unclipped AnnotationBbox growth), so tight
1666
+ # bbox is safe and removes the large whitespace left by equal-aspect
1667
+ # landscape axes inside a tall/wide figure.
1668
+ del has_strip # kept for API compatibility with callers
1669
+ plt.savefig(
1670
+ output_file,
1671
+ transparent=False,
1672
+ dpi=dpi,
1673
+ bbox_inches="tight",
1674
+ pad_inches=0.05,
1675
+ )
1601
1676
 
1602
1677
 
1603
1678
  def profile_structure_indices(atoms_list, y_values, plot_structures, plot_mode):
@@ -1617,15 +1692,22 @@ def profile_strip_payload(atoms_list, x_values, y_values, plot_structures, plot_
1617
1692
  """Build an ordered strip payload for profile plots."""
1618
1693
 
1619
1694
  payload = []
1695
+ saddle_idx = (
1696
+ int(np.argmax(y_values[1:-1]) + 1)
1697
+ if plot_mode == "energy" and len(y_values) > 2
1698
+ else int(np.argmin(y_values))
1699
+ )
1620
1700
  for index in profile_structure_indices(
1621
1701
  atoms_list, y_values, plot_structures, plot_mode
1622
1702
  ):
1623
- if plot_structures == "all":
1624
- label = str(index)
1625
- elif index == 0:
1703
+ if index == 0:
1626
1704
  label = "R"
1627
1705
  elif index == len(atoms_list) - 1:
1628
1706
  label = "P"
1707
+ elif index == saddle_idx:
1708
+ label = "SP"
1709
+ elif plot_structures == "all":
1710
+ label = str(index)
1629
1711
  else:
1630
1712
  label = "SP"
1631
1713
  payload.append(
File without changes
File without changes
File without changes