This page is for an AI agent (or a person scripting one) that drives UltrafastEngine: writing system files and run
specs, running them, reading results, and changing the code. The short version is in AGENTS.md at the repository
root and llms.txt (an index of the documentation).
A system file (.ufs, JSON with comments) lists elements in beam order (or, in a Branched system, with the link next from each element): bulk, gap, plate, mirror,
lens, gratingPair, crystal, gain, ... (supported elements) A run spec (run.json) gives the input pulse, physics switches,
instruments and overrides. The engine compiles both into linear and nonlinear operators on a frequency grid that it
sizes itself, propagates the pulse, and writes summary.json (scalars), result.npz (arrays), CSVs and
provenance.json (where every number came from). Every option has a documented default; nothing is guessed silently
-- unknown keys produce warnings with suggestions.
| question | ask the engine |
|---|---|
| every element type, option, unit, default | docs/reference/options.md, or ultrafast schema system / ultrafast schema run (JSON Schema) |
| what is built in (materials, crystals, models, element types, instruments) | ultrafast info (JSON; Python uf.capabilities()) |
| materials and refractiveindex.info pages | ultrafast materials list, ultrafast materials show <name> |
| is my file valid | ultrafast validate system.ufs run.json (exit code ≠ 0 on errors) |
| a commented starting point | ultrafast template run.json; system files: the examples |
| what the engine will do with each element | ultrafast describe system.ufs |
| Python signatures | docs/reference/python-api.md; TypedDicts in ultrafast.types |
Set ULTRAFAST_STRICT_OPTIONS=1 to turn unknown-key warnings into errors while you are writing files: a typo then
fails instead of being ignored.
ultrafast run system.ufs run.json -o results # exit 0 on success; warnings on stderr and in summary.jsonresults/summary.json:
output: the final pulse (energyJ,fwhmS,peakPowerW,transformLimitFwhmS,spectralFwhmM,pulseGddS2, ...);elements[]: per elementid,bIntegralRad,energyOutJ,peakFluenceJPerM2,lidtMargin,criticalPowerRatio,notes,values(e.g.trackedBeamRadiusXM,peakElectronDensityM3);instruments[]:name,kind,values(scalars),settings(every device parameter with the value used); arrays are inresult.npzas<name>_<array>;lossBudget,energyBudget,totals,warnings,notes,grid.
Python: res = uf.run(system, spec); res.summary, res["name_array"], res.instrument("name");
uf.load("results") opens a folder without the engine.
For beam splitters, interferometers, pump arms and loops, set "topology": "branched", and give every element next (Branched systems). Check the layout with ultrafast validate system.ufs --graph. Read the budget from summary["graph"]: energyClosureJ should be at rounding level.
Use a study, not a loop: it freezes the grid (comparable results), reuses the unchanged part of the system and
runs in parallel (Parameter studies). Parameter paths: element:ID/key, material:NAME/n2,
pulse/energyJ, pulse/chirp/gddFs2; outputs: pulse:end/fwhmS, record:ID/BIntegralRad,
instrument:NAME/key. Recorded data is core: an instrument's "measured" (compared on the recording's axis, range
and resolution; result.comparisons) and measured input spectra (pulse.spectrum, with background), see
Measured data. Fitting against measured data is the fitting plugin's "fit": mark transform numbers with {"value", "fit": true}
or list paths; results in fit.json (layers, influence, provenance) and fitted-system.ufs. "backward" propagates a
measured field to the input (Fitting).
-
steadyStateloops need gain. A passive cavity is aringDownloop, withtolerancenear the square of the accuracy you want. -
beam.m2is along x on a cartesian grid;beamProfilealso givesm2Y. -
Port c of a 50:50 Mach-Zehnder with equal arms is dark: all the light leaves by d.
-
SI units everywhere, with the unit in the key (
lengthM,durationFwhmS,gddFs2is the explicit exception in fs²). Wavelengths in metres:1.03e-6, not1030. -
beamon an element orinputBeamin the run is needed for any nonlinearity (intensity = power / area). With a GaussianinputBeamthe beam is tracked through lenses and curved mirrors; elements with their ownbeamuse it. -
1-D runs warn above the critical power for self-focusing; that is a warning about the model, not an error. Use a
transversemodel when spatial effects matter. -
Gases:
n2of N2 and air is the electronic part; the rotational Raman response is separate. -
SHG-FROG retrieval cannot determine the sign of the chirp.
-
The grid planner sizes the time window for stretched pulses and satellites (ghosts, pedestals). Override
gridonly with a reason; checkedgeEnergyFractioninoutput(should be < 1e-6). -
Synthetic data with known answers for testing an analysis: Assets.
Two plugins, driven from Python (load them with uf.plugins.load_python_plugins(); the examples show the pattern):
ao:from ultrafast_ao import DmBench, Slm, DeformableMirror, SpectralShaper, Aopdf, tiled_array. A deformable mirror and an SLM are elements that compile into the coremodulator; big maps are passed as a callback ("phaseTargetRad": "@name",fields={"name": f(x, y, z)}) or an NPZ file, never as JSON. The algorithms are NumPy:ultrafast.algorithms.holography(Gerchberg-Saxton, weighted GS),.control(modal and zonal reconstruction, interaction and control matrices, integrator loop) and.sensorless(spgd,modal_search,transmission_matrix). Rules that save time: choose the lensf = N dx^2 / lambdaso that focal pixels are FFT bins; keep patterns in the inner half of the window; setgrid.windowSto cover a shaper's side pulses (2 pi / pixel bandwidth); raisetransverse.spectralSamplesuntilspectralSamplingErroris small for a pulse. Examples: AdaptiveOptics; reference page: ao.twin:ultrafast twin init|fit|validate|predict|design|track|check(setULTRAFAST_PYTHON) orultrafast_twinfrom Python. A twin is the fit across conditions (the fitting plugin) plus a validation report: always mark at least one conditionheldOut, read the verdict (ok,marginal,fits-training-only,unvalidated) before trusting a prediction, and give the drift tracker the expected drift in physical units. The MCP server for agents is not built. Examples: DigitalTwin; reference page: twin.
- Layout:
src/UltrafastEngine.Core(engine),src/UltrafastEngine.Cli,src/UltrafastEngine.Native(C API),python/src/ultrafast,plugins/(fitting, zemax, gpu, hitran),tests/UltrafastEngine.Tests(custom runner, no NuGet). - Zero NuGet dependencies; the core must build for
net10.0andnet48(no newer APIs without#if NET). - Every element/option lives in
src/UltrafastEngine.Core/Schema/BuiltIn*.cs; after changing one, regenerateultrafast schema system -o schemas/ufs.schema.json,ultrafast schema run -o schemas/run.schema.json,ultrafast reference -o docs/reference/options.md,python python/tools/gen_types.pyandpython python/tools/gen_api_docs.py. Tests fail if any of these is stale. - Tests:
dotnet run --project tests/UltrafastEngine.Tests -f net10.0 -c Release(-- --slowfor all,-- Nameto filter); Python:python python/tools/build_engine.py && pytest python/tests. First-time setup and which build to pick: Install and build (the "For AI agents" box). See Testing. - Extension points (index models, responses, elements, instruments, retrievals, compute back-ends, FFT providers) and plugins: Extending, Plugins.