Substantial app.py refactor, feature upgrades, hygiene improvements, and more#14
Merged
Conversation
Move HTML result-card formatting helpers out of quantui/app.py into a new quantui/app_formatters.py and update app.py to import and delegate to these functions. Add unit tests (tests/test_app_formatters.py) to verify each formatter. This separates presentation logic for easier testing and maintenance without changing formatter behaviour.
Extract export-related logic from quantui/app.py into a new module quantui/app_exports.py and delegate calls from QuantUIApp. The new file implements on_export, on_export_xyz, on_export_mol, on_export_pdb, export_molecule_and_label, and molecule_to_rdkit. quantui/app.py now imports these helpers (aliased with _exp_*) and replaces the previous inline implementations with calls to the extracted functions. Refactor for separation of concerns; behavior should remain unchanged.
Move history-related logic out of quantui/app.py into a new module quantui/app_history.py and delegate calls to the new helpers. The following behaviors were relocated: past-dropdown handling, view-log flow, reconstructing Molecule from a result dir, loading results into the Results tab, loading analysis panels, and building the analysis context. app.py now imports these helpers (with _hist_ aliases) and forwards to them, keeping external behavior unchanged while cleaning up and modularizing the main app file.
Move Analysis panel state and population helpers out of quantui/app.py into a new quantui/app_analysis.py module. Replace in-file implementations with imports and delegating calls (build_ana_switcher, select_ana_panel, activate_ana_panel, deactivate_all_ana_panels, apply_analysis_context and pop_* helpers) so QuantUIApp now uses the extracted functions. Remove a redundant local types import from app.py and wire the new module to preserve existing behaviour (including layout handling and plot re-render observers). This refactor isolates analysis concerns and reduces file size/complexity in app.py.
Move visualization and rendering logic out of QuantUIApp into a new quantui/app_visualization.py. app.py now imports the visualization functions (prefixed _viz_) and delegates the former inlined methods (trajectory, vib/IR plotting, orbital isosurfaces, 3D rendering, PES plotting, etc.) to the new module, slimming app.py and avoiding circular-import issues. Behavior is preserved; the new module contains the full implementations (trajectory carousel, vib animation, IR/ORB plotting, export handlers, etc.). Also includes small call-site cleanups (e.g. local _last_pes handling and passing layout_fn into trajectory helpers).
Move UI construction logic out of quantui/app.py into a new quantui/app_builders.py module. Replace in-file widget construction with calls to builder helpers (build_theme_selector, build_welcome_header, build_molecule_section, build_calc_setup, build_run_section, build_compare_section, build_output_tab, build_help_section, build_issue_widgets) and update imports. Add a TYPE_CHECKING block in QuantUIApp to declare attributes initialized by the new builders to avoid attr churn. This is a refactor only — no behavioral changes to the UI are intended.
Extract the Status and History tab construction from quantui/app.py into new builder functions in quantui/app_builders.py. Introduces build_status_panel and build_history_section which receive needed dependencies (layout, session resource and calibration loaders, feature flags, and benchmark lists) and create the corresponding widgets on the app instance. App.py imports and calls these builders and adds several new widget attributes to QuantUIApp. This modularizes UI construction, reduces code duplication in app.py, and keeps panel-specific logic in app_builders.py.
Move large widget-construction and run/flow handlers out of quantui/app.py into dedicated modules for better modularity. Added build_shared_widgets and build_results_section to quantui/app_builders.py and introduced quantui/app_runflow.py (new) with on_run_clicked, update_estimate, and update_notes. Updated imports and calls in app.py to delegate to these helpers and adjusted attribute declarations accordingly, significantly reducing app.py size and centralising UI construction and run logic.
Move calculation-type, PES scan and frequency-seed UI logic out of QuantUIApp into app_runflow.py as standalone functions (on_calc_type_changed, update_scan_widgets, refresh_freq_seed_options, on_freq_seed_changed). Update quantui/app.py to import and delegate to these functions (passing layout_fn where needed) and add corresponding import aliases. Also add ipywidgets import in app_runflow.py. This refactors UI behavior into the runflow module without changing functionality.
Move multiple runflow-related UI handler implementations out of QuantUIApp and into quantui.app_runflow, and update QuantUIApp to delegate to those functions. Handlers moved include solvent checkbox toggling, clearing the run log, accumulating/clearing in-session comparison results, compare list refresh/clear, and result/comparison browser refresh/population. This separates UI wiring from handler logic for better organization and testability, with no functional change to behavior.
Refactor: extract many QuantUI UI event handler implementations from quantui/app.py into standalone functions in quantui/app_runflow.py and update app.py to delegate to them. Handlers moved/rewired include Compare, History refresh, copy-results-path, perf-log reset/confirm, calibration run/stop/do_calibration, log clear, clear-log-cache (and confirm), exit, help toggle/topic, issue report (open/cancel/submit), expand molecule input, and method/basis help. The new functions accept injected dependencies (e.g. layout_fn, reset_perf_log_fn, calc_log_mod, issue_tracker_mod, benchmark suites, pyscf_available) to keep app.py thin and improve testability. Also adjusted imports (removed some direct os/Javascript usage from app.py; moved Javascript and time use into app_runflow; added time import) and updated threading usage where appropriate.
Introduce structured status markers and calc_type-aware performance logging and estimation. - Log capture: recognize [QuantUI_STATUS] lines and update the UI status label; add an on_scf_converged callback (fired once) so callers can record SCF-convergence timing. - App runflow: instrument run finalization with named timing marks, compute spans between stages, record a calc_tail_timing event (post-SCF and other checkpoints), and use a distinct elapsed_for_est for perf logging. Adjust run_status lifecycle text. - calc_log: add optional calc_type to logged records and to estimate_time so estimates are scoped by calc_type (with a back-compat bridge allowing legacy untyped records only for single_point). Filtering logic updated across estimation strategies. - runflow & benchmarks: propagate calc_type when logging/estimating; benchmarks default to "single_point". - freq_calc: emit QuantUI_STATUS marker lines during SCF/Hessian/IR/thermochemistry steps so UI can display progress; emit status messages on failures as well. - Tests: add unit tests for LogCapture status marker handling and SCF callback, and new tests verifying calc_log estimate_time scoping by calc_type and legacy record behavior. These changes improve UI feedback during long workflows and make performance estimates and analytics more accurate by separating different calculation workflows.
Add native Jupyter launch scripts (Windows .bat + WSL .sh) and include logs in .gitignore to support a local editable QuantUI JupyterLab workflow. Introduce render tokens and main-thread queuing for trajectory and orbital-isosurface rendering to avoid stale background renders and race conditions; add timeout/watchdog and richer error/logging for iso rendering. Improve Analysis panel UX with contextual "not available" messages, panel availability bookkeeping, and telemetry for missing expected panels. Add optional QM pre-optimization before non-Geometry-Opt calculations, tweak several UI labels/layouts (energy-level label, preopt descriptions, input widths), and show calculation type badges in history lists. Update notebook cell outputs/metadata and adjust tests to expect the new contextual missing-trajectory message.
Introduce UV-Vis spectrum support: add ToggleButtons and FWHM slider to the TDDT/F accordion, persist last wavelengths and oscillator strengths on the app, and wire controls to main-thread callbacks. Implement visualization helpers (show_uv_vis_spectrum, wire_uv_controls, on_uv_mode_changed, on_uv_fwhm_changed, update_uv_vis_figure) that render stick or broadened spectra via Plotly (using NumPy for broadening) and log plotting errors. Hook the analysis path to delegate UV-Vis rendering to the new API and observe the tddft accordion. Add unit tests covering the new widgets and basic show/update behaviors.
Preserve live-log scrolling behavior in notebook/Voila frontends by installing a JS scroll-guard for the run Output widget. Adds a DOM class to run_output, an app flag _run_output_scroll_guard_installed, and _install_run_output_scroll_guard() which injects a small JS routine (via display(Javascript)) to keep logs pinned to the bottom when the user is already at the bottom while allowing manual scrolling up. The installer is invoked during app init and fails silently outside notebook contexts. Tests updated to assert the run_output CSS class is present.
Introduce export controls and logic for IR/UV/orbital/PES plots: add dropdowns, save buttons and status widgets in the results UI and wire them to new handlers. Implement QuantUIApp._export_plot_figure to write Plotly figures to HTML or PNG (with kaleido detection) into the current results folder and surface success/error status. Track last rendered figures (_last_ir_fig/_last_uv_fig/_last_orb_fig/_last_pes_fig) and persist last_result_dir when loading history so exports target the correct directory. Avoid unobserve_all() in IR/UV control wiring to prevent removing unrelated trait observers. Add tests for the new export controls, export helper behavior, and existence of the scroll-guard installer.
Introduce a read-only Files tab with a safe file browser and preview (images/text), rooted to approved locations. Add a toolbar activity indicator (button) and activity tracking APIs (_activity_begin/_end/_pulse/_refresh) used to show compute vs UI activity; wire pulses into tab navigation and many existing callbacks (run, compare, history, file ops). Propagate result timestamps into _AnalysisContext and use them in analysis headings to align history labels. Update builders to create the files panel and activity button, add html import usage, and update tests to cover the new UI elements and the post-optimization single-point behavior (mocking run_in_session). Misc: various safety checks for paths, size formatting, status messages, and minor UI wiring/refresh logic.
Increase default isosurface figure size and tweak visual defaults for better integration with app themes: width 760, height 620, transparent paper background, and tighter top margin. Add an optional title_color parameter (used by app_visualization to pass theme font color) and apply it to the title font. Update tests to assert the new defaults and title_color override. These changes improve appearance and theming consistency for orbital isosurface plots.
Cache the Jupyter kernel io_loop on QuantUIApp (self._kernel_io_loop) and add _get_kernel_io_loop to resolve it lazily. Replace direct UI calls from worker threads with queued main-thread callbacks that use the cached io_loop (or fall back to direct calls when unavailable) to ensure reliable scheduling. Update visualization frame rendering to handle error and Plotly frames more robustly. Add tests covering worker-thread callback scheduling and import threading where needed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request introduces a native JupyterLab launcher for local development in WSL, improves export functionality in the QuantUI app, and enhances pre-commit configuration for type checking. The main themes are new developer tooling for running JupyterLab, new export features in the app, and code hygiene improvements.
Developer tooling: Native JupyterLab launchers
launch-native-jupyter.batandlaunch-native-jupyter.shscripts to run JupyterLab directly from the local conda environment in WSL, bypassing containers. This setup auto-clears Python bytecode caches to avoid stale code issues, automatically reinstalls the package ifpyproject.tomlchanges, and opens the main notebook in the browser on port 8868. [1] [2]QuantUI export features
quantui/app_exports.pywith helper functions to export calculation scripts and molecule geometries in XYZ, MOL, and PDB formats, with robust error handling and RDKit integration.Pre-commit and code hygiene
fail_fast: truein.pre-commit-config.yamlfor faster feedback on hook failures.mypypre-commit hook to run at thepre-pushstage for improved type checking enforcement.Miscellaneous
notebooks/molecule_computations.ipynbfrom 3.11.15 to 3.11.14.