quantui 0.5.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 (70) hide show
  1. quantui-0.5.1/CHANGELOG.md +494 -0
  2. quantui-0.5.1/LICENSE +21 -0
  3. quantui-0.5.1/MANIFEST.in +39 -0
  4. quantui-0.5.1/PKG-INFO +533 -0
  5. quantui-0.5.1/README.md +442 -0
  6. quantui-0.5.1/SECURITY.md +62 -0
  7. quantui-0.5.1/pyproject.toml +307 -0
  8. quantui-0.5.1/quantui/__init__.py +311 -0
  9. quantui-0.5.1/quantui/analytics.py +609 -0
  10. quantui-0.5.1/quantui/app.py +5650 -0
  11. quantui-0.5.1/quantui/app_analysis.py +662 -0
  12. quantui-0.5.1/quantui/app_builders.py +2465 -0
  13. quantui-0.5.1/quantui/app_exports.py +194 -0
  14. quantui-0.5.1/quantui/app_formatters.py +493 -0
  15. quantui-0.5.1/quantui/app_history.py +624 -0
  16. quantui-0.5.1/quantui/app_runflow.py +1544 -0
  17. quantui-0.5.1/quantui/app_visualization.py +2620 -0
  18. quantui-0.5.1/quantui/ase_bridge.py +236 -0
  19. quantui-0.5.1/quantui/benchmarks.py +1543 -0
  20. quantui-0.5.1/quantui/c_stderr.py +124 -0
  21. quantui-0.5.1/quantui/cactus.py +88 -0
  22. quantui-0.5.1/quantui/calc_log.py +1116 -0
  23. quantui-0.5.1/quantui/calculator.py +204 -0
  24. quantui-0.5.1/quantui/cancellation.py +88 -0
  25. quantui-0.5.1/quantui/cli.py +288 -0
  26. quantui-0.5.1/quantui/comparison.py +306 -0
  27. quantui-0.5.1/quantui/config.py +725 -0
  28. quantui-0.5.1/quantui/data/js/3Dmol-min.js +2 -0
  29. quantui-0.5.1/quantui/data/js/3Dmol-min.js.LICENSE.txt +5 -0
  30. quantui-0.5.1/quantui/data/library/library.sqlite +0 -0
  31. quantui-0.5.1/quantui/data/manifests/bulk_qm9.json +1 -0
  32. quantui-0.5.1/quantui/data/manifests/curated.json +15482 -0
  33. quantui-0.5.1/quantui/data/manifests/presets.json +816 -0
  34. quantui-0.5.1/quantui/descriptor_cards.py +186 -0
  35. quantui-0.5.1/quantui/freq_calc.py +712 -0
  36. quantui-0.5.1/quantui/freq_ir_workers.py +229 -0
  37. quantui-0.5.1/quantui/gpu_offload.py +278 -0
  38. quantui-0.5.1/quantui/help_content.py +474 -0
  39. quantui-0.5.1/quantui/ir_plot.py +130 -0
  40. quantui-0.5.1/quantui/issue_tracker.py +170 -0
  41. quantui-0.5.1/quantui/live_log.py +387 -0
  42. quantui-0.5.1/quantui/log_utils.py +492 -0
  43. quantui-0.5.1/quantui/molecule.py +577 -0
  44. quantui-0.5.1/quantui/molecule_library.py +433 -0
  45. quantui-0.5.1/quantui/nmr_calc.py +437 -0
  46. quantui-0.5.1/quantui/optimizer.py +670 -0
  47. quantui-0.5.1/quantui/orbital_visualization.py +1102 -0
  48. quantui-0.5.1/quantui/pes_scan.py +420 -0
  49. quantui-0.5.1/quantui/preopt.py +355 -0
  50. quantui-0.5.1/quantui/progress.py +111 -0
  51. quantui-0.5.1/quantui/pubchem.py +1157 -0
  52. quantui-0.5.1/quantui/reorganization_energy.py +435 -0
  53. quantui-0.5.1/quantui/results_storage.py +902 -0
  54. quantui-0.5.1/quantui/security.py +14 -0
  55. quantui-0.5.1/quantui/session_calc.py +622 -0
  56. quantui-0.5.1/quantui/structure_providers.py +277 -0
  57. quantui-0.5.1/quantui/tddft_calc.py +307 -0
  58. quantui-0.5.1/quantui/user_settings.py +238 -0
  59. quantui-0.5.1/quantui/utils.py +287 -0
  60. quantui-0.5.1/quantui/vib_cache.py +247 -0
  61. quantui-0.5.1/quantui/visualization_py3dmol.py +593 -0
  62. quantui-0.5.1/quantui/viz_assets.py +101 -0
  63. quantui-0.5.1/quantui/viz_backend_router.py +243 -0
  64. quantui-0.5.1/quantui.egg-info/PKG-INFO +533 -0
  65. quantui-0.5.1/quantui.egg-info/SOURCES.txt +68 -0
  66. quantui-0.5.1/quantui.egg-info/dependency_links.txt +1 -0
  67. quantui-0.5.1/quantui.egg-info/entry_points.txt +2 -0
  68. quantui-0.5.1/quantui.egg-info/requires.txt +50 -0
  69. quantui-0.5.1/quantui.egg-info/top_level.txt +1 -0
  70. quantui-0.5.1/setup.cfg +4 -0
@@ -0,0 +1,494 @@
1
+ # Changelog
2
+
3
+ All notable changes to QuantUI are documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.5.1] - 2026-07-31
11
+
12
+ ### Fixed
13
+
14
+ - **The "Geometry optimization before calculation" checkbox no longer gets
15
+ stuck disabled.** Selecting a seed geometry on Frequency or UV-Vis disables
16
+ that checkbox (a seed is already an optimised geometry, so re-optimising
17
+ first would be redundant) — but switching to a different calculation type
18
+ afterwards used to leave it disabled with no way to re-enable it short of
19
+ going back and clearing the seed selection.
20
+ - **The Geometry Opt seed dropdown now updates when you change molecules
21
+ while already on that panel.** It previously only refreshed when you
22
+ switched *into* the Geometry Opt calculation type, so loading a new
23
+ molecule without leaving the panel could leave it listing matches for the
24
+ wrong molecule.
25
+
26
+ ### Changed
27
+
28
+ - **Internal cleanup:** the Geometry Opt / Frequency / UV-Vis seed-geometry
29
+ dropdowns, refresh buttons, and status notes are now one shared widget group
30
+ instead of three near-identical copies. No user-visible change — the same
31
+ dropdown, filtering, and messages appear on each calculation type as before.
32
+
33
+ ## [0.5.0] - 2026-07-31
34
+
35
+ First release published to **PyPI** — `pip install quantui`.
36
+
37
+ ### Added
38
+
39
+ - **Seed geometry for Geometry Optimization runs** — a run can now start from
40
+ the final geometry of a previous optimization instead of the current molecule,
41
+ which makes the standard "optimize at a cheap level of theory, then refine at
42
+ a higher one" workflow a single dropdown choice. Frequency and UV-Vis already
43
+ supported this; Geometry Opt now matches them.
44
+ - **A "still working" heartbeat in the live log.** Long silent phases — the
45
+ TD-DFT excited-state solve most of all — could leave the output log unchanged
46
+ for minutes while the calculation was running normally, which reads as a hang.
47
+ The log now reports `… still working — <stage> · <elapsed>` whenever it has
48
+ been quiet for 25 seconds. The saved `pyscf.log` is unaffected; it stays a
49
+ faithful record of the calculation's own output.
50
+ - **Basis-set names now show their alternate notation.** `6-31G*` and `6-31G(d)`
51
+ are the same basis set written two ways, and nothing in the UI said so. The
52
+ basis card now notes the equivalent spelling, and the basis-set help topic
53
+ explains the star/parenthesis convention, the `+`/`++` diffuse markers and
54
+ when anions need them, and why Dunning sets (`cc-pVDZ`) have no star at all.
55
+ - **The launcher terminal now prints the QuantUI wordmark** instead of two bare
56
+ lines of text.
57
+ - **Reorganization energy (Marcus 4-point)** — a new "Reorganization Energy"
58
+ calculation type that computes the internal reorganization energy λ for hole
59
+ (cation) and/or electron (anion) charge transfer. It optimizes the neutral and
60
+ ion geometries and evaluates the four single-point energies of the 4-point
61
+ scheme (λ = [E_ion(R_neutral) − E_ion(R_ion)] + [E_neutral(R_ion) −
62
+ E_neutral(R_neutral)]), reporting λ, its λ₁ (ion) and λ₂ (neutral) relaxation
63
+ components, in eV and kcal/mol. `mode="both"` shares the neutral optimization
64
+ across both channels. Open-shell HF ions are automatically promoted to UHF.
65
+ - **One-click "Calc. Reorganization Energy" button** — sets the calculation type
66
+ to Reorganization Energy, defaults the channel to both hole + electron, and
67
+ launches the run in a single click.
68
+ - **GPU offload can now be switched off from the UI** — Status tab → Settings →
69
+ "Use GPU when available". The preference persists across launches. This exists
70
+ because GPU offload is not always faster: quantum-chemistry SCF is
71
+ double-precision throughout, and consumer/workstation GPUs gate FP64 to roughly
72
+ 1/32–1/64 of their FP32 rate, so offload on such a card can be *slower* than a
73
+ many-core CPU. `QUANTUI_DISABLE_GPU=1` still overrides the setting for scripted
74
+ runs.
75
+ - **A warning when a detected GPU is unlikely to help.** `quantui gpu check` and
76
+ the Status tab now flag consumer-class devices with a note that double
77
+ precision is weak on them and offload may be slower than CPU, instead of
78
+ presenting any detected CUDA device as free speed.
79
+
80
+ ### Changed
81
+
82
+ - **The live calculation log no longer snaps back to the bottom while a run is
83
+ in progress**, so you can scroll up and read earlier output mid-calculation.
84
+ It still follows new output automatically when you are at the bottom. The log
85
+ is now a container QuantUI owns and appends to, rather than a widget that
86
+ rebuilt itself on every line.
87
+ - **No pre-optimization preview when the geometry barely moves.** Previously a
88
+ relaxation that changed essentially nothing still opened an animation pane and
89
+ a Keep/Revert choice between two effectively identical structures. Below
90
+ 0.05 Å RMS displacement QuantUI now just reports the number and proceeds with
91
+ your geometry.
92
+ - **All launcher scripts moved into a `launchers/` folder** to declutter the repo
93
+ root. Behaviour is unchanged — each launcher now resolves the repo root as its
94
+ parent directory. `launchers/launch-app.bat` still finds `quantui.sif` next to
95
+ itself (student download) or in the repo root (dev build). Docs and shortcuts
96
+ that referenced the old top-level paths were updated.
97
+ - **Apptainer container now builds on `condaforge/miniforge3` with the `mamba`
98
+ (libmamba) solver.** The previous `continuumio/miniconda3` base used conda's
99
+ classic solver, which could hang for hours resolving the PySCF + RDKit +
100
+ JupyterLab dependency set. The build now installs from conda-forge only
101
+ (`--override-channels`, strict channel priority), which resolves in minutes and
102
+ avoids the base image's implicit `defaults` channel. No change to the shipped
103
+ package set or runtime behavior.
104
+
105
+ ### Fixed
106
+
107
+ - **The live log and run header render in a fixed-width font again.** A
108
+ system-font rule was applying to the log, which garbled the ASCII wordmark and
109
+ pushed the run header's `Label : value` columns out of alignment.
110
+ - **`quantui gpu check` no longer reports a broken CUDA install as "gpu4pyscf not
111
+ installed".** `ModuleNotFoundError` is a subclass of `ImportError`, so catching
112
+ the latter conflated "the package is absent" with "the package is present but
113
+ its CUDA libraries are missing" — the second case was reported as the first,
114
+ sending users back to an install step they had already completed. The two are
115
+ now distinguished, the underlying exception is included in the message (e.g.
116
+ the missing `libnvJitLink.so`), and both cases are logged. The reason string
117
+ now comes from the detection probe itself rather than being re-derived by the
118
+ CLI, so the message can no longer contradict what the run dispatcher decided.
119
+ - **Exit is now a two-stage confirmation, so one click can no longer tear down an
120
+ HPC allocation.** Exit shuts the server down by sending `SIGTERM` to the parent
121
+ process. On a laptop that parent is just Voilà, but on a cluster interactive
122
+ session (e.g. NCShare) that parent process *is* the job — so a single stray
123
+ click destroyed the entire allocation. The first click now only arms the
124
+ shutdown: Exit re-labels to "Confirm shutdown" and an inline warning plus a
125
+ Cancel button appear. Only a second click runs the shutdown, which is otherwise
126
+ unchanged. An armed Exit auto-reverts after 15 seconds so a stray click doesn't
127
+ leave the button primed.
128
+
129
+ ## [0.4.1] - 2026-07-16
130
+
131
+ Bug-fix and hardening release from a full repository audit. No new features and
132
+ no breaking changes — it fixes correctness bugs across orbital isosurfaces,
133
+ Molden export, the XYZ parser, NMR references, PES scans, and IR intensities,
134
+ plus a range of edge-case, packaging, and hygiene issues found by reading the
135
+ codebase end to end.
136
+
137
+ ### Added
138
+
139
+ - Single-atom molecules (e.g. a lone He or Ne atom) are now accepted as XYZ input
140
+ and run end to end — atomic calculations are legitimate targets.
141
+
142
+ ### Changed
143
+
144
+ - **Python 3.9 is now covered by CI.** The minimum supported version was
145
+ previously claimed but untested; adding it surfaced and fixed real
146
+ geometry-optimization and frequency failures on the older ASE that resolves for
147
+ Python 3.9.
148
+ - **Faster `quantui` CLI startup** — the command-line tool no longer imports the
149
+ full notebook/GUI stack (ipywidgets, IPython, the app module) just to tail a
150
+ log.
151
+ - **No more logging hijack** — importing `quantui` no longer reconfigures the
152
+ root logger, so it won't override or duplicate logging in a host application or
153
+ notebook.
154
+ - **Faster time estimates over long sessions** — the performance log is cached and
155
+ re-read only when it changes, instead of being fully parsed on every UI update.
156
+
157
+ ### Fixed
158
+
159
+ - **Orbital isosurfaces for charged and open-shell molecules** — the isosurface
160
+ viewer previously errored for every odd-electron system (radicals, and ions
161
+ such as H₃O⁺, NH₄⁺, OH⁻); charge and spin are now carried through to the cube
162
+ generator.
163
+ - **Molden export from frequency calculations** — the exported geometry was
164
+ inflated (Bohr coordinates read as Ångström) and internally inconsistent, so it
165
+ rendered wrong in Avogadro/IQmol; frequency geometries are now stored and
166
+ written in the correct units. This also fixes history replay of frequency
167
+ orbital isosurfaces.
168
+ - **Export Script and method notes for `wB97X-D`** — "Export Script" failed with
169
+ a "method not supported" error and the educational notes silently disappeared
170
+ for `wB97X-D`; mixed-case method names are now matched correctly.
171
+ - **2D structure images from XYZ input** — this path never worked (it always
172
+ returned nothing) and now renders.
173
+ - **XYZ files with a blank or comment (`#`) title line** no longer silently drop
174
+ the first atom — a very common file layout was losing an atom with only a
175
+ warning.
176
+ - **NMR reference provenance** — chemical shifts no longer silently fall back to
177
+ the B3LYP/6-31G\* TMS constants for other method/basis combinations; the
178
+ reference that was actually applied is now recorded, and the lookup is
179
+ case-insensitive.
180
+ - **IR intensities for open-shell / UHF-singlet frequency runs** no longer abort
181
+ the whole IR-intensity step.
182
+ - **PES scans** — a failed scan point no longer records a bogus geometry frame or
183
+ poisons the energy/barrier statistics with NaN, and angle/dihedral scans work
184
+ with current ASE releases.
185
+ - **UHF calculations** now report a dipole moment and Mulliken charges (these were
186
+ silently skipped).
187
+ - **Clearer errors for unsupported input** — elements outside the supported H–Kr
188
+ range, and post-Hartree–Fock methods (MP2 / CCSD / CCSD(T)) requested for
189
+ calculation types that don't support them, now fail with an explicit message
190
+ instead of a misleading one or an uninformative crash.
191
+ - **Windows exports** no longer fail when the basis-set name contains `*` (e.g.
192
+ `6-31G*`) — export filenames are sanitized.
193
+ - **Method-notes panel** renders bold text correctly instead of leaking literal
194
+ `**` markers.
195
+ - **Robustness** — the event log is no longer subject to lost entries under
196
+ concurrent writes; a thumbnail-save failure no longer aborts saving a result;
197
+ PubChem availability checks respect the configured throttle and timeout; and
198
+ results carrying NumPy scalar values now save correctly.
199
+
200
+ ## [0.4.0] - 2026-06-18
201
+
202
+ Interactive-visualization and offline-readiness release. Adds molecular-orbital
203
+ isosurfaces and an interactive pre-optimization preview, reworks the 3D viewers
204
+ to preserve camera orientation across frames, makes all 3D rendering work
205
+ offline, and substantially speeds up startup.
206
+
207
+ ### Added
208
+
209
+ - **Molecular-orbital isosurfaces (py3Dmol)** — interactive HOMO / LUMO / MO
210
+ isosurface viewer rendered with py3Dmol; the downsampled Plotly path remains a
211
+ fallback.
212
+ - **Interactive classical pre-optimization** — a **Preview** button relaxes the
213
+ geometry with a fast bonded force field (RDKit MMFF94 → UFF) and animates the
214
+ relaxation in place; **Keep this geometry** adopts it as the active structure
215
+ or **Revert** discards it. Stepper controls (play/pause, prev/next, scrub
216
+ slider, and an input ⇄ relaxed flip) let you compare geometries, and the
217
+ captured trajectory is sampled at even RMSD spacing for smooth playback.
218
+ - **Cancel button** — stop a running calculation cooperatively at the next SCF
219
+ cycle / optimization step.
220
+ - **Live vibrational-animation framerate** — the Vib fps setting updates the
221
+ running animation immediately.
222
+
223
+ ### Changed
224
+
225
+ - **Single persistent 3D viewers** — the trajectory and vibrational-mode viewers
226
+ now load all frames into one py3Dmol viewer and switch frames/modes
227
+ client-side, so the camera (rotation/zoom) is preserved across steps and modes
228
+ and there is no per-frame rebuild or flicker.
229
+ - **Pre-optimization is Preview-only** — the silent "classical pre-optimize"
230
+ checkbox is gone; pre-optimization happens only through the transparent
231
+ Preview → Keep/Revert flow, so nothing relaxes the geometry invisibly. (The
232
+ separate QM "geometry optimization before calculation" option is unchanged.)
233
+ - **Offline-first 3D rendering** — 3Dmol.js is vendored and loaded per-view from
234
+ a local `data:` URI instead of a CDN, so every 3D view works with no network
235
+ (the build fails if the vendored asset is missing). Native launchers tolerate
236
+ offline `pip install`.
237
+ - **Faster startup** — GPU detection and History/Compare population are deferred
238
+ off the synchronous construction path, so the UI paints in ~1 s instead of
239
+ ~15 s; the GPU status badge and dropdowns fill in shortly after.
240
+ - **Clear** of the live calculation log is disabled while a calculation runs.
241
+
242
+ ### Fixed
243
+
244
+ - **GPU-offloaded result extraction** — HOMO–LUMO gap, dipole moment, and
245
+ Mulliken charges are now reported for GPU runs. CuPy arrays are copied to host
246
+ before extraction, and Mulliken falls back to the CPU object (gpu4pyscf does
247
+ not implement population analysis on the GPU).
248
+ - **Vibrational animation glitchiness** — stacked animation loops (a new loop
249
+ started on every mode switch) made playback jittery and too fast and ignored
250
+ the framerate setting; exactly one loop now runs.
251
+ - **Cancel status** no longer sticks on "Cancelling…" after a calculation is
252
+ cancelled.
253
+ - **Stale run status** — "Pre-optimized geometry accepted." is cleared when a new
254
+ molecule is loaded or a preview is reverted.
255
+ - Structure provenance is reported and the input viewer is persisted across
256
+ reloads.
257
+
258
+ ## [0.3.0] - 2026-06-11
259
+
260
+ Structure-sourcing release. Repairs the external-database structure search and
261
+ replaces the 20-entry inline molecule list with an indexed, three-tier bundled
262
+ library, alongside visualization and result-card fixes.
263
+
264
+ ### Added
265
+
266
+ - **External structure search** — resolve molecules by name, PubChem CID, InChI,
267
+ InChIKey, SMILES, or CAS number. Input is routed by type: SMILES/InChI resolve
268
+ locally via RDKit with no network, while names and identifiers query PubChem
269
+ through a hardened client (URL-encoding, request throttling, bounded retry on
270
+ server throttling). NCI CACTUS acts as a fallback resolver, and an offline
271
+ bundled-library fallback keeps the search usable without a network connection.
272
+ - **Disambiguation pick-list** — an ambiguous query (e.g. a name with several
273
+ PubChem matches) presents a selectable list instead of silently choosing the
274
+ first hit.
275
+ - **Three-tier bundled molecule library** — 20 presets, 156 curated named
276
+ molecules, and ~1,900 bulk QM9 structures (CC0), held in an indexed,
277
+ lazily-loaded package-data store. Bulk entries are reachable via search.
278
+ - **Library browse/search tab** — category filter plus name/formula search,
279
+ replacing the flat preset dropdown.
280
+
281
+ ### Changed
282
+
283
+ - The molecule preset list moved from an inline `config.py` dictionary into the
284
+ indexed library store; `config.MOLECULE_LIBRARY` is preserved as a
285
+ backward-compatible accessor.
286
+ - Frequency / UV-Vis seed-geometry dropdown entries are now labeled as optimized
287
+ geometries so their source is explicit.
288
+
289
+ ### Fixed
290
+
291
+ - **Orbital isosurface could exhaust browser memory** — the full volumetric grid
292
+ was serialized into the Plotly figure. The rendered surface is now downsampled
293
+ to a bounded point count (the saved cube file remains full-resolution).
294
+ - **CCSD / MP2 result cards** now show the HF reference and correlation-energy
295
+ breakdown (plus the (T) triples correction for CCSD(T)); these fields are also
296
+ persisted with saved results.
297
+ - The live calculation log no longer jumps to the top while streaming output.
298
+ - Structures fetched as 2D records are re-embedded in 3D, and salt/counterion
299
+ fragments are separated so bond perception does not misread them.
300
+
301
+ ## [0.2.0] - 2026-05-22
302
+
303
+ First substantial release after `v0.1.0`. The codebase moved from a single
304
+ monolithic `app.py` to a modular package, added six PySCF-backed calculation
305
+ types end-to-end, introduced a results-persistence layer with history replay,
306
+ and shipped a complete visualization stack (3D viewer with selectable backend,
307
+ trajectory animation, IR/UV-Vis/PES plots, orbital isosurfaces, vibrational
308
+ mode animation with caching). UI runs as a Voilà app suitable for classroom
309
+ deployment.
310
+
311
+ ### Added
312
+
313
+ #### Calculations
314
+
315
+ - **Geometry optimization** (`optimizer.py`) — ASE-BFGS driver around a custom
316
+ PySCF calculator; per-step trajectory persisted.
317
+ - **Vibrational frequency analysis** (`freq_calc.py`) — Hessian via
318
+ `pyscf.hessian`, ZPVE, thermochemistry (H/S/G at 298 K), IR intensities via
319
+ `pyscf.prop.infrared` or a numerical-derivative fallback for compatibility
320
+ across PySCF versions.
321
+ - **TD-DFT UV-Vis** (`tddft_calc.py`) — excitation energies, oscillator
322
+ strengths, wavelengths; full spectrum plot in the Analysis tab.
323
+ - **NMR shielding** (`nmr_calc.py`) — GIAO shielding via `pyscf.nmr` (core
324
+ preferred over `pyscf-properties` to dodge a known upstream bug); ¹H/¹³C
325
+ chemical shifts relative to TMS.
326
+ - **1D PES scan** (`pes_scan.py`) — bond / angle / dihedral; energy profile +
327
+ per-step geometry animation.
328
+ - **PCM implicit solvent** — Water, Ethanol, THF, DMSO, Acetonitrile via a
329
+ single checkbox in the Calculate tab.
330
+ - **MP2** post-HF method support.
331
+
332
+ #### Analysis & visualization
333
+
334
+ - **Analysis tab with 8 always-in-DOM panels** (Energies, Trajectory,
335
+ Vibrational, IR Spectrum, PES Scan, Isosurface, UV-Vis, NMR) wired through
336
+ a `_PANEL_REGISTRY` so live runs and history replay share one code path.
337
+ - **IR spectrum chart** (`ir_plot.py`) — stick plot + Lorentzian-broadened
338
+ curve; broadening toggle and FWHM slider.
339
+ - **UV-Vis spectrum plot** — Plotly chart with wavelength/energy axes.
340
+ - **Orbital visualization** (`orbital_visualization.py`) — energy-level
341
+ diagram (matplotlib → Plotly HTML) and cube-file isosurface viewer with
342
+ HOMO-1/HOMO/LUMO/LUMO+1 toggle.
343
+ - **Trajectory animation** — atomic Output-children swap to avoid
344
+ Voilà-deferred-display blank frames; py3Dmol-only render path with
345
+ prev/next arrow navigation.
346
+ - **Vibrational mode animation** — py3Dmol multi-frame XYZ renderer with
347
+ amplitude scaling, prev/next mode nav, and dropdown skipping near-zero
348
+ modes.
349
+ - **3D visualization backend router** (`viz_backend_router.py`) — pure
350
+ function that picks py3Dmol or plotlymol3d per `VizTask` based on user
351
+ preference and runtime availability; immutable `Decision` carries chosen
352
+ backend, fallback, and reason.
353
+ - **Lifecycle telemetry** — `_viz_render_event` context manager emits
354
+ `viz_render_start` / `viz_render_done` / `viz_render_error` JSONL events
355
+ with backend, task, `elapsed_ms`, and extras at every render dispatch.
356
+ - **Side-by-side Compare tab** — pick any two saved calculations and view a
357
+ diff table.
358
+
359
+ #### Persistence & logging
360
+
361
+ - **Results storage** (`results_storage.py`) — every run is saved to a
362
+ timestamped directory containing `result.json` (schema v2, additive-only),
363
+ `pyscf.log`, optional `trajectory.json` / `orbitals.npz` / `thumbnail.png`.
364
+ - **History tab** — browse and replay saved calculations after a kernel
365
+ restart; replay path is identical to live-run analysis activation.
366
+ - **Performance log** (`calc_log.py`) — `perf_log.jsonl` per converged run +
367
+ `event_log.jsonl` for startup/calc/error events; 7-day auto-prune.
368
+ - **Time estimator** — 4-strategy priority chain (N_basis-normalised → cross-method
369
+ electron-count) populates "Estimated time" before each run.
370
+ - **Benchmark suite** (`benchmarks.py`) — one-click calibration suite to
371
+ populate the time-estimator history with real machine data.
372
+ - **Issue tracker** (`issue_tracker.py`) — in-app bug-report UI writing to a
373
+ local `issues.db`.
374
+ - **Persistent user settings** (`user_settings.py`) — stored at
375
+ `~/.quantui/settings.json` (override via `QUANTUI_SETTINGS_PATH`). Schema
376
+ is section-based for additive growth, with atomic writes and graceful
377
+ fallback to defaults on corruption.
378
+ - **Vibrational-animation disk cache** (`vib_cache.py`) — per-result-dir
379
+ `vib_frames/` of pre-rendered py3Dmol HTML keyed by
380
+ `(mode, n_frames, amplitude, renderer, fps)`. Mode switches on repeat
381
+ visits and history replay are instant.
382
+ - **Vib FPS user preference** — `viz.vib_framerate_fps` exposed as an
383
+ IntSlider in the Status tab (clamped 1–120, default 10); included in the
384
+ vib cache key so changing FPS invalidates cleanly.
385
+
386
+ #### UI
387
+
388
+ - **Modular UI package** — `app.py` (orchestration) plus `app_analysis.py`,
389
+ `app_builders.py`, `app_exports.py`, `app_formatters.py`, `app_history.py`,
390
+ `app_runflow.py`, `app_visualization.py`.
391
+ - **Seven-tab layout** — Calculate, Results, Analysis, History, Compare, Log,
392
+ Status — with a floating Help overlay (not a tab).
393
+ - **Light / Dark theme selector** — dark by default on startup.
394
+ - **Status tab** — environment info, performance-history accordion (two-step
395
+ reset), default-3D-backend toggle, vib-FPS slider.
396
+ - **Files tab + activity indicator** for browsing saved results.
397
+ - **Plot export UI** — save IR, UV-Vis, PES, orbital diagram plots as HTML.
398
+ - **Scroll guard** for the run output area to keep long PySCF logs from
399
+ jumping the page.
400
+ - **Welcome header**, completion banner, structured log header/footer.
401
+ - **Compare-tab Copy-path button** (replaced a broken Open-folder action).
402
+ - **Result directory label + log accordion** showing inline `pyscf.log`.
403
+ - **Structure exports** — XYZ, MOL/SDF, PDB, plus a standalone runnable `.py`
404
+ script export.
405
+
406
+ #### Tooling & dev
407
+
408
+ - **Test suite grew from a handful to 1004 passed / 97 skipped** (Windows
409
+ `quantui-win` env baseline; the 97 skips are PySCF-gated Linux-only tests).
410
+ - New analysis-history end-to-end tests for every calc type
411
+ (`test_sp_analysis_history.py`, `test_geo_opt_analysis_history.py`,
412
+ `test_freq_analysis_history.py`, `test_tddft_analysis_history.py`,
413
+ `test_nmr_analysis_history.py`, `test_pes_scan_analysis_history.py`).
414
+ - `test_code_quality.py` enforces:
415
+ - No `include_plotlyjs="cdn"` anywhere (fails silently in offline Voilà).
416
+ - No bare `except: pass` blocks.
417
+ - `test_viz_backend_router.py` + `test_viz_backend_sync.py` — full
418
+ task × preference × availability matrix and Calculate/Analysis toggle sync.
419
+ - `test_vib_cache.py`, `test_vib_py3dmol_render.py`,
420
+ `test_viz_render_telemetry.py` — vib animation + telemetry coverage.
421
+ - `_layout(...)` helper sanitises `widgets.Layout` kwargs to eliminate a
422
+ 4808 → 13 traitlets warning regression.
423
+ - `_safe_cb` wrapper around every `.observe()` callback so exceptions surface
424
+ in the Log tab instead of disappearing into the Voilà kernel console.
425
+ - Kernel `io_loop` is cached at startup; thread-spawned callbacks are queued
426
+ onto the main thread to avoid `RuntimeError: no current event loop`.
427
+ - Native launchers: `launch-native.bat` (Windows / WSL) and
428
+ `launch-native.command` (macOS / Linux) — double-clickable, port `8867`,
429
+ stamp-based editable-install skip, browser auto-open. README documents
430
+ pinning each to the Start menu / Dock as a real app.
431
+ - Native JupyterLab launcher (`launch-native-jupyter.bat`) and Apptainer
432
+ launcher improvements.
433
+
434
+ #### Docs
435
+
436
+ - `.github/copilot-instructions.md` — canonical AI-assistant context (now
437
+ the single source of truth for any AI assistant working on this repo).
438
+ - `CLAUDE.md` — Claude-specific session/workflow context (git-ignored).
439
+ - Site favicons (ICO + SVG) for the GitHub Pages docs site.
440
+
441
+ ### Changed
442
+
443
+ - **Visualization is py3Dmol-first.** `plotlymol3d` remains an optional
444
+ fallback for non-trajectory tasks; trajectory rendering is hard-wired to
445
+ py3Dmol to avoid Plotly/RequireJS flicker.
446
+ - **Plotly figures are rendered via `plotly.io.to_html(..., include_plotlyjs="require")`**
447
+ inside `widgets.HTML`, not `display(fig)`, so threaded renders work and
448
+ offline Voilà loads correctly.
449
+ - **`pyscf` is now an optional extra** (`pip install quantui[pyscf]`); the
450
+ package imports cleanly on Windows with PySCF unavailable.
451
+ - Repo renamed from `QuantUI-local` to `QuantUI`.
452
+
453
+ ### Fixed
454
+
455
+ - **Trajectory accordion blank on first expand** — switched `traj_output`
456
+ from `Output` to `VBox` and use atomic children-swap so deferred
457
+ widget-display is no longer a blank-frame risk.
458
+ - **Vib mode races on rapid switching** — render-token guard (`_vib_render_token`)
459
+ causes stale background renders to bail rather than overwriting newer
460
+ output.
461
+ - **Camera state lost on mode switch** — JS hook caches the active
462
+ `$3Dmol.GLViewer` state across atomic HTML swaps; reset only on a
463
+ genuinely new frequency result.
464
+ - **PySCF API drift** — robust handling for v2 NMR / thermo API and the
465
+ `pyscf.prop.infrared` rename; both `Infrared.kernel()` and the older
466
+ IR API are supported.
467
+ - **Result-dir name collisions** — timestamps now include microseconds; same
468
+ formula + method + basis no longer overwrite each other.
469
+ - **IR x-axis** — corrected wavenumber axis on the IR Plotly figure.
470
+ - **Plotly figures invisible after accordion show** — figures are re-rendered
471
+ on accordion expand to handle RequireJS / display-deferral edge cases.
472
+
473
+ ### Removed
474
+
475
+ - `visualization.py` (PlotlyMol fallback) — replaced by the router-backed
476
+ `visualization_py3dmol.py` path.
477
+ - All SLURM-era infrastructure already removed during the downstream port:
478
+ `job_manager.py`, `storage.py`, `slurm_errors.py`, SLURM config templates.
479
+
480
+ ## [0.1.0] - 2026
481
+
482
+ Initial public scaffolding of the QuantUI package: `quantui` package with
483
+ `molecule.py`, `pubchem.py`, `config.py`, `visualization_py3dmol.py`,
484
+ `calculator.py`, basic notebook launcher, Apptainer container definition,
485
+ MIT license, and project metadata.
486
+
487
+ [Unreleased]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.5.1...HEAD
488
+ [0.5.1]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.5.0...v0.5.1
489
+ [0.5.0]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.4.1...v0.5.0
490
+ [0.4.1]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.4.0...v0.4.1
491
+ [0.4.0]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.3.0...v0.4.0
492
+ [0.3.0]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.2.0...v0.3.0
493
+ [0.2.0]: https://github.com/The-Schultz-Lab/QuantUI/compare/v0.1.0...v0.2.0
494
+ [0.1.0]: https://github.com/The-Schultz-Lab/QuantUI/releases/tag/v0.1.0
quantui-0.5.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 The Schultz Lab, North Carolina Central University
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,39 @@
1
+ # Source-distribution contents (M-PYPI PYPI.3).
2
+ #
3
+ # setuptools already picks up the package itself, README, LICENSE and
4
+ # pyproject.toml. This file fixes the two things it gets wrong for us:
5
+ # CHANGELOG.md was missing, and tests/ was being shipped.
6
+ #
7
+ # Policy — what belongs in the sdist:
8
+ # INCLUDE the package, its bundled data, and the documents a user or a
9
+ # downstream packager needs to understand what they installed.
10
+ # EXCLUDE anything only useful from a git clone. A pip user cannot run the
11
+ # test suite meaningfully (it needs dev extras and PySCF), cannot
12
+ # build the container, and does not get the notebooks in a usable
13
+ # location — those all stay in the repo.
14
+
15
+ include CHANGELOG.md
16
+ include SECURITY.md
17
+
18
+ # Tests need the dev extras + PySCF to run and are not importable from an
19
+ # installed copy; shipping them roughly doubles the sdist for no benefit.
20
+ prune tests
21
+
22
+ # Repo-only material: container recipes, launcher scripts, tutorial notebooks,
23
+ # the docs site, and the environment file are all clone-time artifacts.
24
+ prune apptainer
25
+ prune docs
26
+ prune launchers
27
+ prune notebooks
28
+ prune local-setup
29
+ prune scripts
30
+
31
+ # Build/dev droppings that must never reach an artifact.
32
+ prune .github
33
+ global-exclude *.py[cod]
34
+ global-exclude __pycache__
35
+ global-exclude .DS_Store
36
+ exclude .dev_install_stamp
37
+ exclude .pre-commit-config.yaml
38
+ exclude AUDIT_FINDINGS.md
39
+ exclude quantui.sif