TOML migration (2026-05) โ
๐ค Auto-edited by Claude (Opus 4.7) โ verify before relying on details. This page and the TOML-migration banners across ecaljdoc were drafted in a single Claude Code session (commit
86e7646onmain). The shape is right (file roles, conversion command, sample dirs, gotchas all reflect the actual ecalj state at master7ee2d7c13/c4bf09418plus the nvfortran cherry-pickf693848ce), but specific commit hashes, line counts, and English wording may need a human pass. Flag anything that reads off and either fix it directly or open an issue.
As of May 2026, the Fortran binaries (lmf, lmfa, lmchk, gwsc, hsfp0, eps_lmfh, epsPP_lmfh, epsPP0, mlo, ...) read structured TOML only. Legacy ctrl.<sname> and GWinput text files are no longer parsed by Fortran โ they are kept around as developer references but must be converted before any binary is invoked.
The two TOML files โ
| file | role | scope |
|---|---|---|
ctrlg.<sname>.toml | merged ctrl + GW driver sections + product-basis cut-offs | sname-specific |
PB.<sname>.toml | per-atom product-basis tables (nlx, valence, core) | sname-free, shared per spec |
PB.<sname>.tomlis for the GW path only โ normally no hand editing. It feeds the mixed-product-basis generator (hbasfp0/hvccfp0etc.) used bygwsc, the eps tools andmlo's W-side. It is auto-emitted byctrlgenToml.py(orLegacy2toml.py); leave it as generated. All hand edits live inctrlg.<sname>.toml.If you have a pure DFT / no-GW workflow (just
lmf/lmfa/ band plots) and don't want the GW sections at all, pass--skipgwtoctrlgenToml.pyโ that skips thelmfa โ lmf --jobgw=0 โ gwinitsub-step, omits[gw]/[product_basis]/[blocks]from the output, and does not writePB.<sname>.toml.Adding GW sections later (preserving your hand-edits): use
ctrlgenToml.py <sname> --addgw. This appends[gw]/[product_basis]/[blocks]and writesPB.<sname>.tomlwithout regenerating the ctrl-side keys โ your edits to[bz],[ham],[[spec]]etc. are preserved as is. It refuses to run if[gw]is already present (to avoid silent duplication). Do not plain re-runctrlgenToml.py <sname>for this purpose: the default flow overwrites the wholectrlg.<sname>.tomlfromctrls.<sname>(the previous file is moved toctrlg.<sname>.toml.bakup, one-generation backup only).
<sname> is the user-defined material extension (e.g. si, cu, gaas, fe, ...). One working directory normally has exactly one ctrlg.<sname>.toml; lmf auto-detects it without a positional argument when run inside the directory.
Migration of an existing legacy directory โ
# inside an old directory containing ctrl.<sname> [+ GWinput]
Legacy2toml.py <sname>
# produces ctrlg.<sname>.toml + PB.<sname>.toml
# resume normal workflow (lmf, gwsc, eps_lmfh, ...) unchangedLegacy2toml.py lives at ecalj/SRC/exec/Legacy2toml.py (installed in ~/bin/ along with the binaries by InstallAll.py). It is idempotent and prints [INFO] / [WARN] / [ERROR] diagnostics for any command-line -v overrides that would not survive the conversion.
Run-time --ctrlg: overrides โ
%const constants embedded in the legacy ctrl.<sname> are baked into ctrlg.<sname>.toml at conversion time. Run-time overrides use --ctrlg:<dotted.path>=<value>, processed in-memory by m_toml_override.f90 (no on-disk rewrite):
# OLD (no longer parsed โ silently ignored or aborted)
lmf si -vnk=8 -vmetal=3
lmf si -v[bz.nkabc]=[8,8,8] -v[bz.metal]=3
lmf si --toml.bz.nkabc=[8,8,8] --toml.bz.metal=3
# NEW
lmf si --ctrlg:bz.nkabc=[8,8,8] --ctrlg:bz.metal=3The text after --ctrlg: is the dotted TOML path (section.key); the value parses as TOML ([8,8,8] for an integer vector, true/false lowercase for bools, quoted strings, etc.). The override layer auto-quotes a bare identifier value (find โ "find") so that shell quote-stripping is forgiving.
โ ๏ธ Retired override forms (all abort with a hint). Earlier iterations of the migration accepted several override spellings (
-v<NAME>=<VAL>,-v[<path>]=<VAL>,--[<path>]=<VAL>,--<a.b.c>=<VAL>,--toml.<path>=<VAL>,--pr=N,--time=N,M,--phispinsym). They are all gone; any of them on the cmdline triggers a one-line abort pointing at the canonical--ctrlg:<path>=<value>form.
--ctrlg:bz.nkabc=[8,8,8]โ directly set the value at TOML path[bz].nkabcinctrlg.<sname>.tomlfor this run, in memory. No%constindirection; no on-disk rewrite. The path must match a real key in the schema. Each applied override is logged on rank 0 so it appears inllmfetc.Practical consequences:
- Old habits like
-vmetal=3,-vnspin=2 -vso=0abort with a migration hint. Use--ctrlg:bz.metal=3,--ctrlg:ham.nspin=2 --ctrlg:ham.so=0.Legacy2toml.pyprints[INFO] / [WARN] / [ERROR]diagnostics for any%constoverrides it encounters during conversion to help spot silent breakages.
Migrated samples (use these as templates) โ
The following directories under ecalj/Samples/ are fully TOML-migrated and pass testecalj:
| dir | role |
|---|---|
| Samples/MLOsamples/ | MuffinTin Localized Orbitals (Wannier replacement). 17 samples โ see MLOsamples/README.md |
| Samples/TestInstall/ | install validation suite. 23 samples driven by testecalj --all |
| Samples/EPS/ | dielectric function ฮต(q,ฯ) โ EPS_Cu, EPS_GaAs, EPS_Ag (epsPP0) |
| Samples/PROCAR/ | fat-band weight โ MgO_PROCAR, Ni2MnGa_L21_PROCAR |
The catch-all index for the sample tree is Samples/README.md.
Legacy (awaiting migration) โ
Everything else lives under Samples/Legacy/ and still uses ctrl.<sname> + GWinput. To run any of those, first Legacy2toml.py <sname> inside a working copy of the directory, then proceed as usual. The Legacy/ subgroups include Magnon/, AFsymmetry/ (with test.py) plus 24 example/educational directories.
Result summaries (worked-out reference values) โ
- MLOsamples/README.md ยง Reference value: bcc Fe Fe-3d on-site W โ bcc Fe Fe-3d on-site screened W ~1.5 eV (job_mloW reproduction, 2ร2ร2 vs 4ร4ร4 BZ)
- MLOsamples/README.md ยง Regression test (testecalj Fe) โ automated diagonal V/W-V check against inline reference values
- MLOsamples/README_SOC.md โ SOC-as-perturbation variant (
job_mlo_soc)
Auto-job runner (ecalj_auto) โ
For batch QSGW / GW jobs across many materials, see ecalj_auto/README.md and ecalj_auto/README_slot_scheduler.md. The auto/ driver consumes ctrlg.<sname>.toml directly (no legacy fallback) and dispatches to jobtemplate.{kugui,ohtaka,ucgw,...} for SLURM/PBS clusters.
Common gotchas โ
- Retired override forms โ
lmfaborts on-vnspin=2 -vso=0,-v[ham.so]=1,--toml.ham.so=1,--pr=50,--time=5,5,--phispinsym. Each abort prints the canonical--ctrlg:<path>=<value>replacement. - Stale
Worbblocks โgwinput2toml.py(the GWinput leg ofLegacy2toml.py) used to last-write-wins on duplicate<Worb>blocks; now keeps the first. mlo_emax = 0literal โ TOML reader now honours an explicit0; the historical "0 means default" sentinel was retired.- gfortran 13.3 / 14.2 codegen โ a documented codegen bug was worked around in
m_HamPMT.f90(one-line baitaaa = trim(aaa) // ' '); see commits35ee9f225andf693848ceon master.
For nvfortran 26.1 specifically: findloc runtime crashes on logical arrays were fixed by adding use m_nvfortran, only: findloc to the seven affected source files (commit f693848ce).