chemparseplot 1.9.0__tar.gz → 1.9.2__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.0 → chemparseplot-1.9.2}/PKG-INFO +1 -1
  2. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/_version.py +2 -2
  3. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/eon/neb.py +2 -2
  4. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/plot/neb.py +40 -19
  5. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/.gitignore +0 -0
  6. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/LICENSE +0 -0
  7. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/__init__.py +0 -0
  8. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/__init__.py +0 -0
  9. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/chemgp_hdf5.py +0 -0
  10. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/chemgp_jsonl.py +0 -0
  11. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/converter.py +0 -0
  12. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/eon/__init__.py +0 -0
  13. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/eon/_trajectory_common.py +0 -0
  14. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/eon/con_io.py +0 -0
  15. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/eon/dimer_trajectory.py +0 -0
  16. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/eon/gprd.py +0 -0
  17. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/eon/min_trajectory.py +0 -0
  18. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/eon/minimization.py +0 -0
  19. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/eon/saddle_search.py +0 -0
  20. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/eon/stitch.py +0 -0
  21. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/file_.py +0 -0
  22. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/neb_utils.py +0 -0
  23. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/orca/__init__.py +0 -0
  24. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/orca/geomscan.py +0 -0
  25. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/orca/neb/__init__.py +0 -0
  26. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/orca/neb/interp.py +0 -0
  27. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/orca/neb/opi_parser.py +0 -0
  28. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/patterns.py +0 -0
  29. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/plumed.py +0 -0
  30. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/projection.py +0 -0
  31. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/sella/saddle_search.py +0 -0
  32. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/trajectory/__init__.py +0 -0
  33. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/trajectory/hdf5.py +0 -0
  34. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/trajectory/neb.py +0 -0
  35. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/parse/types.py +0 -0
  36. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/plot/__init__.py +0 -0
  37. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/plot/chemgp.py +0 -0
  38. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/plot/geomscan.py +0 -0
  39. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/plot/optimization.py +0 -0
  40. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/plot/plumed.py +0 -0
  41. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/plot/structs.py +0 -0
  42. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/plot/theme.py +0 -0
  43. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/units.py +0 -0
  44. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/chemparseplot/util.py +0 -0
  45. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/pyproject.toml +0 -0
  46. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/readme.md +0 -0
  47. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/__init__.py +0 -0
  48. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/_optional_imports.py +0 -0
  49. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/conftest.py +0 -0
  50. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/__init__.py +0 -0
  51. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/_con_fixtures.py +0 -0
  52. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/orca/test_geomscan.py +0 -0
  53. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/orca/test_interp.py +0 -0
  54. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_chemgp_hdf5.py +0 -0
  55. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_chemgp_jsonl_types.py +0 -0
  56. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_con_io.py +0 -0
  57. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_converter.py +0 -0
  58. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_dimer_trajectory.py +0 -0
  59. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_eon_neb_types.py +0 -0
  60. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_eon_trajectory_common.py +0 -0
  61. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_min_trajectory.py +0 -0
  62. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_minimization_result.py +0 -0
  63. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_neb_stitch.py +0 -0
  64. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_neb_utils.py +0 -0
  65. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_parser_types.py +0 -0
  66. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_patterns.py +0 -0
  67. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_plumed.py +0 -0
  68. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_projection.py +0 -0
  69. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_readcon_boundary.py +0 -0
  70. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_saddle_results.py +0 -0
  71. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_sella_saddle.py +0 -0
  72. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_trajectory_hdf5.py +0 -0
  73. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/parse/test_trajectory_neb.py +0 -0
  74. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/plot/__init__.py +0 -0
  75. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/plot/test_chemgp_utils.py +0 -0
  76. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/plot/test_neb_helpers.py +0 -0
  77. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/plot/test_neb_renderers.py +0 -0
  78. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/plot/test_optimization.py +0 -0
  79. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/plot/test_orca_neb_payload.py +0 -0
  80. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/plot/test_projection_refactor.py +0 -0
  81. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/plot/test_strip_rendering.py +0 -0
  82. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/plot/test_structs_units.py +0 -0
  83. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/test_coverage_batch.py +0 -0
  84. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/tests/test_full_coverage.py +0 -0
  85. {chemparseplot-1.9.0 → chemparseplot-1.9.2}/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.0
3
+ Version: 1.9.2
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.0'
22
- __version_tuple__ = version_tuple = (1, 9, 0)
21
+ __version__ = version = '1.9.2'
22
+ __version_tuple__ = version_tuple = (1, 9, 2)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -69,7 +69,7 @@ def load_or_compute_data(
69
69
  ```{versionadded} 0.1.0
70
70
  ```
71
71
  """
72
- if cache_file and cache_file.exists() and not force_recompute:
72
+ if cache_file and Path(cache_file).exists() and not force_recompute:
73
73
  log.info(f"Loading cached {context_name} data from {cache_file}...")
74
74
  try:
75
75
  df = pl.read_parquet(cache_file)
@@ -111,7 +111,7 @@ def load_structures_and_calculate_additional_rmsd(
111
111
  sp_data = None
112
112
  ira_instance = ira_mod.IRA() if ira_mod else None
113
113
 
114
- if sp_file and sp_file.exists():
114
+ if sp_file and Path(sp_file).exists():
115
115
  log.info(f"Loading explicit saddle point from {sp_file}")
116
116
  sp_atoms = ase_read(sp_file)
117
117
  sp_rmsd_r = calculate_rmsd_from_ref(
@@ -584,11 +584,14 @@ def plot_structure_strip(
584
584
 
585
585
  ax.axis("off")
586
586
  n_plot = len(atoms_list)
587
- n_cols = min(n_plot, max_cols)
588
- n_rows = (n_plot + max_cols - 1) // max_cols
587
+ # Prefer a single row when everything fits; multi-row with a shared label
588
+ # baseline previously stacked numbers on top of each other.
589
+ effective_max_cols = max(max_cols, n_plot) if n_plot <= 16 else max_cols
590
+ n_cols = min(n_plot, effective_max_cols)
591
+ n_rows = (n_plot + effective_max_cols - 1) // effective_max_cols
589
592
 
590
593
  # Adaptive font size: shrink for many items
591
- label_fontsize = min(11, max(7, 14 - n_plot))
594
+ label_fontsize = min(11, max(7, 14 - n_plot // 2))
592
595
 
593
596
  fig = ax.figure
594
597
  fig.canvas.draw()
@@ -599,7 +602,6 @@ def plot_structure_strip(
599
602
  ax.set_xlim(0, ax_w_px)
600
603
  ax.set_ylim(0, ax_h_px)
601
604
 
602
- per_row_px = ax_h_px / max(n_rows, 1)
603
605
  per_col_px = ax_w_px / max(n_cols, 1)
604
606
  label_band_px = label_fontsize * fig.dpi / 72 * 1.8
605
607
  top_padding_px = 6.0
@@ -607,7 +609,7 @@ def plot_structure_strip(
607
609
  row_gap_px = 10.0
608
610
  usable_total_height_px = max(
609
611
  24.0,
610
- ax_h_px - label_band_px - top_padding_px - bottom_padding_px,
612
+ ax_h_px - label_band_px * n_rows - top_padding_px - bottom_padding_px,
611
613
  )
612
614
  slot_height_px = usable_total_height_px / max(n_rows, 1)
613
615
  slot_width_px = per_col_px
@@ -615,7 +617,7 @@ def plot_structure_strip(
615
617
  target_width_px = max(
616
618
  20, int(round((slot_width_px - col_gap_px) * width_fill_fraction))
617
619
  )
618
- available_height_px = max(20.0, slot_height_px - row_gap_px)
620
+ available_height_px = max(20.0, slot_height_px - row_gap_px - label_band_px * 0.35)
619
621
  target_height_px = max(
620
622
  20,
621
623
  int(
@@ -626,14 +628,14 @@ def plot_structure_strip(
626
628
  )
627
629
  ),
628
630
  )
629
- label_y_px = 4.0
630
631
  canvas = np.zeros((ax_h_px, ax_w_px, 4), dtype=np.float32)
631
632
 
632
633
  for i, atoms in enumerate(atoms_list):
633
- col = i % max_cols
634
- row = i // max_cols
634
+ col = i % effective_max_cols
635
+ row = i // effective_max_cols
635
636
  slot_center_x = (col + 0.5) * slot_width_px
636
637
  slot_top_y = ax_h_px - top_padding_px - row * slot_height_px
638
+ slot_bottom_y = slot_top_y - slot_height_px
637
639
  img_top_y = (
638
640
  slot_top_y - (slot_height_px - target_height_px) / 2 - target_height_px
639
641
  )
@@ -661,15 +663,20 @@ def plot_structure_strip(
661
663
  _alpha_blit_rgba(canvas, resized, x0, y0)
662
664
 
663
665
  if labels and i < len(labels):
666
+ # Label under *this* cell (not a shared strip baseline). Multi-row
667
+ # layouts previously wrote every label at y=4, so column mates from
668
+ # different rows stacked on top of each other.
669
+ cell_label_y = max(2.0, slot_bottom_y + 3.0)
664
670
  ax.text(
665
671
  x=slot_center_x,
666
- y=label_y_px,
672
+ y=cell_label_y,
667
673
  s=labels[i],
668
674
  ha="center",
669
675
  va="bottom",
670
676
  fontsize=label_fontsize,
671
677
  color=theme_color,
672
678
  fontweight="bold",
679
+ clip_on=False,
673
680
  )
674
681
 
675
682
  ax.imshow(
@@ -1585,12 +1592,19 @@ def landscape_half_span(x_limits, final_r, final_p, additional_atoms_data, globa
1585
1592
 
1586
1593
 
1587
1594
  def save_plot(output_file, dpi, *, has_strip):
1588
- """Save plots without tight-bbox strip overflow."""
1589
-
1590
- save_kwargs = {"transparent": False, "pad_inches": 0.1, "dpi": dpi}
1591
- if not has_strip:
1592
- save_kwargs["bbox_inches"] = "tight"
1593
- plt.savefig(output_file, **save_kwargs)
1595
+ """Save plots, cropping unused figure canvas (including strip layouts)."""
1596
+
1597
+ # Strips use imshow+Text (not unclipped AnnotationBbox growth), so tight
1598
+ # bbox is safe and removes the large whitespace left by equal-aspect
1599
+ # landscape axes inside a tall/wide figure.
1600
+ del has_strip # kept for API compatibility with callers
1601
+ plt.savefig(
1602
+ output_file,
1603
+ transparent=False,
1604
+ dpi=dpi,
1605
+ bbox_inches="tight",
1606
+ pad_inches=0.12,
1607
+ )
1594
1608
 
1595
1609
 
1596
1610
  def profile_structure_indices(atoms_list, y_values, plot_structures, plot_mode):
@@ -1610,15 +1624,22 @@ def profile_strip_payload(atoms_list, x_values, y_values, plot_structures, plot_
1610
1624
  """Build an ordered strip payload for profile plots."""
1611
1625
 
1612
1626
  payload = []
1627
+ saddle_idx = (
1628
+ int(np.argmax(y_values[1:-1]) + 1)
1629
+ if plot_mode == "energy" and len(y_values) > 2
1630
+ else int(np.argmin(y_values))
1631
+ )
1613
1632
  for index in profile_structure_indices(
1614
1633
  atoms_list, y_values, plot_structures, plot_mode
1615
1634
  ):
1616
- if plot_structures == "all":
1617
- label = str(index)
1618
- elif index == 0:
1635
+ if index == 0:
1619
1636
  label = "R"
1620
1637
  elif index == len(atoms_list) - 1:
1621
1638
  label = "P"
1639
+ elif index == saddle_idx:
1640
+ label = "SP"
1641
+ elif plot_structures == "all":
1642
+ label = str(index)
1622
1643
  else:
1623
1644
  label = "SP"
1624
1645
  payload.append(
File without changes
File without changes
File without changes