Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@ QuantUI/
│ ├── quantui.def ← Apptainer container definition
│ └── build.sh ← Build script
├── local-setup/ ← Conda environment YAMLs
├── launch-app.bat ← Windows double-click launcher (Voilà app mode)
├── launch-dev.bat ← Windows double-click launcher (JupyterLab mode)
├── launchers/ ← Double-click launchers (Windows .bat, macOS .command, Linux/WSL .sh)
├── CHANGELOG.md ← Release history (Keep a Changelog format)
├── pyproject.toml ← Package config (name: quantui, imports as quantui)
└── pytest.ini ← pytest configuration
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Dev launcher stamp (written by launch-native.bat to skip redundant pip install)
# Dev launcher stamp (written by launchers/launch-native.* to skip redundant pip install)
.dev_install_stamp

# Python
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht

### Changed

- **All launcher scripts moved into a `launchers/` folder** to declutter the repo
root. Behaviour is unchanged — each launcher now resolves the repo root as its
parent directory. `launchers/launch-app.bat` still finds `quantui.sif` next to
itself (student download) or in the repo root (dev build). Docs and shortcuts
that referenced the old top-level paths were updated.
- **Apptainer container now builds on `condaforge/miniforge3` with the `mamba`
(libmamba) solver.** The previous `continuumio/miniconda3` base used conda's
classic solver, which could hang for hours resolving the PySCF + RDKit +
Expand Down
42 changes: 31 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,35 @@ no rebuild.

| Platform | File | Action |
| --- | --- | --- |
| Windows | [`launch-native.bat`](launch-native.bat) | Activates the `quantui` conda env inside WSL Ubuntu, runs Voilà, and opens `http://localhost:8867` |
| macOS / Linux | [`launch-native.command`](launch-native.command) | Activates the local `quantui` conda env directly (no WSL needed) and does the same |

Both launchers reuse port `8867`, so you can keep the same browser tab pinned
across platforms.
| Windows | [`launchers/launch-native.bat`](launchers/launch-native.bat) | Activates the `quantui` conda env inside WSL Ubuntu, runs Voilà, and opens `http://localhost:8867` |
| macOS | [`launchers/launch-native.command`](launchers/launch-native.command) | Activates the local `quantui` conda env directly (no WSL needed) and does the same |
| Linux / WSL | [`launchers/launch-native.sh`](launchers/launch-native.sh) | Run `./launchers/launch-native.sh` from a Linux or WSL terminal; activates `quantui` and does the same |

All launchers reuse port `8867`, so you can keep the same browser tab pinned
across platforms. They **auto-detect your conda installation** — miniforge
(recommended), miniconda, or anaconda, in your home directory or a system
prefix — so no path editing is needed regardless of which you installed.

> **WSL users — clone into the Linux filesystem, not `/mnt/c`.** Running
> `pip install -e .` (or the launchers) against a repo on the Windows drive
> (`/mnt/c/...`) fails with `error: [Errno 1] Operation not permitted` because
> the 9P bridge WSL uses for Windows files doesn't support the file operations
> an editable build needs — and it's ~10× slower besides. Clone the repo into
> your WSL home instead and work from there:
>
> ```bash
> git clone https://github.com/The-Schultz-Lab/QuantUI.git ~/GitHub/QuantUI
> cd ~/GitHub/QuantUI
> ```
>
> Then open it in VS Code with `code .` (installs the WSL server and reopens
> the window connected to WSL). `launchers/launch-native.sh` resolves its own
> location, so it works from any clone path.

### Windows — pin to the Start menu

1. Right-click [`launch-native.bat`](launch-native.bat) in File Explorer
→ **Send to** → **Desktop (create shortcut)**.
1. Right-click [`launchers/launch-native.bat`](launchers/launch-native.bat) in
File Explorer → **Send to** → **Desktop (create shortcut)**.
2. Rename the shortcut to something friendly like `QuantUI`.
3. *(Optional)* Right-click the shortcut → **Properties** → **Change Icon...**
and point at `docs\logo.ico` for a proper app icon.
Expand All @@ -222,7 +241,8 @@ in your browser.

### macOS — pin to the Dock / Launchpad

**Quickest:** double-click [`launch-native.command`](launch-native.command)
**Quickest:** double-click
[`launchers/launch-native.command`](launchers/launch-native.command)
from Finder. macOS will open Terminal, run the script, and pop the app open
in your browser. The first launch is gated by Gatekeeper: right-click the
file → **Open** → **Open** to clear it (one time only).
Expand All @@ -239,7 +259,7 @@ application so it lives in Launchpad and pins to the Dock.
your clone lives elsewhere):

```bash
"$HOME/path/to/QuantUI/launch-native.command"
"$HOME/path/to/QuantUI/launchers/launch-native.command"
```

4. **File → Save** → name it `QuantUI` → save into `/Applications`.
Expand All @@ -253,8 +273,8 @@ You now have a real `.app` you can launch from Spotlight, Launchpad, or the
Dock — it just runs the `.command` script under the hood, so any
`quantui/*.py` edits take effect immediately on the next launch.

> **Linux users:** the same `launch-native.command` script works from a
> terminal — `./launch-native.command`. To wire it into your desktop
> **Linux users:** the same `launchers/launch-native.command` script works from
> a terminal — `./launchers/launch-native.command`. To wire it into your desktop
> environment as a pinned app, create a `.desktop` entry pointing at the
> script.

Expand Down
7 changes: 4 additions & 3 deletions apptainer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,13 @@ the `.def` file copies the entire repo root into the container with

### Windows — double-click launchers (easiest)

Two `.bat` files in the repo root handle WSL and browser launch automatically:
Two `.bat` files in the repo's `launchers/` folder handle WSL and browser launch
automatically:

| File | Purpose |
| --- | --- |
| `launch-app.bat` | Student-facing app — uses the baked-in notebook |
| `launch-dev.bat` | Development mode — uses local `notebooks/` (no rebuild needed for notebook edits) |
| `launchers/launch-app.bat` | Student-facing app — uses the baked-in notebook |
| `launchers/launch-dev.bat` | Development mode — uses local `notebooks/` (no rebuild needed for notebook edits) |

Double-click either file. The browser opens automatically at
[http://localhost:8866](http://localhost:8866).
Expand Down
3 changes: 1 addition & 2 deletions apptainer/quantui.def
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ FROM: condaforge/miniforge3:latest
%post
export PATH="/opt/conda/bin:${PATH}"

echo "Installing dependencies via mamba (libmamba solver — the old classic"
echo "conda solver hangs for hours on this pyscf + rdkit + jupyterlab spec)..."
echo "Installing dependencies via mamba (libmamba solver — the old classic conda solver hangs for hours on this pyscf + rdkit + jupyterlab spec)."
# conda-forge only, strict priority: avoids mixing in the base image's
# implicit 'defaults' channel, which both slows the solve and pulls from a
# channel with separate terms of service.
Expand Down
11 changes: 7 additions & 4 deletions launch-app.bat → launchers/launch-app.bat
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@
echo QuantUI — Starting...
echo.

REM Check that the .sif exists before trying to launch
if not exist "%~dp0quantui.sif" (
REM Locate quantui.sif — next to this launcher (student download) or in the
REM repo root one level up (dev build via apptainer/build.sh).
set "SIFDIR=%~dp0"
if not exist "%SIFDIR%quantui.sif" set "SIFDIR=%~dp0..\"
if not exist "%SIFDIR%quantui.sif" (
echo ERROR: quantui.sif not found.
echo Build it first: bash apptainer/build.sh
echo Or download it from the GitHub Releases page.
pause
exit /b 1
)

REM Convert the Windows repo path to a WSL path for portability
for /f "delims=" %%i in ('wsl wslpath -a "%~dp0"') do set WSLPATH=%%i
REM Convert the folder holding the .sif to a WSL path for portability
for /f "delims=" %%i in ('wsl wslpath -a "%SIFDIR%"') do set WSLPATH=%%i

REM Launch Voila in a new WSL window (stays open so you can see logs)
start "QuantUI" wsl -d Ubuntu -- bash -c "cd '%WSLPATH%' && apptainer run quantui.sif app"
Expand Down
9 changes: 6 additions & 3 deletions launch-dev.bat → launchers/launch-dev.bat
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
echo QuantUI DEV MODE — Using local notebook (no rebuild needed)
echo.

if not exist "%~dp0quantui.sif" (
REM Repo root is one level up from this launchers/ folder.
for %%i in ("%~dp0..") do set "REPO=%%~fi"

if not exist "%REPO%\quantui.sif" (
echo ERROR: quantui.sif not found.
pause
exit /b 1
Expand All @@ -14,8 +17,8 @@ echo Edits to quantui/*.py require a container rebuild to take effect.
echo For package-level dev, use launch-native.bat instead.
echo.

REM Convert the Windows repo path to a WSL path for portability
for /f "delims=" %%i in ('wsl wslpath -a "%~dp0"') do set WSLPATH=%%i
REM Convert the repo root to a WSL path for portability
for /f "delims=" %%i in ('wsl wslpath -a "%REPO%"') do set WSLPATH=%%i

REM Uses the local notebook on disk instead of the baked-in copy.
REM Edits to notebooks/ take effect immediately — no container rebuild needed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ echo QuantUI NATIVE JUPYTER MODE -- Local conda env in WSL, no container
echo Use this when you have edited quantui/*.py and want JupyterLab.
echo.

REM Convert the Windows repo path to a WSL path for portability
set "WIN_REPO=%~dp0."
for /f "delims=" %%i in ('wsl wslpath -a "%WIN_REPO%"') do set WSLPATH=%%i
REM Repo root is one level up from this launchers/ folder; convert it to a WSL
REM path for portability.
for %%i in ("%~dp0..") do set "REPO=%%~fi"
for /f "delims=" %%i in ('wsl wslpath -a "%REPO%"') do set WSLPATH=%%i
if not defined WSLPATH (
echo ERROR: Could not resolve a WSL path for %WIN_REPO%
echo ERROR: Could not resolve a WSL path for %REPO%
echo Try this command manually:
echo wsl wslpath -a "%WIN_REPO%"
echo wsl wslpath -a "%REPO%"
echo.
pause
exit /b 1
)
set LOGFILE=%~dp0logs\native-jupyter.log
set "LOGFILE=%REPO%\logs\native-jupyter.log"

echo Startup log: %LOGFILE%
echo.
Expand All @@ -30,7 +31,7 @@ REM Clears quantui/__pycache__ on every launch to prevent stale .pyc bytecode
REM (WSL2 DrvFs does not reliably propagate Windows-side mtime changes, so Python
REM may load pre-edit bytecode even after source changes -- see GOTCHAS.md).
REM PYTHONDONTWRITEBYTECODE=1 prevents a new stale cache from accumulating.
start "QuantUI [native-jupyter]" wsl -d Ubuntu --cd "%WSLPATH%" -- bash ./launch-native-jupyter.sh
start "QuantUI [native-jupyter]" wsl -d Ubuntu --cd "%WSLPATH%" -- bash ./launchers/launch-native-jupyter.sh

echo Waiting for JupyterLab to start on localhost:8868...
set MAX_WAIT=45
Expand Down
31 changes: 30 additions & 1 deletion launch-native-jupyter.sh → launchers/launch-native-jupyter.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#!/usr/bin/env bash
set -euo pipefail

# Repo root is one level up from this launchers/ folder. cd there so every
# relative path below (logs/, pyproject.toml, quantui/, notebooks/) resolves
# regardless of the caller's working directory.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR/.."

LOG_FILE="logs/native-jupyter.log"
mkdir -p "$(dirname "$LOG_FILE")"

Expand All @@ -12,7 +18,30 @@ mkdir -p "$(dirname "$LOG_FILE")"

exec > >(tee -a "$LOG_FILE") 2>&1

source ~/miniconda3/etc/profile.d/conda.sh
# Locate conda.sh. Detect the install rather than assuming one location:
# miniforge (recommended for WSL), miniconda, and anaconda are all supported.
# Falls back to an already-configured conda via $CONDA_EXE.
CONDA_SH=""
for candidate in \
"$HOME/miniforge3/etc/profile.d/conda.sh" \
"$HOME/miniconda3/etc/profile.d/conda.sh" \
"$HOME/anaconda3/etc/profile.d/conda.sh" \
"/opt/miniforge3/etc/profile.d/conda.sh" \
"/opt/miniconda3/etc/profile.d/conda.sh" \
"/opt/conda/etc/profile.d/conda.sh"; do
[ -f "$candidate" ] && CONDA_SH="$candidate" && break
done
if [ -z "$CONDA_SH" ] && [ -n "${CONDA_EXE:-}" ]; then
fallback="$(dirname "$(dirname "$CONDA_EXE")")/etc/profile.d/conda.sh"
[ -f "$fallback" ] && CONDA_SH="$fallback"
fi
if [ -z "$CONDA_SH" ]; then
echo "ERROR: Could not locate conda.sh. Install Miniforge to ~/miniforge3."
echo " https://github.com/conda-forge/miniforge"
exit 1
fi
# shellcheck disable=SC1090
source "$CONDA_SH"
conda activate quantui

echo "Using Python: $(command -v python)"
Expand Down
8 changes: 5 additions & 3 deletions launch-native.bat → launchers/launch-native.bat
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ echo QuantUI NATIVE MODE — Local conda env in WSL, no container
echo Use this when you have edited quantui/*.py and want to test immediately.
echo.

REM Convert the Windows repo path to a WSL path for portability
for /f "delims=" %%i in ('wsl wslpath -a "%~dp0"') do set WSLPATH=%%i
REM Repo root is one level up from this launchers/ folder; convert it to a WSL
REM path for portability.
for %%i in ("%~dp0..") do set "REPO=%%~fi"
for /f "delims=" %%i in ('wsl wslpath -a "%REPO%"') do set WSLPATH=%%i

REM Runs Voila directly from the quantui conda env inside WSL.
REM pip install -e . is skipped when pyproject.toml has not changed since the
Expand All @@ -25,7 +27,7 @@ REM make EVERY subsequent offline launch retry (and re-delay on) pip — the
REM reinstall is attempted once, then skipped. quantui/*.py + package-data are
REM live in editable mode, so a skipped reinstall is harmless offline; re-run
REM `pip install -e .` manually when online if you add a real dependency.
start "QuantUI [native]" wsl -d Ubuntu -- bash -c "cd '%WSLPATH%' && source ~/miniconda3/etc/profile.d/conda.sh && conda activate quantui && if [ pyproject.toml -nt .dev_install_stamp ] || ! python -c 'import quantui' 2>/dev/null; then pip install -e . -q --timeout=5 --retries=0 && touch .dev_install_stamp || { echo '[QuantUI] editable reinstall skipped (offline?) - using live source'; touch .dev_install_stamp; }; fi; rm -rf quantui/__pycache__ && PYTHONDONTWRITEBYTECODE=1 voila notebooks/molecule_computations.ipynb --no-browser --port=8867 --ServerApp.disable_check_xsrf=True"
start "QuantUI [native]" wsl -d Ubuntu -- bash -c "cd '%WSLPATH%' && for c in ~/miniforge3 ~/miniconda3 ~/anaconda3 /opt/conda; do [ -f $c/etc/profile.d/conda.sh ] && . $c/etc/profile.d/conda.sh && break; done && conda activate quantui && if [ pyproject.toml -nt .dev_install_stamp ] || ! python -c 'import quantui' 2>/dev/null; then pip install -e . -q --timeout=5 --retries=0 && touch .dev_install_stamp || { echo '[QuantUI] editable reinstall skipped (offline?) - using live source'; touch .dev_install_stamp; }; fi; rm -rf quantui/__pycache__ && PYTHONDONTWRITEBYTECODE=1 voila notebooks/molecule_computations.ipynb --no-browser --port=8867 --ServerApp.disable_check_xsrf=True"

echo Waiting for Voila to start...
timeout /t 6 /nobreak > nul
Expand Down
20 changes: 15 additions & 5 deletions launch-native.command → launchers/launch-native.command
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,22 @@ set -eu

# Resolve script directory so double-click from any location works.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
# Repo root is one level up from this launchers/ folder.
cd "$SCRIPT_DIR/.."

echo "QuantUI NATIVE MODE — Local conda env on macOS, no container"
echo "Use this when you have edited quantui/*.py and want to test immediately."
echo

# Locate conda.sh. Miniconda at ~/miniconda3 is the documented install;
# we try a few common fallback locations before giving up.
# Locate conda.sh. Detect the install rather than assuming one location:
# miniforge, miniconda, and anaconda are all supported, in home, /opt, and
# Homebrew Caskroom prefixes. Falls back to an already-configured conda via
# $CONDA_EXE.
CONDA_SH=""
for candidate in \
"$HOME/miniforge3/etc/profile.d/conda.sh" \
"/opt/miniforge3/etc/profile.d/conda.sh" \
"/opt/homebrew/Caskroom/miniforge/base/etc/profile.d/conda.sh" \
"/opt/miniconda3/etc/profile.d/conda.sh" \
"/opt/miniconda3/condabin/conda" \
"$HOME/miniconda3/etc/profile.d/conda.sh" \
Expand All @@ -34,11 +40,15 @@ for candidate in \
break
fi
done
if [ -z "$CONDA_SH" ] && [ -n "${CONDA_EXE:-}" ]; then
fallback="$(dirname "$(dirname "$CONDA_EXE")")/etc/profile.d/conda.sh"
[ -f "$fallback" ] && CONDA_SH="$fallback"
fi

if [ -z "$CONDA_SH" ]; then
echo "ERROR: Could not locate conda.sh."
echo " Install Miniconda to ~/miniconda3 and re-run."
echo " https://docs.conda.io/projects/miniconda/en/latest/"
echo " Install Miniforge to ~/miniforge3 and re-run."
echo " https://github.com/conda-forge/miniforge"
echo
read -n 1 -s -r -p "Press any key to close this window..."
exit 1
Expand Down
Loading
Loading