# ============================================================================== # lf_mri_platform — Start services and GUI # Usage: # .\start.ps1 — start Docker services + GUI # .\start.ps1 -GuiOnly — start GUI only (no Docker) # .\start.ps1 -Mode real — start in real hardware mode # .\start.ps1 -ServicesOnly — start Docker services only # ============================================================================== param( [switch]$GuiOnly, [switch]$ServicesOnly, [ValidateSet("plug", "real")] [string]$Mode = "plug" ) $ErrorActionPreference = "Stop" $Root = $PSScriptRoot $GuiDir = Join-Path $Root "apps\gui" $venvPython = Join-Path $GuiDir ".venv\Scripts\python.exe" $appScript = Join-Path $GuiDir "app.py" function Write-Step($msg) { Write-Host "`n==> $msg" -ForegroundColor Cyan } function Write-OK($msg) { Write-Host " [OK] $msg" -ForegroundColor Green } function Write-Warn($msg) { Write-Host " [!!] $msg" -ForegroundColor Yellow } # ── Start Docker services ───────────────────────────────────────────────────── if (-not $GuiOnly) { Write-Step "Starting Docker services (mode: $Mode)" try { & docker info *>$null } catch { Write-Warn "Docker is not running. Starting Docker Desktop..." Start-Process "C:\Program Files\Docker\Docker\Docker Desktop.exe" -ErrorAction SilentlyContinue Write-Host " Waiting 20 seconds for Docker to start..." Start-Sleep 20 } $envFile = Join-Path $Root ".env" if (-not (Test-Path $envFile)) { Copy-Item (Join-Path $Root ".env.example") $envFile Write-Warn ".env not found — created from .env.example" } $env:ORCHESTRATOR_MODE = $Mode & docker compose --env-file $envFile up --build -d Write-OK "Services started in '$Mode' mode" Write-Host " Waiting for services to become healthy..." -ForegroundColor DarkGray $maxWait = 60 $elapsed = 0 $orchPort = (Get-Content $envFile | Select-String "ORCHESTRATOR_PORT=(\d+)").Matches[0].Groups[1].Value if (-not $orchPort) { $orchPort = "1717" } while ($elapsed -lt $maxWait) { try { $r = Invoke-WebRequest "http://localhost:$orchPort/health" -UseBasicParsing -TimeoutSec 2 -ErrorAction SilentlyContinue if ($r.StatusCode -eq 200) { Write-OK "Orchestrator is up (http://localhost:$orchPort)"; break } } catch {} Start-Sleep 3 $elapsed += 3 Write-Host " ... $elapsed/$maxWait s" -ForegroundColor DarkGray } if ($elapsed -ge $maxWait) { Write-Warn "Orchestrator not responding after ${maxWait}s — GUI will use local fallback" } } # ── Start GUI ───────────────────────────────────────────────────────────────── if (-not $ServicesOnly) { Write-Step "Starting LF-MRI GUI" if (-not (Test-Path $venvPython)) { Write-Warn "Venv not found. Run .\install.ps1 first. Falling back to system Python..." $venvPython = "python" } Write-OK "Launching GUI..." Start-Process $venvPython -ArgumentList "`"$appScript`"" ` -WorkingDirectory $Root ` -WindowStyle Normal } # ── Status summary ──────────────────────────────────────────────────────────── Write-Host "" Write-Host " Service endpoints:" -ForegroundColor White Write-Host " Orchestrator http://localhost:1717/docs" Write-Host " Seq-Interp http://localhost:7475/docs" Write-Host " Spectrometer http://localhost:8000/admin/" Write-Host " Reconstructor http://localhost:8081/docs" Write-Host " Spectroscopy http://localhost:8002/docs" Write-Host "" Write-Host " Stop services: .\stop.ps1"