quantui 0.5.1__py3-none-any.whl

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 (62) hide show
  1. quantui/__init__.py +311 -0
  2. quantui/analytics.py +609 -0
  3. quantui/app.py +5650 -0
  4. quantui/app_analysis.py +662 -0
  5. quantui/app_builders.py +2465 -0
  6. quantui/app_exports.py +194 -0
  7. quantui/app_formatters.py +493 -0
  8. quantui/app_history.py +624 -0
  9. quantui/app_runflow.py +1544 -0
  10. quantui/app_visualization.py +2620 -0
  11. quantui/ase_bridge.py +236 -0
  12. quantui/benchmarks.py +1543 -0
  13. quantui/c_stderr.py +124 -0
  14. quantui/cactus.py +88 -0
  15. quantui/calc_log.py +1116 -0
  16. quantui/calculator.py +204 -0
  17. quantui/cancellation.py +88 -0
  18. quantui/cli.py +288 -0
  19. quantui/comparison.py +306 -0
  20. quantui/config.py +725 -0
  21. quantui/data/js/3Dmol-min.js +2 -0
  22. quantui/data/js/3Dmol-min.js.LICENSE.txt +5 -0
  23. quantui/data/library/library.sqlite +0 -0
  24. quantui/data/manifests/bulk_qm9.json +1 -0
  25. quantui/data/manifests/curated.json +15482 -0
  26. quantui/data/manifests/presets.json +816 -0
  27. quantui/descriptor_cards.py +186 -0
  28. quantui/freq_calc.py +712 -0
  29. quantui/freq_ir_workers.py +229 -0
  30. quantui/gpu_offload.py +278 -0
  31. quantui/help_content.py +474 -0
  32. quantui/ir_plot.py +130 -0
  33. quantui/issue_tracker.py +170 -0
  34. quantui/live_log.py +387 -0
  35. quantui/log_utils.py +492 -0
  36. quantui/molecule.py +577 -0
  37. quantui/molecule_library.py +433 -0
  38. quantui/nmr_calc.py +437 -0
  39. quantui/optimizer.py +670 -0
  40. quantui/orbital_visualization.py +1102 -0
  41. quantui/pes_scan.py +420 -0
  42. quantui/preopt.py +355 -0
  43. quantui/progress.py +111 -0
  44. quantui/pubchem.py +1157 -0
  45. quantui/reorganization_energy.py +435 -0
  46. quantui/results_storage.py +902 -0
  47. quantui/security.py +14 -0
  48. quantui/session_calc.py +622 -0
  49. quantui/structure_providers.py +277 -0
  50. quantui/tddft_calc.py +307 -0
  51. quantui/user_settings.py +238 -0
  52. quantui/utils.py +287 -0
  53. quantui/vib_cache.py +247 -0
  54. quantui/visualization_py3dmol.py +593 -0
  55. quantui/viz_assets.py +101 -0
  56. quantui/viz_backend_router.py +243 -0
  57. quantui-0.5.1.dist-info/METADATA +533 -0
  58. quantui-0.5.1.dist-info/RECORD +62 -0
  59. quantui-0.5.1.dist-info/WHEEL +5 -0
  60. quantui-0.5.1.dist-info/entry_points.txt +2 -0
  61. quantui-0.5.1.dist-info/licenses/LICENSE +21 -0
  62. quantui-0.5.1.dist-info/top_level.txt +1 -0
quantui/__init__.py ADDED
@@ -0,0 +1,311 @@
1
+ """
2
+ QuantUI Package
3
+
4
+ An open-source frontend for DFT and post-HF quantum chemistry with PySCF.
5
+ Calculations run locally in the Jupyter session — no cluster or SLURM required.
6
+
7
+ PySCF requires Linux/macOS/WSL. Windows users should use the Apptainer container.
8
+ """
9
+
10
+ __version__ = "0.5.1"
11
+
12
+ import logging
13
+ from typing import Any
14
+
15
+ logging.getLogger(__name__).addHandler(logging.NullHandler())
16
+
17
+ from .calculator import PySCFCalculation, create_calculation
18
+
19
+ # Calculation comparison
20
+ from .comparison import (
21
+ CalcSummary,
22
+ comparison_table_html,
23
+ plot_comparison,
24
+ summary_from_saved_result,
25
+ summary_from_session_result,
26
+ )
27
+ from .config import (
28
+ DEFAULT_BASIS,
29
+ DEFAULT_CHARGE,
30
+ DEFAULT_FMAX,
31
+ DEFAULT_METHOD,
32
+ DEFAULT_MULTIPLICITY,
33
+ DEFAULT_OPT_STEPS,
34
+ DESCRIPTION_WIDTH,
35
+ METHOD_INFO,
36
+ MOLECULE_LIBRARY,
37
+ PYSCF_SCRIPT_TEMPLATE,
38
+ QUICK_START_TEMPLATES,
39
+ SUPPORTED_BASIS_SETS,
40
+ SUPPORTED_METHODS,
41
+ VALID_ATOMS,
42
+ WIDGET_LAYOUT,
43
+ )
44
+ from .molecule import Molecule, parse_xyz_input
45
+
46
+ # Orbital visualization (matplotlib energy diagrams, cube-file viewer)
47
+ from .orbital_visualization import (
48
+ OrbitalInfo,
49
+ load_orbital_info,
50
+ orbital_info_from_arrays,
51
+ orbital_summary_html,
52
+ parse_cube_file,
53
+ plot_orbital_diagram,
54
+ )
55
+
56
+ # Security — catchable exception for constraint violations
57
+ from .security import SecurityError
58
+ from .utils import (
59
+ get_session_resources,
60
+ get_username,
61
+ sanitize_filename,
62
+ session_can_handle,
63
+ )
64
+
65
+ # ASE bridge (optional — requires ase>=3.22.0)
66
+ try:
67
+ from .ase_bridge import (
68
+ ASE_AVAILABLE,
69
+ ASE_MOLECULE_PRESETS,
70
+ ase_molecule_library,
71
+ atoms_to_molecule,
72
+ is_ase_available,
73
+ molecule_to_atoms,
74
+ read_structure_file,
75
+ )
76
+ except ImportError:
77
+ ASE_AVAILABLE = False
78
+ ASE_MOLECULE_PRESETS: dict = {} # type: ignore[misc,no-redef]
79
+
80
+ # ASE pre-optimization (optional — requires ase_bridge)
81
+ try:
82
+ from .preopt import preoptimize
83
+ except ImportError:
84
+ pass
85
+
86
+ # ASE-PySCF in-session calculator (optional — requires ase>=3.22 + pyscf, Linux/WSL)
87
+ try:
88
+ from .session_calc import SessionResult, run_in_session
89
+ except ImportError:
90
+ pass
91
+
92
+ # Frequency analysis (optional — requires pyscf, Linux/WSL)
93
+ try:
94
+ from .freq_calc import FreqResult, run_freq_calc
95
+ except ImportError:
96
+ pass
97
+
98
+ # TD-DFT excited states (optional — requires pyscf, Linux/WSL)
99
+ try:
100
+ from .tddft_calc import TDDFTResult, run_tddft_calc
101
+ except ImportError:
102
+ pass
103
+
104
+ # Results persistence — pure Python, always available
105
+ from .results_storage import list_results, load_result, save_result
106
+
107
+ # QM geometry optimizer (optional — requires ase>=3.22 + pyscf, Linux/WSL)
108
+ try:
109
+ from .optimizer import OptimizationResult, optimize_geometry
110
+ except ImportError:
111
+ pass
112
+
113
+ # 1D PES scan (optional — requires ase>=3.22 + pyscf, Linux/WSL)
114
+ try:
115
+ from .pes_scan import PESScanResult, run_pes_scan # noqa: F401
116
+ except ImportError:
117
+ pass
118
+
119
+ # Reorganization energy — Marcus 4-point (optional — requires optimizer stack)
120
+ try:
121
+ from .reorganization_energy import ( # noqa: F401
122
+ ReorganizationEnergyResult,
123
+ run_reorganization_energy,
124
+ )
125
+ except ImportError:
126
+ pass
127
+
128
+ # PubChem integration (optional — requires internet)
129
+ try:
130
+ from .cactus import fetch_from_cactus
131
+ from .pubchem import (
132
+ MoleculeNotFoundError,
133
+ PubChemError,
134
+ check_pubchem_availability,
135
+ classify_query,
136
+ display_2d_structure,
137
+ fetch_molecule,
138
+ fetch_structure,
139
+ generate_2d_structure_svg,
140
+ get_common_molecules,
141
+ get_smiles_examples,
142
+ inchi_to_xyz,
143
+ search_cid_by_inchikey,
144
+ search_cids_by_name,
145
+ search_pubchem_candidates,
146
+ smiles_to_xyz,
147
+ student_friendly_fetch,
148
+ student_friendly_resolve,
149
+ student_friendly_smiles_to_xyz,
150
+ validate_smiles,
151
+ )
152
+ from .structure_providers import (
153
+ ResolvedStructure,
154
+ resolve_structure,
155
+ search_candidates,
156
+ )
157
+
158
+ PUBCHEM_AVAILABLE = True
159
+ except ImportError:
160
+ PUBCHEM_AVAILABLE = False
161
+
162
+ # Visualization — py3Dmol only (no PlotlyMol fallback)
163
+ try:
164
+ from .visualization_py3dmol import (
165
+ display_molecule,
166
+ is_visualization_available,
167
+ visualize_molecule,
168
+ )
169
+
170
+ VISUALIZATION_AVAILABLE = True
171
+ PY3DMOL_AVAILABLE = True
172
+ except ImportError:
173
+ VISUALIZATION_AVAILABLE = False
174
+ PY3DMOL_AVAILABLE = False
175
+
176
+ # App class, StepProgress, and help_content are resolved lazily via
177
+ # module __getattr__ (PEP 562) below. All three unconditionally pull in
178
+ # ipywidgets (app.py additionally pulls in the rest of the GUI stack), and
179
+ # eagerly importing them here defeats lightweight consumers like
180
+ # ``quantui.cli`` that only need pure-Python submodules (calc_log,
181
+ # analytics, gpu_offload) — see cli.py's module docstring.
182
+ _LAZY_ATTRS = {
183
+ "QuantUIApp": (".app", "QuantUIApp"),
184
+ "StepProgress": (".progress", "StepProgress"),
185
+ "HELP_TOPICS": (".help_content", "HELP_TOPICS"),
186
+ "VALID_TOPICS": (".help_content", "VALID_TOPICS"),
187
+ "help_panel": (".help_content", "help_panel"),
188
+ }
189
+
190
+
191
+ def __getattr__(name: str) -> Any:
192
+ target = _LAZY_ATTRS.get(name)
193
+ if target is None:
194
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
195
+ module_name, attr_name = target
196
+ import importlib
197
+
198
+ module = importlib.import_module(module_name, __name__)
199
+ return getattr(module, attr_name)
200
+
201
+
202
+ __all__ = [
203
+ # Config constants
204
+ "MOLECULE_LIBRARY",
205
+ "SUPPORTED_METHODS",
206
+ "METHOD_INFO",
207
+ "SUPPORTED_BASIS_SETS",
208
+ "DEFAULT_METHOD",
209
+ "DEFAULT_BASIS",
210
+ "DEFAULT_CHARGE",
211
+ "DEFAULT_MULTIPLICITY",
212
+ "DEFAULT_FMAX",
213
+ "DEFAULT_OPT_STEPS",
214
+ "VALID_ATOMS",
215
+ "QUICK_START_TEMPLATES",
216
+ "WIDGET_LAYOUT",
217
+ "DESCRIPTION_WIDTH",
218
+ "PYSCF_SCRIPT_TEMPLATE",
219
+ # Utils
220
+ "get_username",
221
+ "sanitize_filename",
222
+ "get_session_resources",
223
+ "session_can_handle",
224
+ # Core
225
+ "Molecule",
226
+ "parse_xyz_input",
227
+ "PySCFCalculation",
228
+ "create_calculation",
229
+ # Security
230
+ "SecurityError",
231
+ # UI components
232
+ "help_panel",
233
+ "HELP_TOPICS",
234
+ "VALID_TOPICS",
235
+ "StepProgress",
236
+ # Orbital visualization
237
+ "OrbitalInfo",
238
+ "load_orbital_info",
239
+ "orbital_info_from_arrays",
240
+ "plot_orbital_diagram",
241
+ "orbital_summary_html",
242
+ "parse_cube_file",
243
+ # App class
244
+ "QuantUIApp",
245
+ # Comparison
246
+ "CalcSummary",
247
+ "summary_from_session_result",
248
+ "summary_from_saved_result",
249
+ "comparison_table_html",
250
+ "plot_comparison",
251
+ # ASE bridge (optional)
252
+ "is_ase_available",
253
+ "molecule_to_atoms",
254
+ "atoms_to_molecule",
255
+ "read_structure_file",
256
+ "ase_molecule_library",
257
+ "ASE_AVAILABLE",
258
+ "ASE_MOLECULE_PRESETS",
259
+ # ASE pre-optimization (optional)
260
+ "preoptimize",
261
+ # In-session calculator (optional — Linux/WSL)
262
+ "SessionResult",
263
+ "run_in_session",
264
+ # Frequency analysis (optional — Linux/WSL)
265
+ "FreqResult",
266
+ "run_freq_calc",
267
+ # TD-DFT excited states (optional — Linux/WSL)
268
+ "TDDFTResult",
269
+ "run_tddft_calc",
270
+ # Results persistence
271
+ "save_result",
272
+ "list_results",
273
+ "load_result",
274
+ # QM geometry optimizer (optional — Linux/WSL)
275
+ "OptimizationResult",
276
+ "optimize_geometry",
277
+ # Reorganization energy — Marcus 4-point (optional — Linux/WSL)
278
+ "ReorganizationEnergyResult",
279
+ "run_reorganization_energy",
280
+ # PubChem (optional)
281
+ "fetch_molecule",
282
+ "fetch_structure",
283
+ "classify_query",
284
+ "student_friendly_fetch",
285
+ "student_friendly_resolve",
286
+ "resolve_structure",
287
+ "ResolvedStructure",
288
+ "search_candidates",
289
+ "fetch_from_cactus",
290
+ "inchi_to_xyz",
291
+ "search_cid_by_inchikey",
292
+ "search_cids_by_name",
293
+ "search_pubchem_candidates",
294
+ "get_common_molecules",
295
+ "check_pubchem_availability",
296
+ "PubChemError",
297
+ "MoleculeNotFoundError",
298
+ "PUBCHEM_AVAILABLE",
299
+ "smiles_to_xyz",
300
+ "student_friendly_smiles_to_xyz",
301
+ "generate_2d_structure_svg",
302
+ "display_2d_structure",
303
+ "get_smiles_examples",
304
+ "validate_smiles",
305
+ # Visualization (optional)
306
+ "is_visualization_available",
307
+ "visualize_molecule",
308
+ "display_molecule",
309
+ "VISUALIZATION_AVAILABLE",
310
+ "PY3DMOL_AVAILABLE",
311
+ ]