Architecture¶
How the internals fit together. This mirrors the developer notes in
CLAUDE.md / AGENTS.md.
Startup order (critical)¶
main.py enforces a strict import order:
multiprocessing.freeze_support()— must be first (Windows PyInstaller requirement).apply_patches()fromapp/patches.py— must run before anydaraimport.- Ray initialization with tuned memory / CPU caps.
MainWindowlaunch.
Violating this order causes crashes or incorrect behaviour. The MCP server mirrors the same order (with Ray initialized lazily on the first job).
Monkeypatching (app/patches.py)¶
Four dara internals are patched before any dara module is imported:
dara.xrd.get_xrdml_data— fixes XRDML parsing for newer file schemas.dara.bgmn.download_bgmn.download_bgmn— redirects the BGMN binary download to a writable temp dir.BGMNWorker.__init__/EflechWorker.__init__— points both refinement engines to that writable dir.
This is required because dara's default paths are not writable in PyInstaller bundles.
Analysis pipeline (app/analysis_worker.py)¶
AnalysisWorker(QThread) runs the entire analysis off the main thread:
- Patches
requests.get(mirror fallback),CODDatabase.download_structures(concurrent downloads, failure resilience) anddara.search.tree.batch_refinement(Ray task throttling, progress tracking, deepcopy GC fix) — all applied inline for one run and restored infinally. - CIF acquisition — checks the persistent per-chemical-system cache and skips COD download if CIFs already exist.
- Pattern isolation — copies the input to a fresh temp dir as
pattern.xy. search_phases()— the core search / refinement call; returns rankedSolutionobjects.- Packaging — the top solutions become dicts with fit metrics, phase weight
fractions, profile / peaks tables, raw
.lst, and structural data. - Emits
results_readywith the list of result dicts.
Ray is initialized once at startup and never shut down mid-session — a
ray.shutdown() would kill the cluster for all subsequent runs.
UI layout¶
MainWindow (QMainWindow)
└── QSplitter (horizontal)
├── SidebarWidget — inputs, file pickers, advanced params, run/cancel
└── ResultsArea — welcome page → one tab per ranked solution
Each result tab contains a Plotly chart, phase-weight bars, metric cards
(Rwp / Rp / GoF / Durbin–Watson), a lattice-parameter table, a peaks table, and
a raw .lst viewer with export.
Design system (app/theme.py)¶
All colours, fonts, and spacing constants live here — UI code never hardcodes
values inline. Theming is token-based: THEMES holds three switchable palettes
— A (Helios, light native — default), B (Graphite, dark instrument), and
C (Mineral, light + scope) — read via tokens(), with set_theme() /
cycle_theme() to switch.
Key design decisions¶
- Ray throttling —
batch_refinementuses a sliding window (MAX_IN_FLIGHT = min(100, cpu_count * 4)) to prevent worker explosion with large phase counts. Results aredeepcopy'd immediately to free Ray object store memory. - CIF cache — a per-chemical-system persistent cache avoids re-downloading from COD on repeated analyses of the same system.
- Deferred temp-dir cleanup — a short delay before removing the temp dir
lets orphaned Ray tasks referencing
pattern.xyfinish naturally without killing the cluster.