quantui 0.9.0__tar.gz → 0.11.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 (128) hide show
  1. {quantui-0.9.0 → quantui-0.11.1}/CHANGELOG.md +460 -1
  2. {quantui-0.9.0/quantui.egg-info → quantui-0.11.1}/PKG-INFO +76 -21
  3. {quantui-0.9.0 → quantui-0.11.1}/README.md +67 -16
  4. {quantui-0.9.0 → quantui-0.11.1}/pyproject.toml +19 -5
  5. quantui-0.11.1/quantui/__init__.py +311 -0
  6. {quantui-0.9.0 → quantui-0.11.1}/quantui/app.py +775 -93
  7. {quantui-0.9.0 → quantui-0.11.1}/quantui/app_analysis.py +195 -26
  8. {quantui-0.9.0 → quantui-0.11.1}/quantui/app_builders.py +766 -260
  9. {quantui-0.9.0 → quantui-0.11.1}/quantui/app_exports.py +77 -30
  10. {quantui-0.9.0 → quantui-0.11.1}/quantui/app_formatters.py +599 -137
  11. {quantui-0.9.0 → quantui-0.11.1}/quantui/app_history.py +12 -6
  12. {quantui-0.9.0 → quantui-0.11.1}/quantui/app_launcher.py +218 -5
  13. {quantui-0.9.0 → quantui-0.11.1}/quantui/app_measurement.py +18 -19
  14. {quantui-0.9.0 → quantui-0.11.1}/quantui/app_runflow.py +294 -98
  15. {quantui-0.9.0 → quantui-0.11.1}/quantui/app_slurm.py +84 -6
  16. quantui-0.11.1/quantui/app_structure_edit.py +403 -0
  17. quantui-0.11.1/quantui/app_viewer.py +183 -0
  18. {quantui-0.9.0 → quantui-0.11.1}/quantui/app_visualization.py +1091 -110
  19. {quantui-0.9.0 → quantui-0.11.1}/quantui/app_xyz_input.py +82 -10
  20. {quantui-0.9.0 → quantui-0.11.1}/quantui/backends/__init__.py +2 -3
  21. {quantui-0.9.0 → quantui-0.11.1}/quantui/backends/base.py +3 -3
  22. quantui-0.11.1/quantui/backends/batch_chain.py +120 -0
  23. quantui-0.11.1/quantui/backends/batch_input.py +295 -0
  24. quantui-0.11.1/quantui/backends/batch_status.py +213 -0
  25. {quantui-0.9.0 → quantui-0.11.1}/quantui/backends/cluster_config.py +90 -6
  26. {quantui-0.9.0 → quantui-0.11.1}/quantui/backends/dispatch.py +31 -9
  27. {quantui-0.9.0 → quantui-0.11.1}/quantui/backends/local.py +3 -3
  28. {quantui-0.9.0 → quantui-0.11.1}/quantui/backends/registry.py +6 -5
  29. quantui-0.11.1/quantui/backends/result_summary.py +146 -0
  30. {quantui-0.9.0 → quantui-0.11.1}/quantui/backends/slurm.py +166 -42
  31. {quantui-0.9.0 → quantui-0.11.1}/quantui/backends/slurm_ingest.py +43 -12
  32. {quantui-0.9.0 → quantui-0.11.1}/quantui/backends/slurm_utils.py +138 -63
  33. {quantui-0.9.0 → quantui-0.11.1}/quantui/backends/worker.py +614 -54
  34. {quantui-0.9.0 → quantui-0.11.1}/quantui/backends/worker_payload.py +116 -31
  35. quantui-0.11.1/quantui/batch_launcher.py +160 -0
  36. {quantui-0.9.0 → quantui-0.11.1}/quantui/calc_log.py +159 -77
  37. {quantui-0.9.0 → quantui-0.11.1}/quantui/calculator.py +104 -3
  38. quantui-0.11.1/quantui/checklist_widget.py +60 -0
  39. {quantui-0.9.0 → quantui-0.11.1}/quantui/checkpoint.py +17 -15
  40. {quantui-0.9.0 → quantui-0.11.1}/quantui/cli.py +360 -18
  41. {quantui-0.9.0 → quantui-0.11.1}/quantui/comparison.py +7 -2
  42. {quantui-0.9.0 → quantui-0.11.1}/quantui/config.py +125 -15
  43. {quantui-0.9.0 → quantui-0.11.1}/quantui/connectivity.py +51 -17
  44. quantui-0.11.1/quantui/data/launcher/quantui_batch.py +1791 -0
  45. {quantui-0.9.0 → quantui-0.11.1}/quantui/data/library/library.sqlite +0 -0
  46. {quantui-0.9.0 → quantui-0.11.1}/quantui/data/manifests/presets.json +60 -40
  47. {quantui-0.9.0 → quantui-0.11.1}/quantui/density_fitting.py +3 -3
  48. {quantui-0.9.0 → quantui-0.11.1}/quantui/descriptor_cards.py +13 -2
  49. quantui-0.11.1/quantui/downloads.py +90 -0
  50. {quantui-0.9.0 → quantui-0.11.1}/quantui/engines/base.py +4 -2
  51. {quantui-0.9.0 → quantui-0.11.1}/quantui/engines/pyscf_engine.py +4 -2
  52. {quantui-0.9.0 → quantui-0.11.1}/quantui/estimator_eval.py +1 -1
  53. {quantui-0.9.0 → quantui-0.11.1}/quantui/freq_calc.py +561 -139
  54. {quantui-0.9.0 → quantui-0.11.1}/quantui/freq_displacement_ids.py +4 -5
  55. {quantui-0.9.0 → quantui-0.11.1}/quantui/freq_ir_workers.py +21 -12
  56. {quantui-0.9.0 → quantui-0.11.1}/quantui/freq_raman_workers.py +7 -7
  57. {quantui-0.9.0 → quantui-0.11.1}/quantui/help_content.py +161 -1
  58. {quantui-0.9.0 → quantui-0.11.1}/quantui/inorganic_guards.py +1 -1
  59. {quantui-0.9.0 → quantui-0.11.1}/quantui/ir_plot.py +34 -7
  60. quantui-0.11.1/quantui/irc.py +431 -0
  61. {quantui-0.9.0 → quantui-0.11.1}/quantui/live_log.py +7 -5
  62. {quantui-0.9.0 → quantui-0.11.1}/quantui/log_utils.py +2 -2
  63. {quantui-0.9.0 → quantui-0.11.1}/quantui/measurement.py +1 -1
  64. {quantui-0.9.0 → quantui-0.11.1}/quantui/molecule.py +40 -4
  65. {quantui-0.9.0 → quantui-0.11.1}/quantui/molecule_library.py +28 -5
  66. {quantui-0.9.0 → quantui-0.11.1}/quantui/nmr_calc.py +7 -5
  67. {quantui-0.9.0 → quantui-0.11.1}/quantui/nmr_plot.py +20 -6
  68. {quantui-0.9.0 → quantui-0.11.1}/quantui/optimizer.py +94 -10
  69. {quantui-0.9.0 → quantui-0.11.1}/quantui/orbital_visualization.py +703 -39
  70. {quantui-0.9.0 → quantui-0.11.1}/quantui/pes_scan.py +4 -4
  71. {quantui-0.9.0 → quantui-0.11.1}/quantui/pes_scan_ui.py +4 -2
  72. {quantui-0.9.0 → quantui-0.11.1}/quantui/populations_overlay.py +84 -20
  73. {quantui-0.9.0 → quantui-0.11.1}/quantui/preopt.py +1 -1
  74. {quantui-0.9.0 → quantui-0.11.1}/quantui/progress.py +37 -1
  75. {quantui-0.9.0 → quantui-0.11.1}/quantui/pubchem.py +3 -3
  76. {quantui-0.9.0 → quantui-0.11.1}/quantui/raman_calc.py +8 -8
  77. {quantui-0.9.0 → quantui-0.11.1}/quantui/raman_plot.py +18 -7
  78. {quantui-0.9.0 → quantui-0.11.1}/quantui/reorganization_energy.py +110 -18
  79. {quantui-0.9.0 → quantui-0.11.1}/quantui/results_storage.py +39 -8
  80. {quantui-0.9.0 → quantui-0.11.1}/quantui/scf_robust.py +12 -14
  81. {quantui-0.9.0 → quantui-0.11.1}/quantui/session_calc.py +313 -165
  82. {quantui-0.9.0 → quantui-0.11.1}/quantui/spin_presets.py +1 -1
  83. quantui-0.11.1/quantui/structure_edit.py +272 -0
  84. quantui-0.11.1/quantui/structure_upload.py +234 -0
  85. quantui-0.11.1/quantui/symmetry.py +968 -0
  86. {quantui-0.9.0 → quantui-0.11.1}/quantui/tddft_calc.py +92 -11
  87. {quantui-0.9.0 → quantui-0.11.1}/quantui/theme.py +49 -4
  88. quantui-0.11.1/quantui/ts_search.py +391 -0
  89. {quantui-0.9.0 → quantui-0.11.1}/quantui/user_settings.py +37 -5
  90. {quantui-0.9.0 → quantui-0.11.1}/quantui/visualization_py3dmol.py +14 -5
  91. {quantui-0.9.0 → quantui-0.11.1}/quantui/viz_assets.py +109 -0
  92. {quantui-0.9.0 → quantui-0.11.1}/quantui/viz_backend_router.py +1 -1
  93. {quantui-0.9.0 → quantui-0.11.1}/quantui/xyz_input.py +5 -4
  94. {quantui-0.9.0 → quantui-0.11.1/quantui.egg-info}/PKG-INFO +76 -21
  95. {quantui-0.9.0 → quantui-0.11.1}/quantui.egg-info/SOURCES.txt +15 -0
  96. {quantui-0.9.0 → quantui-0.11.1}/quantui.egg-info/requires.txt +9 -4
  97. quantui-0.9.0/quantui/__init__.py +0 -311
  98. {quantui-0.9.0 → quantui-0.11.1}/LICENSE +0 -0
  99. {quantui-0.9.0 → quantui-0.11.1}/MANIFEST.in +0 -0
  100. {quantui-0.9.0 → quantui-0.11.1}/SECURITY.md +0 -0
  101. {quantui-0.9.0 → quantui-0.11.1}/quantui/analytics.py +0 -0
  102. {quantui-0.9.0 → quantui-0.11.1}/quantui/app_pes_pick.py +0 -0
  103. {quantui-0.9.0 → quantui-0.11.1}/quantui/ase_bridge.py +0 -0
  104. {quantui-0.9.0 → quantui-0.11.1}/quantui/backends/cluster_security.py +0 -0
  105. {quantui-0.9.0 → quantui-0.11.1}/quantui/backends/slurm_errors.py +0 -0
  106. {quantui-0.9.0 → quantui-0.11.1}/quantui/benchmarks.py +0 -0
  107. {quantui-0.9.0 → quantui-0.11.1}/quantui/c_stderr.py +0 -0
  108. {quantui-0.9.0 → quantui-0.11.1}/quantui/cactus.py +0 -0
  109. {quantui-0.9.0 → quantui-0.11.1}/quantui/cancellation.py +0 -0
  110. {quantui-0.9.0 → quantui-0.11.1}/quantui/data/js/3Dmol-min.js +0 -0
  111. {quantui-0.9.0 → quantui-0.11.1}/quantui/data/js/3Dmol-min.js.LICENSE.txt +0 -0
  112. {quantui-0.9.0 → quantui-0.11.1}/quantui/data/manifests/bulk_qm9.json +0 -0
  113. {quantui-0.9.0 → quantui-0.11.1}/quantui/data/manifests/curated.json +0 -0
  114. {quantui-0.9.0 → quantui-0.11.1}/quantui/data/manifests/inorganic.json +0 -0
  115. {quantui-0.9.0 → quantui-0.11.1}/quantui/engines/__init__.py +0 -0
  116. {quantui-0.9.0 → quantui-0.11.1}/quantui/engines/pyfock_engine.py +0 -0
  117. {quantui-0.9.0 → quantui-0.11.1}/quantui/gpu_offload.py +0 -0
  118. {quantui-0.9.0 → quantui-0.11.1}/quantui/issue_tracker.py +0 -0
  119. {quantui-0.9.0 → quantui-0.11.1}/quantui/mulliken_plot.py +0 -0
  120. {quantui-0.9.0 → quantui-0.11.1}/quantui/pyfock_gpu.py +0 -0
  121. {quantui-0.9.0 → quantui-0.11.1}/quantui/security.py +0 -0
  122. {quantui-0.9.0 → quantui-0.11.1}/quantui/structure_providers.py +0 -0
  123. {quantui-0.9.0 → quantui-0.11.1}/quantui/utils.py +0 -0
  124. {quantui-0.9.0 → quantui-0.11.1}/quantui/vib_cache.py +0 -0
  125. {quantui-0.9.0 → quantui-0.11.1}/quantui.egg-info/dependency_links.txt +0 -0
  126. {quantui-0.9.0 → quantui-0.11.1}/quantui.egg-info/entry_points.txt +0 -0
  127. {quantui-0.9.0 → quantui-0.11.1}/quantui.egg-info/top_level.txt +0 -0
  128. {quantui-0.9.0 → quantui-0.11.1}/setup.cfg +0 -0
@@ -7,6 +7,462 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.11.1] - 2026-11-02
11
+
12
+ ### Changed
13
+
14
+ - Documentation site: an "Open the Viewer" link in the Home sidebar and on
15
+ the home page, a two-column Features page, and shorter text throughout.
16
+
17
+ ### Fixed
18
+
19
+ - **IRC no longer ends both directions in the same minimum.** Sella's
20
+ iterative estimate of the starting Hessian could carry a spurious mode,
21
+ so from a transition state converged only to the force threshold the
22
+ first step went sideways and both directions fell into one valley. The
23
+ IRC now starts from PySCF's analytic Hessian, as the transition-state
24
+ search already does. If Sella's inner loop fails, the direction is
25
+ finished by mass-weighted steepest descent before a short-step BFGS;
26
+ if both ends still match, the verdict says so rather than reporting a
27
+ connection.
28
+ - Viewer installer builds use the `macos-15` runner (`macos-14` is retired).
29
+
30
+ ## [0.11.0] - 2026-11-01
31
+
32
+ ### Added
33
+
34
+ - **IRC calc type** (M-TS TS.3, engine Sella): follows the reaction path
35
+ downhill from a transition state in both directions, in mass-weighted
36
+ coordinates, to the two minima it connects. Pick the Transition State
37
+ result under *Start from*. The card gives the barrier from each side and
38
+ a verdict; the PES Scan panel plots energy against the reaction coordinate
39
+ (click a point to jump the Trajectory panel there); Trajectory plays
40
+ reactant → TS → product; History replays both. Steps of 0.2 Å·amu½ with
41
+ Sella's gamma at 0.4 (measured: 35–71 SCFs per direction where the
42
+ defaults stalled); if Sella's inner loop gives out near a minimum, that
43
+ direction is finished by minimizing and the card says so. PCM supported.
44
+ Also a batch job (`--calc irc`, usually `--from` a Transition State job;
45
+ no mid-path resume) in `quantui submit`, `quantui-batch` and the app's
46
+ SLURM path; `results` prints the barriers and verdict.
47
+ - **Full symmetry labels for D4h, D4, C4v and D2d** vibrational modes
48
+ (square-planar, square-pyramidal and allene-type molecules) instead of
49
+ their D2h/C2v/D2 subgroup labels. B1 and B2 follow the usual convention
50
+ (C2′ axes, or σv planes, through the ligands), so a square-planar AB4's
51
+ B1g is the in-plane stretch. Point-group detection for mode labels no
52
+ longer drops to a lower group at the loose tolerance (an exact square
53
+ pyramid was labelled C2v).
54
+ - **The Viewer draws the HOMO and LUMO** (M-VIEWER VW.7): when orbitals are
55
+ saved (app or batch job), the HOMO and LUMO, each spin for unrestricted
56
+ results, are also saved as gzipped cubes at the Isosurface panel's
57
+ default grid (about 0.4 MB each; `frontier_cubes/`). The desktop and
58
+ browser Viewer, which have no PySCF, draw those; for any other orbital,
59
+ density or ESP they say to open the result in the full QuantUI. Set
60
+ `QUANTUI_FRONTIER_CUBES=0` to skip them.
61
+ - **`quantui view` opens the last folder it showed** when started without
62
+ one (desktop shortcuts), instead of the home directory.
63
+ - **`quantui jobs`** (M-BATCH2 B2.9): your batch jobs, newest first, with
64
+ where each one is: waiting, running (with the worker's progress),
65
+ done or failed. With `squeue` on PATH it refreshes the job records from
66
+ the queue first; without it (an OnDemand session) it reads each job
67
+ folder. `--running` lists unfinished jobs, `--all` every job.
68
+ - **History lists batch jobs not finished yet** (B2.10): on app start and
69
+ on Refresh, jobs submitted from a terminal show their state and progress
70
+ from their job folders, since OnDemand has no `squeue`. A
71
+ terminal-submitted job's record is marked succeeded when its result is
72
+ saved to History.
73
+ - **Transition State as a batch job** (M-TS TS.5): `quantui submit`,
74
+ `quantui-batch submit --calc transition_state` and the app's SLURM path
75
+ run the same Sella search and frequency check as the window, PCM included.
76
+ A killed job resumes the search from its last step, never redoes a
77
+ finished search, and keeps the frequency check's finished displacements.
78
+ History shows the stationary point found with its search path;
79
+ `results` prints the verdict; `--from` a TS job starts from its saddle
80
+ point. A post-HF method is refused before the job queues. Both Apptainer
81
+ images now install the `[ts]` extra (Sella), which Transition State needs
82
+ on the cluster in the window as well.
83
+ - **Clarity and layout pass** (M-UIPOLISH, from a rendered-UI walk-through):
84
+ - Molecules open facing the camera in every viewer (principal axes), so
85
+ water no longer looks linear and the dipole arrow is visible.
86
+ - The library finds common names ("water", "ammonia", "benzene"); QM9
87
+ entries come after the curated ones and duplicates are listed once.
88
+ - Two-column layouts on wide screens: Calculate (molecule | setup + run),
89
+ Results (card | structure), and the Analysis viewer, Mulliken,
90
+ Vibrational and Orbital panels; they stack on narrow windows.
91
+ - One-line header with the toolbar, a one-line step indicator, the
92
+ "Calculation complete" links right under Run, and a shorter, resizable
93
+ log that hides internal bookkeeping lines.
94
+ - Analysis lists the panels that have data first; plots opened from a
95
+ collapsed panel fill their width; Raman follows the IR axis direction.
96
+ - UV-Vis shows vacuum-UV bands (the window started at 100 nm) and lists
97
+ the excited states; NMR groups equivalent nuclei and uses one
98
+ Atom | σ | δ table.
99
+ - Live and History result cards show the same rows; frequencies are
100
+ listed with their symmetry labels; formulas read NH3, not H3N.
101
+ - Compare uses checkboxes and renders its chart; History offers recent
102
+ results as links with the other filters folded away; Help and Report
103
+ Issue open as side drawers (Esc closes both).
104
+ - Shorter copy throughout, a 12 px minimum text size, clearer section
105
+ headings, neutral Report Issue / Exit / idle Cancel buttons.
106
+ - Fixed: the System Settings GPU row could stay at "checking…" forever.
107
+ - **Vibrational-mode symmetry labels** (M-SPECTRA2 SPC2.4) — after a Frequency
108
+ calculation each normal mode gets its irreducible representation: a *Sym.*
109
+ column and a Γvib caption in the Vibrational mode table (NH₃: 2A₁ + 2E), the
110
+ label in the mode dropdown, and a *Symmetry* line in the IR and Raman stick
111
+ hovers. Works for live results and History reloads (computed from the saved
112
+ displacements). Full-group labels for abelian groups, C3v, D3h, D3, D3d, D6h,
113
+ Td, Oh and linear molecules (σ/π); other groups (e.g. D4h) show labels in
114
+ PySCF's computational subgroup, said so in the caption.
115
+ `quantui.symmetry.label_mode_irreps()`.
116
+ - **Diffuse basis sets** — `6-31+G*`, `6-31++G**`, `aug-cc-pVDZ` and
117
+ `def2-SVPD` join the basis menu (each next to the set it extends), for
118
+ anions, radical anions and weakly bound species. Available with PySCF in the
119
+ app, `quantui submit` and `quantui-batch`; PyFock's menu is unchanged.
120
+ `6-31+G(d)` / `6-31++G(d,p)` are accepted as the same sets. The basis card
121
+ marks them *Diffuse*, the educational notes explain them and nudge an anion
122
+ on a non-diffuse basis toward one, and the basis-set help topic has a new
123
+ *Anions need diffuse functions* paragraph. SLURM memory factors and the time
124
+ estimator's basis-function table cover the new sets.
125
+ `config.DIFFUSE_BASIS_SETS` / `config.is_diffuse_basis()` list them.
126
+ - **`quantui results JOB_DIR`** — the `quantui-batch results` summary
127
+ (convergence, energy, imaginary modes, strongest IR bands, excited states,
128
+ NMR shifts) from inside the image. Both now also note a saddle-point
129
+ retry.
130
+ - **Site limits for batch jobs** — `QUANTUI_SLURM_MAX_MEMORY_GB`,
131
+ `QUANTUI_SLURM_ESTIMATE_MAX_MEMORY_GB` and `QUANTUI_SLURM_MAX_CORES` set the
132
+ hard limits and the automatic estimate's own memory ceiling (defaults
133
+ unchanged: 128 GB, 32 cores). Set them in the image environment before
134
+ `quantui install-launcher` so `quantui-batch` uses the same values.
135
+ - **Viewer mode (`quantui view [FOLDER]`)** — a lightweight QuantUI with only
136
+ the History and Analysis tabs, pointed at a results folder, needing no quantum
137
+ engine. `QuantUIApp(viewer=True, results_dir=...)` adds a results-folder bar
138
+ above the tabs; `quantui view` starts Voilà on a free `127.0.0.1` port and
139
+ opens the browser. Packaging for two delivery routes lives in
140
+ `packaging/viewer/` (unsigned conda-constructor desktop installers and a
141
+ Voici/Pyodide browser build), built by the new `viewer-builds` workflow.
142
+ - **QuantUI Viewer in the docs** — new *QuantUI Viewer* page
143
+ (`/viewer/`) with a link to the browser Viewer, which the Pages workflow now
144
+ builds and publishes at `/viewer/app/` on each release and docs change.
145
+ Publishing a release also attaches the three Viewer installers to it.
146
+ - **SLURM GPU and account settings** — `QUANTUI_SLURM_GRES`,
147
+ `QUANTUI_SLURM_QOS` and `QUANTUI_SLURM_ACCOUNT` add `#SBATCH --gres`,
148
+ `--qos` and `--account` lines to generated batch scripts (app, `quantui
149
+ submit` and `quantui-batch`). A GRES that asks for a GPU also turns on
150
+ `apptainer exec --nv`; `QUANTUI_SLURM_NV=1`/`0` overrides that.
151
+ - **Batch Geometry Opt results are complete** — a SLURM `geometry_opt`
152
+ result now records the optimized geometry (`final_molecule`), the final
153
+ SCF's dipole moment and Mulliken charges, so History and
154
+ `quantui-batch results` show them without a follow-up single point.
155
+ `--from` chaining reads the recorded geometry.
156
+
157
+ ### Changed
158
+
159
+ - **`quantui view` needs a per-run token.** It listened on 127.0.0.1 with
160
+ no authentication, so any local process or web page could start kernels
161
+ on its port; it now starts Voila with a random token and opens the URL
162
+ that carries it. A request without it gets a login page. (Standalone
163
+ Voila has no XSRF setting, so the `disable_check_xsrf` flag was never in
164
+ effect for the viewer; DEC-001's container setting is unchanged.)
165
+ - **Frequency results check the geometry** — every Frequency run now
166
+ computes the forces at the input geometry. When the largest force is above
167
+ the Geometry Opt threshold (0.05 eV/Å) the result card (live and History)
168
+ and the Analysis thermochemistry box warn that the geometry is not a
169
+ stationary point, so its frequencies and thermochemistry are not
170
+ meaningful, and say how to fix it. `FreqResult.max_force_ev_per_ang`;
171
+ saved as `spectra.ir.max_force_ev_per_ang`.
172
+ - **IR spectra run 4000 → 400 cm⁻¹ by default** (FTIR convention). An
173
+ **Axis** dropdown on the IR panel switches back to 400 → 4000; the choice
174
+ is remembered (`viz.ir_axis` in user settings). `plot_ir_spectrum()` gains
175
+ `descending=`.
176
+ - **Energy-level diagram hides core orbitals by default** — occupied
177
+ orbitals more than 50 eV below the HOMO (e.g. water's O 1s) no longer set
178
+ the Y range and squeeze the valence levels into a sliver; the subtitle says
179
+ how many are hidden and a **Show core orbitals** checkbox restores them.
180
+ The HOMO–LUMO gap label no longer overlaps the axis labels.
181
+ - **Dipole arrow convention** — the Mulliken panel says which end the arrow
182
+ head marks and offers both conventions (− → +, IUPAC/physics, default; or
183
+ + → −, the chemistry crossed arrow), remembered as `viz.dipole_arrow`.
184
+ - **Frequency card** — title reads "H2O · B3LYP/6-31G* (RKS)"; H and G are
185
+ shown with their thermal correction vs E in kJ/mol instead of an absolute
186
+ kJ/mol value.
187
+ - **Less duplication, tidier layout** — viewers no longer repeat the molecule
188
+ facts in a "Molecule Information" box; the launcher notebook drops its
189
+ duplicate "QuantUI" heading; result tables are compact and left-aligned;
190
+ the empty Calculate tab no longer reserves a blank viewer block.
191
+ - **Esc closes the Help panel** (as does its Close button).
192
+ - **Clearer controls** — no more truncated labels or "?.." buttons; PES atom
193
+ chips read "O1"; XYZ table headers line up; a **Done** button closes the
194
+ molecule editor; the Help panel has a **Close** button; System Settings
195
+ groups all settings in one card and says PlotlyMol; the activity indicator
196
+ is a neutral status chip; History, Compare and the Analysis heading show
197
+ readable times ("2026-10-25 04:31").
198
+ - **Context-aware extras** — the spin-state helper appears only for molecules
199
+ with a transition metal; "Use mode → new Frequency calc" only when there
200
+ are imaginary modes; Analysis panels that don't apply say what they need in
201
+ their title; dark themes give 3D viewers the panel colour (also in PNG
202
+ exports) instead of black.
203
+ - `import quantui` no longer loads numpy, RDKit, ASE, Plotly, IPython or
204
+ requests; every public name is resolved when first used. `quantui`
205
+ command-line tools and the batch worker start in a fraction of the time,
206
+ which matters on cluster login nodes (slow shared filesystems, per-user
207
+ thread limits).
208
+
209
+ ### Fixed
210
+
211
+ - **"Copy path" in the browser viewer** no longer raises: Pyodide cannot
212
+ start the thread that resets the label, so the label just stays.
213
+ - **`quantui-batch check` prints a fix hint only under a failed or warning
214
+ line.** Passing lines showed their hint too (`[ok ] image …` followed by
215
+ "ask your instructor: the course image is missing or unreadable"), which
216
+ read as an error to students.
217
+ - **Generate Isosurface works again for molecular orbitals** — it failed for
218
+ every MO with `unexpected keyword argument 'esp_range'` since the ESP-map
219
+ release. The orbital gallery was not affected.
220
+ - **Edit Structure stays available after a molecule loads** — loading or
221
+ changing a molecule rebuilt the Calculate panel without it.
222
+ - **Mulliken viewer** opens charge-coloured with the dipole arrow when those
223
+ boxes are ticked, instead of only after a box was toggled.
224
+ - **Sliders are visible on every theme** (ipywidgets 8 sliders were unstyled:
225
+ no visible track, and a white handle on the Light theme), and the selected
226
+ option of toggle-button groups and History filter chips is now highlighted.
227
+ - The QM pre-optimization checkbox no longer keeps the PES Scan wording
228
+ ("…before scan") after switching to another calculation type.
229
+ - The Files tab re-lists its folder when opened, so newly saved results show
230
+ without clicking Refresh.
231
+ - PES Scan: suggested Start/Stop values are rounded (0.001 Å / 0.1°) and the
232
+ unit label sits after Stop rather than after Points.
233
+ - **Time-estimate basis-function counts** — the per-element table behind
234
+ `calc_log.count_basis_functions` had drifted from PySCF for 75 entries
235
+ (every element in def2-TZVP, e.g. H 14 instead of 6; Li/Be and Na–Ar in
236
+ the 6-31G*, cc-pV*Z and def2-SVP rows; Al–Ar in 3-21G/6-31G). It is now
237
+ generated from PySCF's AO counts and a test checks every entry. History
238
+ records logged before this keep their old `n_basis`, so estimates for
239
+ def2-TZVP and second-row/heavier molecules settle as new runs are logged.
240
+ - **CPU image no longer overrides a caller's `QUANTUI_RESULTS_DIR` /
241
+ `QUANTUI_FREQ_PARALLEL`** (M-BATCH2 B2.12). `apptainer/quantui.def`
242
+ hard-exported both, so a site module or job script setting either was
243
+ silently clobbered inside the container. Both are now defaults
244
+ (`${VAR:-default}`), matching `quantui-gpu.def`.
245
+
246
+ - History's **Refresh** button also saves batch jobs that finished since
247
+ the app started; before, they appeared only after a restart or a Cluster
248
+ Jobs refresh.
249
+ - The batch resource estimate knows def2-SVP, def2-TZVP and LANL2DZ (they
250
+ used a generic factor), treats `6-31G(d)` / `6-31G(d,p)` like `6-31G*` /
251
+ `6-31G**`, and adds walltime for TD-DFT runs with more than 10 states and
252
+ PES scans with more than 10 points.
253
+ - Batch `live.log` files no longer contain a copy of QuantUI's worker
254
+ source. PySCF writes the running script into its output at the log level
255
+ QuantUI uses; in a batch job that script is the worker (~900 lines per
256
+ calculation). PySCF's version and input summary are still logged.
257
+ - Batch job and folder names write Pople bases the usual way: `6-31G*` →
258
+ `6-31Gd`, `6-31G(d,p)` → `6-31Gdp`, `6-31+G*` → `6-31pGd` (was
259
+ `6-31Gx`, `6-31Gxdxpx`, …).
260
+ - `quantui submit` and `quantui-batch` refuse an XYZ file whose first line
261
+ gives a different atom count from the atoms listed (a cut-off or padded
262
+ file). The app still only warns, where you see the structure.
263
+ - `quantui submit` (and Resubmit) syncs job states with the SLURM queue before
264
+ checking the concurrent-job limit. With no app open, finished jobs stayed
265
+ "submitted" in the registry and kept counting, so after two submissions
266
+ every further one was refused.
267
+ - Generated SLURM scripts ask for one task with N CPUs
268
+ (`--ntasks=1 --cpus-per-task=N`) instead of N tasks, which is what the
269
+ single multi-threaded worker uses; a `SLURM_CPUS_PER_TASK` inherited from
270
+ the submitting allocation no longer sets the thread count.
271
+ - `apptainer exec --nv` is no longer used for CPU jobs, and the worker runs
272
+ the batch image's own `python` instead of the submitting process's
273
+ interpreter path, which need not exist in that image.
274
+ - SLURM jobs resume again after a resubmission. Since job folders got one
275
+ attempt folder per run, the checkpoint and the cached pre-opt geometry
276
+ were kept inside the attempt folder, which the next attempt never sees,
277
+ so killed geometry optimizations, PES scans and frequency runs restarted
278
+ from scratch. Both now live in the job folder.
279
+ - The geometry optimization before a Frequency calculation (app and batch)
280
+ now converges to 0.01 eV/Å instead of 0.05. Residual forces at 0.05 left
281
+ soft modes such as methyl rotors wrong, or imaginary (CHEM-3200 Lab 4).
282
+ Plain Geometry Opt and the pre-opt for other calc types are unchanged.
283
+ - When that pre-optimized Frequency run still finds an imaginary mode below
284
+ 20i cm⁻¹ (usually a methyl or other rotor stuck at its eclipsed saddle
285
+ point), QuantUI displaces along the mode, re-optimizes and repeats the
286
+ frequencies once (app and batch). The result card and `result.json`
287
+ (`spectra.ir.imaginary_mode_retry`) say what was done; a mode still
288
+ imaginary after the retry is reported, not retried again.
289
+ - **Viewer installers: the shortcut opened and closed a console without
290
+ starting anything.** `quantui view` looked for the `voila` command on
291
+ `PATH`, which a shortcut launch of an unactivated install does not set; it
292
+ printed "Voilà is not installed or not on PATH" and exited. It now runs
293
+ Voilà as `python -m voila` from its own interpreter and puts the install's
294
+ folders on `PATH` for the server. The Windows shortcut runs through
295
+ `cmd /c ... || pause`, so any future failure stays on screen. Stopping
296
+ `quantui view` now stops Voilà too, instead of leaving it serving. The
297
+ installer CI smoke test starts the viewer the way a shortcut does and
298
+ fetches a page (it previously only ran `quantui view --help`).
299
+
300
+ - History → "View Results" / "View Analysis" navigated by fixed tab index, so
301
+ with the Cluster Jobs tab visible they landed one tab early. They now look
302
+ the tab up by name.
303
+ - Background renders (vibrational animation, isosurface, export) and the
304
+ activity-light timer fall back to running inline when threads are
305
+ unavailable instead of leaving the panel stuck.
306
+
307
+ ## [0.10.0] - 2026-10-03
308
+
309
+ ### Added
310
+
311
+ - **Upload structure files** — new **Upload File** tab (Calculate → Molecule
312
+ Input) and **Load as molecule** on the Files tab: XYZ (last frame), MOL,
313
+ SDF, MOL2, PDB, CIF, Gaussian `.gjf`/`.com` and `.log`/`.out`. Charge and
314
+ multiplicity are read from the file when it records them; 2-D MOL/SDF
315
+ drawings are embedded in 3-D.
316
+ - **Download to your computer** — every export (structure files, script,
317
+ bundle, cubes, PNGs, plots, CSV, animations) now offers a browser download
318
+ link, and the Files tab has a **Download** button. Works on remote
319
+ Voilà/OnDemand sessions; files over 25 MB get a notice instead.
320
+ - **Implicit solvent for optimizations, frequencies and TD-DFT** — Geometry
321
+ Opt is solvated at every step; Frequency uses PySCF's PCM Hessian and
322
+ solvated IR displacements (Raman is skipped in solvent); TD-DFT uses an
323
+ equilibrium ground state and non-equilibrium excitations with each
324
+ solvent's own optical dielectric. Also in SLURM batch jobs.
325
+ - **Point groups and orbital symmetry labels** — the molecule summary and
326
+ result cards show the point group (0.01 Å tolerance, with a "nearly X"
327
+ hint); the orbital energy diagram labels orbitals textbook-style
328
+ (1a₁, 2a₁, 1b₂, 3a₁, 1b₁ for water; σ/π for linear molecules; C₃ᵥ labels
329
+ for NH₃).
330
+ - **Density, spin-density and ESP surfaces** — the Isosurface panel draws the
331
+ electron density, the spin density (α − β) and the electrostatic potential
332
+ mapped on the density surface (red = negative, blue = positive, with a
333
+ colour bar), and α/β orbitals for unrestricted results.
334
+ - **Vibration viewer** — displacement arrows, an amplitude slider and a table
335
+ of every mode with IR intensity and Raman activity.
336
+ - **Thermochemistry at any temperature and pressure** — recomputed from the
337
+ stored frequencies (no new calculation), with U, H, S, G, Cv, Cp and the
338
+ rotational symmetry number.
339
+ - **Edit Structure** — set a bond length, angle or dihedral to a value,
340
+ delete atoms, add a hydrogen, change an element, undo; pick atoms by
341
+ clicking the viewer. **Freeze atoms** for a constrained Geometry Opt.
342
+ - **Orbital gallery** — the Isosurface panel's **Orbital gallery** button
343
+ shows the orbitals around the HOMO–LUMO gap (2, 3 or 4 on each side) as
344
+ small viewers that rotate together, each labelled with its symmetry and
345
+ energy; follows the α/β choice for unrestricted results.
346
+ - **Transition State calc type** — searches for the saddle point near the
347
+ input geometry with Sella (starting from the analytic Hessian, with the
348
+ same PySCF settings as an optimization: PCM, density fitting, D3, GPU, SCF
349
+ rescue), then runs a frequency calculation and says plainly whether it
350
+ found a transition state (exactly one imaginary frequency), a minimum, or
351
+ a higher-order saddle point. Results open on the Vibrational panel to
352
+ animate the imaginary mode, plus IR, search trajectory, orbitals and
353
+ populations. Needs the optional extra: `pip install "quantui[ts]"`.
354
+ Local runs only for now (not SLURM batch).
355
+ - **Populations and Isosurface for Frequency and TD-DFT results** — both
356
+ record the reference SCF's Mulliken charges, dipole and orbitals (both spin
357
+ channels for UHF/UKS), so the Populations, Isosurface and (TD-DFT) Energies
358
+ panels fill for them too, locally and from SLURM. Frequency Molden files
359
+ now include the orbitals.
360
+ - **⟨S²⟩ for open-shell results** — single points record and show ⟨S²⟩
361
+ next to the ideal S(S+1), flagged when off by more than 10 % (spin
362
+ contamination). Reorganization-energy results record it at all four
363
+ points of each channel (`s2_*` fields in `result.json`), so a
364
+ spin-contaminated ion SCF can be filtered out of a λ dataset.
365
+ - **Submit from a login node with `quantui-batch`** — a standard-library
366
+ Python 3.6+ launcher for SSH users. It never starts the image or imports
367
+ QuantUI on the login node: it writes the same job folder as
368
+ `SlurmBackend.prepare()` (constants copied from QuantUI at install time,
369
+ logic held equal by tests) and calls `sbatch`; the calculation runs in the
370
+ image on a compute node. Install once per image, e.g.
371
+ `apptainer exec IMAGE quantui install-launcher /shared/bin`.
372
+ `quantui-batch submit mol.xyz --calc frequency --method B3LYP --basis def2-SVP`;
373
+ `status`, `log`, `rerun` (e.g. `--mem=64G` after running out of memory),
374
+ `cancel`, `estimate` and `path` follow it. At most
375
+ `QUANTUI_MAX_CONCURRENT_JOBS` (default 2) QuantUI jobs may be queued or
376
+ running per user, counted from the real queue.
377
+ - **`quantui-batch` workflow commands** — `--preset NAME` (shared
378
+ `presets.json` beside the launcher, plus per-user presets); `--from JOB`
379
+ starts from another job's optimized geometry, waiting on it with an
380
+ `afterok` dependency if it is still running (the worker loads the geometry
381
+ at run time, `quantui/backends/batch_chain.py`); `--queue-rest` lines jobs
382
+ up behind the user's running ones instead of refusing them; a duplicate
383
+ guard (`--again` to override); `rerun --more-memory` / `--more-time`;
384
+ `results JOB` (energy, convergence, imaginary modes, strongest IR bands,
385
+ excited states, shifts); `presets`; and `check` (python, image, Slurm
386
+ commands, job folders and free space, presets).
387
+ - **Every QuantUI batch job is tagged `#SBATCH --comment=quantui`**, so an
388
+ operator can list all of them with `squeue -o "%k"`.
389
+ - **`quantui submit` accepts `.xyz` files** with `--calc`, `--method`,
390
+ `--basis`, `--charge`, `--mult`, `--solvent`, `--preopt` and repeatable
391
+ `--option KEY=VALUE`; an impossible charge/multiplicity is refused before
392
+ anything is queued. The same flags override a request JSON's values.
393
+ - **`quantui submit --prepare-only`** writes the job folder (`request.json` +
394
+ `submit.slurm`) without calling `sbatch` and prints the script path. Its
395
+ registry record has the new non-active status `prepared`.
396
+
397
+ ### Changed
398
+
399
+ - **The GPU image builds from the working tree, like the CPU image** —
400
+ `quantui-gpu.def` copies the same `%files` allowlist as `quantui.def` and
401
+ installs it editable, instead of a pinned PyPI release, so a GPU node runs
402
+ the code that was just tested. `build-gpu.sh` records the commit
403
+ (`git describe`) in the image's `QuantUICommit` label and
404
+ `/opt/build-info/quantui-commit.txt`; its `--version` flag is gone — check
405
+ out a release tag to build that release.
406
+ - **Finished batch attempts reach History when the app starts**, even where
407
+ SLURM is unavailable (e.g. an OnDemand session), so jobs submitted from a
408
+ terminal show up without opening the Cluster Jobs tab.
409
+
410
+ ### Fixed
411
+
412
+ - **PBE-D3 now includes D3** — it needed `pyscf.dftd3`, which no QuantUI
413
+ environment installed, so PBE-D3 ran as plain PBE (with a warning). D3
414
+ (zero damping) is now applied through PySCF's built-in dispersion
415
+ (`pyscf-dispersion`, added to the `[pyscf]` extra, the conda environment
416
+ and the CPU image), including in gradients and Hessians.
417
+ - **Rotational symmetry number** — thermochemistry detected symmetry at
418
+ PySCF's strict tolerance, so slightly unsymmetric geometries (any
419
+ optimized water or ammonia) used σ = 1, overstating the entropy by R ln σ.
420
+ Symmetric molecules' S and G change.
421
+ - **`quantui submit --depends-on`** accepts a request id or a SLURM job id
422
+ and resolves it; it used to write the request id into
423
+ `--dependency=afterok:` and validate nothing.
424
+ - **"Geometry optimization before the calculation" on SLURM** — Single
425
+ Point and NMR batch jobs ignored the checkbox (the local run honoured it).
426
+ - **Mode-displaced Frequency seeds are re-optimized** — picking "displace
427
+ along mode" as the Frequency seed disabled the pre-optimization, so the
428
+ frequencies were computed at a geometry that is not a stationary point.
429
+ The checkbox is now ticked for that seed (left on, user can untick).
430
+ - **Reorganization Energy shows its optimizer settings** — the run used the
431
+ max-force and max-steps fields while they were hidden, so values left over
432
+ from Geometry Opt or PES Scan applied unseen.
433
+ - **No placeholder Raman spectrum** — when Raman activities were not
434
+ computed (PCM run, or `pyscf-properties` missing), the Raman panel drew
435
+ every mode at the same height. It now says why there is no spectrum.
436
+ - **Disconnected structures are flagged for every source** — the molecule
437
+ summary notes separate fragments for pasted, library, uploaded, edited and
438
+ History structures, not only Online Search results.
439
+ - **Pasting a multi-frame XYZ** says what it is and how to load it, instead
440
+ of "Line N: not enough values".
441
+ - **Export Script follows the calculation** — it used to write a gas-phase
442
+ single point whatever was set up. It now applies the selected PCM solvent
443
+ and density fitting, adds the Hessian + thermochemistry for Frequency and
444
+ the excited states (with the solvent's optical dielectric) for TD-DFT, and
445
+ says plainly when it covers only the SCF (Geometry Opt, NMR, PES Scan,
446
+ Reorganization Energy).
447
+ - **CPU image: NMR and analytical Raman** — the image installed QuantUI
448
+ without the `[pyscf]` extra, so `pyscf-properties` was missing. It now
449
+ installs the extra, and the build fails if `pyscf.prop.nmr` or
450
+ `pyscf.dispersion` cannot be imported.
451
+ - **Solvent names are case-insensitive**; an unknown solvent is an error.
452
+ A request with `"water"` used to run in the gas phase.
453
+ - **Export Script** writes into the result folder instead of the server's
454
+ working directory.
455
+
456
+ - **Solvated batch requests the worker cannot run are refused up front** —
457
+ `quantui submit` and `quantui-batch` reject an unknown solvent, and a
458
+ solvent on a calc type the batch worker runs gas-phase only (e.g. `nmr`),
459
+ instead of letting the job queue and then fail. The supported set now
460
+ lives in one place (`batch_input.SOLVENT_CALC_TYPES`).
461
+ - **SLURM memory estimate for transition-metal complexes** —
462
+ `estimate_slurm_resources()` used a short element table without Mn, Co,
463
+ Ni, Mo and most other metals, so a metal counted as 0 electrons and the
464
+ memory estimate came out low. It now uses the full table.
465
+
10
466
  ## [0.9.0] - 2026-09-26
11
467
 
12
468
  ### Added
@@ -934,7 +1390,10 @@ Initial public scaffolding of the QuantUI package: `quantui` package with
934
1390
  `calculator.py`, basic notebook launcher, Apptainer container definition,
935
1391
  MIT license, and project metadata.
936
1392
 
937
- [Unreleased]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.9.0...HEAD
1393
+ [Unreleased]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.11.1...HEAD
1394
+ [0.11.1]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.11.0...v0.11.1
1395
+ [0.11.0]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.10.0...v0.11.0
1396
+ [0.10.0]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.9.0...v0.10.0
938
1397
  [0.9.0]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.8.2...v0.9.0
939
1398
  [0.8.2]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.8.1...v0.8.2
940
1399
  [0.8.1]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.8.0...v0.8.1