STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
backend.routers.layerx Namespace Reference

Classes

class  UploadSizeGuard
class  Settings
class  PidImport
class  Job
class  CardRequest
class  OptimizeBody
class  SetpointBody
class  HardwareBody
class  ReconcileBody
class  ExportBody
class  ChannelMap
class  MeasurementsBody
class  RunMeta

Functions

None _warn_missing_sources ()
Optional[Dict[str, Dict[str, float]]] check_design_patch (Optional[Dict[str, Dict[str, float]]] value)
Path _user_dir (UserSession session)
Path _runs_dir (UserSession session)
 _store (UserSession session)
 _config_and_runner (UserSession session, Optional[Dict[str, Dict[str, float]]] patch=None)
 _settings (Settings raw)
 _measurements (UserSession session)
 _drawing (UserSession session, str drawing_id)
 _prepare (UserSession session, Settings settings)
Any _json_safe (Any value)
Optional[str] _named_design (Request request, UserSession session)
str _design_label (Request request, UserSession session=Depends(get_session))
str _kind_of (Path path)
Path _index_path (Path session_dir, str run_id)
Path _meta_path (Path session_dir, str run_id)
Optional[Dict[str, Any]] _read_json (Path path)
None _write_json (Path path, Dict[str, Any] data)
bool _pinned (Path session_dir, str run_id)
Path _sidecar_path (Path session_dir, str run_id, str name)
List[Path] _run_files (Path session_dir, str run_id)
None _persist (Path session_dir, Job job)
None _execute (Job job, Callable[[Callable[[str, float], None], Callable[[], bool]], Dict[str, Any]] work, Path runs_dir)
Dict[str, Any] status ()
List[Dict[str, Any]] drawings (UserSession session=Depends(get_session))
Dict[str, Any] upload_drawing (UploadFile file=File(...), UserSession session=Depends(get_session))
None _check_drawing (Any doc)
Dict[str, str] _forward (Request request)
Any _pid_get (str path, Request request, Optional[Dict[str, str]] params=None)
Dict[str, Any] pid_documents (Request request)
Dict[str, Any] pid_import (PidImport body, Request request, UserSession session=Depends(get_session))
Dict[str, Any] preflight (Settings body, UserSession session=Depends(get_session))
Dict[str, Any] engine_card (Settings body, UserSession session=Depends(get_session))
Dict[str, Any] engine_card_for_config (CardRequest body)
Dict[str, Any] start_run (Settings body, UserSession session=Depends(get_session), str design=Depends(_design_label))
str _describe ()
str _code_version ()
Dict[str, Any] _design_snapshot (Any config)
str _design_name (UserSession session)
Job _reserve (UserSession session, Settings settings, str kind, Optional[str] design=None)
str _fingerprint (UserSession session)
None _release (Job job)
Dict[str, Any] _launch (UserSession session, Settings settings, str kind, Callable[[], Callable[..., Dict[str, Any]]] build, Optional[str] design=None)
Dict[str, Any] start_uncertainty (Settings body, UserSession session=Depends(get_session), str design=Depends(_design_label))
Dict[str, Any] optimize_variables (Settings body, UserSession session=Depends(get_session))
Dict[str, Any] start_optimize (OptimizeBody body, UserSession session=Depends(get_session), str design=Depends(_design_label))
Optional[Dict[str, float]] _check_meop (Optional[Dict[str, float]] value)
Dict[str, Any] start_setpoint (SetpointBody body, UserSession session=Depends(get_session), str design=Depends(_design_label))
Dict[str, Any] start_hardware (HardwareBody body, UserSession session=Depends(get_session), str design=Depends(_design_label))
Dict[str, Any] catalog (UserSession session=Depends(get_session))
Dict[str, Any] start_reconcile (ReconcileBody body, UserSession session=Depends(get_session), str design=Depends(_design_label))
 export_config (ExportBody body, UserSession session=Depends(get_session))
Dict[str, Any] drawing_parameters (str drawing_id, UserSession session=Depends(get_session))
Dict[str, Any] drawing_document (str drawing_id, UserSession session=Depends(get_session))
Dict[str, Any] daq_channels ()
Path _channels_path (UserSession session, str drawing_id)
Dict[str, Any] get_channels (str drawing_id, UserSession session=Depends(get_session))
Dict[str, Any] put_channels (str drawing_id, ChannelMap body, UserSession session=Depends(get_session))
Dict[str, Any] put_measurements (str drawing_id, MeasurementsBody body, UserSession session=Depends(get_session))
Optional[Dict[str, Any]] _listing_summary (Dict[str, Any] result)
Optional[Dict[str, Any]] _load_saved (UserSession session, str run_id)
List[Dict[str, Any]] list_runs (UserSession session=Depends(get_session))
Dict[str, Any] annotate_run (str run_id, RunMeta body, UserSession session=Depends(get_session))
Dict[str, Any] delete_run (str run_id, UserSession session=Depends(get_session))
Dict[str, Any] get_run (str run_id, UserSession session=Depends(get_session))
 export_eng (str run_id, Optional[float] diameter_mm=Query(default=None, gt=0.0, lt=5000.0, allow_inf_nan=False), Optional[float] length_mm=Query(default=None, gt=0.0, lt=10000.0, allow_inf_nan=False), Optional[float] dry_kg=Query(default=None, ge=0.0, lt=10000.0, allow_inf_nan=False), UserSession session=Depends(get_session))
Optional[Dict[str, Any]] _read_sidecar (UserSession session, str run_id, str name)
Dict[str, Any] get_sidecar (str run_id, str name, UserSession session=Depends(get_session))
 export_run (str run_id, str fmt, UserSession session=Depends(get_session))
Dict[str, Any] cancel_run (str run_id, UserSession session=Depends(get_session))

Variables

 router = APIRouter(prefix="/api/layerx", tags=["layerx"])
 MAX_JOBS = int(os.environ.get("LAYERX_MAX_JOBS", "2"))
 _JOB_SLOTS = threading.BoundedSemaphore(MAX_JOBS)
int UNSAVED_KEPT = 5
 KEEP_RUNS = int(os.environ.get("LAYERX_KEEP_RUNS", "25"))
tuple PID_DESIGNER_URL = (os.environ.get("PID_DESIGNER_URL") or "http://127.0.0.1:8001").rstrip("/")
float PID_TIMEOUT_S = 8.0
int MAX_UPLOAD_BYTES = 5_000_000
dict PATCH_FIELDS = {"d_jet": (1.0e-4, 0.02), "impingement_angle": (0.0, 80.0), "orifice_l_over_d": (0.5, 50.0)}
 _JOBS_LOCK = threading.Lock()
 _KIND_RE = re.compile(r'"kind":"([a-z]+)"')
 RUN_ID_RE = re.compile(r"^\d{8}-\d{6}-[0-9a-f]{6}$")
tuple SIDECARS = ("axial",)
str _CODE_AT_START = _describe()
dict OPT_LIMITS = {"lockup_psia": (14.0, 5000.0), "copv_psig": (0.0, 12000.0), "copv_volume_L": (0.05, 500.0)}
 LEGACY_KINDS = frozenset({"trade", "optimize"})
 DAQ_CONFIG = Path(os.environ.get("DAQ_CONFIG") or (Path(__file__).resolve().parents[3] / "daq-server" / "config" / "config_ground_daq.toml"))
dict EXPORTS

Detailed Description

Layer X endpoints: the feed system and the engine, burned together.

    GET  /api/layerx/status                 feedtwin importable? shipped data found?
    GET  /api/layerx/runs/{id}/eng          a finished burn's thrust curve as an OpenRocket .eng
    GET  /api/layerx/drawings               drawings this user can run
    POST /api/layerx/drawings               upload a pid-designer / feed-twin drawing (JSON)
    GET  /api/layerx/pid-designer           documents pid-designer offers this user
    POST /api/layerx/pid-designer/import    pull one into this user's drawings
    POST /api/layerx/preflight              settings -> checks, derived plan, the engine link
    POST /api/layerx/card                   settings -> the engine card itself (feedtwin JSON)
    POST /api/layerx/engine-card            any engine config (YAML) -> its card, for the feed-twin cockpit
    GET  /api/layerx/drawings/{id}/parameters   every drawing parameter, and this user's restatements
    PUT  /api/layerx/drawings/{id}/measurements this user's restated (measured) parameters
    POST /api/layerx/uncertainty            start an uncertainty sweep (background); returns its id
    POST /api/layerx/setpoint               dome, lockup and fill for a target mean thrust (background)
    POST /api/layerx/hardware               catalogue parts for the components marked free (background)
    GET  /api/layerx/catalog                the parts Hardware mode chooses from (shipped + this user's)
    POST /api/layerx/optimize/variables     legacy: the old compass search's variables, bounds and reasons
    POST /api/layerx/optimize               legacy: the old compass search (background); kept while the
                                            Optimize page still calls it. Set point replaces it.
    POST /api/layerx/reconcile              resize the injector for the drawing's feed (background)
    POST /api/layerx/export-config          the design with an injector what-if written in, as YAML
    POST /api/layerx/runs                   start a burn (background); returns its id
    GET  /api/layerx/runs                   this user's runs, newest first
    GET  /api/layerx/runs/{id}              status, progress and, when done, the result
    GET  /api/layerx/runs/{id}/sidecar/{name}   a finished burn's large side data (``axial``)
    GET  /api/layerx/runs/{id}/export/{fmt}     a finished burn as ``csv``, ``parquet`` or ``fea`` (zip)
    POST /api/layerx/runs/{id}/cancel

Old runs of kinds that can no longer be started (the trade study) or that the rebuilt tools
replace (the compass-search optimiser) stay listed and readable, marked ``legacy``.

A run is a background thread, one at a time per user and at most
``LAYERX_MAX_JOBS`` across the process. It works on a *copy* of the config
taken when it starts, with its own runner, so loading a different design
mid-run neither corrupts the run nor is corrupted by it. Finished runs are
written to the user's data directory, so a reload finds them again.

Function Documentation

◆ _channels_path()

Path backend.routers.layerx._channels_path ( UserSession session,
str drawing_id )
protected

Definition at line 1195 of file layerx.py.

References _user_dir().

Referenced by get_channels(), and put_channels().

◆ _check_drawing()

None backend.routers.layerx._check_drawing ( Any doc)
protected
A drawing Layer X can hold: lists of node and edge objects, at least one symbol. Anything
else used to be stored and then break the parameter and measurement routes.

Definition at line 593 of file layerx.py.

Referenced by pid_import(), and upload_drawing().

◆ _check_meop()

Optional[Dict[str, float]] backend.routers.layerx._check_meop ( Optional[Dict[str, float]] value)
protected

◆ _code_version()

str backend.routers.layerx._code_version ( )
protected

Definition at line 767 of file layerx.py.

Referenced by _design_snapshot().

◆ _config_and_runner()

backend.routers.layerx._config_and_runner ( UserSession session,
Optional[Dict[str, Dict[str, float]]] patch = None )
protected
A private copy of the live design (with any what-if written in) and a runner of its own.

Definition at line 233 of file layerx.py.

Referenced by _prepare(), and export_config().

◆ _describe()

str backend.routers.layerx._describe ( )
protected
``git describe`` of this checkout, with a mark when it has uncommitted changes.

Definition at line 747 of file layerx.py.

◆ _design_label()

str backend.routers.layerx._design_label ( Request request,
UserSession session = Depends(get_session) )
protected
What a job is filed under: the open design's name, else the file the session loaded.

Definition at line 330 of file layerx.py.

References _design_name(), and _named_design().

◆ _design_name()

str backend.routers.layerx._design_name ( UserSession session)
protected

Definition at line 783 of file layerx.py.

Referenced by _design_label(), and _reserve().

◆ _design_snapshot()

Dict[str, Any] backend.routers.layerx._design_snapshot ( Any config)
protected
What it takes to burn this run again: the design as it was (YAML), and the code version.
The hash alone said whether the design had moved, not what it had been.

Definition at line 771 of file layerx.py.

References _code_version().

Referenced by start_run().

◆ _drawing()

backend.routers.layerx._drawing ( UserSession session,
str drawing_id )
protected

Definition at line 255 of file layerx.py.

References _store().

Referenced by _prepare(), drawing_document(), drawing_parameters(), and put_measurements().

◆ _execute()

None backend.routers.layerx._execute ( Job job,
Callable[[Callable[[str, float], None], Callable[[], bool]], Dict[str, Any]] work,
Path runs_dir )
protected

Definition at line 479 of file layerx.py.

References _json_safe(), _persist(), and time.time().

◆ _fingerprint()

str backend.routers.layerx._fingerprint ( UserSession session)
protected

Definition at line 802 of file layerx.py.

Referenced by _reserve().

◆ _forward()

Dict[str, str] backend.routers.layerx._forward ( Request request)
protected

Definition at line 604 of file layerx.py.

Referenced by _pid_get().

◆ _index_path()

Path backend.routers.layerx._index_path ( Path session_dir,
str run_id )
protected
The run's listing entry (no result): what GET /runs reads, so a poll never parses a burn.

Definition at line 416 of file layerx.py.

Referenced by _kind_of(), _persist(), _run_files(), and list_runs().

◆ _json_safe()

Any backend.routers.layerx._json_safe ( Any value)
protected

◆ _kind_of()

str backend.routers.layerx._kind_of ( Path path)
protected
A saved job's kind: from its index entry, else from the head of its file.

Definition at line 402 of file layerx.py.

References _index_path(), _read_json(), and decode().

Referenced by _persist().

◆ _launch()

Dict[str, Any] backend.routers.layerx._launch ( UserSession session,
Settings settings,
str kind,
Callable[[], Callable[..., Dict[str, Any]]] build,
Optional[str] design = None )
protected
Claim the user's job slot, prepare (``build`` returns the work, or raises), and start.

Definition at line 816 of file layerx.py.

References _release(), _reserve(), _runs_dir(), and start().

Referenced by start_hardware(), start_optimize(), start_reconcile(), start_run(), start_setpoint(), and start_uncertainty().

◆ _listing_summary()

Optional[Dict[str, Any]] backend.routers.layerx._listing_summary ( Dict[str, Any] result)
protected
A run's summary for the list, with the replay's delivered impulse where there is one, so
the list and the result's headline say the same number.

Definition at line 1240 of file layerx.py.

Referenced by list_runs(), and backend.routers.layerx.Job.view().

◆ _load_saved()

Optional[Dict[str, Any]] backend.routers.layerx._load_saved ( UserSession session,
str run_id )
protected

Definition at line 1260 of file layerx.py.

References _runs_dir().

Referenced by get_run().

◆ _measurements()

backend.routers.layerx._measurements ( UserSession session)
protected

Definition at line 249 of file layerx.py.

References _user_dir().

Referenced by _prepare(), drawing_parameters(), and put_measurements().

◆ _meta_path()

Path backend.routers.layerx._meta_path ( Path session_dir,
str run_id )
protected
What the person said about a run: its name, a note, whether it is pinned.

Definition at line 421 of file layerx.py.

Referenced by _pinned(), _run_files(), annotate_run(), and list_runs().

◆ _named_design()

Optional[str] backend.routers.layerx._named_design ( Request request,
UserSession session )
protected
The name of the design the caller has open, when the request names one (the design bar's
``X-Design-Id`` / ``X-Design-Owner``, as the config routes read them: backend/checkout.py) and the
caller may see it: their own, the main design, or one shared with them. Otherwise None.

Definition at line 302 of file layerx.py.

Referenced by _design_label().

◆ _persist()

None backend.routers.layerx._persist ( Path session_dir,
Job job )
protected

Definition at line 460 of file layerx.py.

References _index_path(), _json_safe(), _kind_of(), _pinned(), _run_files(), _sidecar_path(), and _write_json().

Referenced by _execute().

◆ _pid_get()

Any backend.routers.layerx._pid_get ( str path,
Request request,
Optional[Dict[str, str]] params = None )
protected
GET one pid-designer route as JSON. Standard library only: the API image
installs requirements-base.txt, which carries no HTTP client.

Definition at line 609 of file layerx.py.

References _forward().

Referenced by pid_documents(), and pid_import().

◆ _pinned()

bool backend.routers.layerx._pinned ( Path session_dir,
str run_id )
protected

Definition at line 441 of file layerx.py.

References _meta_path(), and _read_json().

Referenced by _persist().

◆ _prepare()

backend.routers.layerx._prepare ( UserSession session,
Settings settings )
protected

◆ _read_json()

Optional[Dict[str, Any]] backend.routers.layerx._read_json ( Path path)
protected

Definition at line 426 of file layerx.py.

Referenced by _kind_of(), _pinned(), _read_sidecar(), annotate_run(), get_channels(), and list_runs().

◆ _read_sidecar()

Optional[Dict[str, Any]] backend.routers.layerx._read_sidecar ( UserSession session,
str run_id,
str name )
protected

Definition at line 1390 of file layerx.py.

References _read_json(), _runs_dir(), and _sidecar_path().

Referenced by export_run(), and get_sidecar().

◆ _release()

None backend.routers.layerx._release ( Job job)
protected

Definition at line 811 of file layerx.py.

Referenced by _launch().

◆ _reserve()

Job backend.routers.layerx._reserve ( UserSession session,
Settings settings,
str kind,
Optional[str] design = None )
protected
One job per user, claimed atomically: the check and the claim under one lock, before the
seconds of preparation, so two requests at once cannot both pass the check.

Definition at line 788 of file layerx.py.

References _design_name(), and _fingerprint().

Referenced by _launch().

◆ _run_files()

List[Path] backend.routers.layerx._run_files ( Path session_dir,
str run_id )
protected
Every file a saved run owns: the run, its index entry, its notes and its sidecars.

Definition at line 454 of file layerx.py.

References _index_path(), _meta_path(), and _sidecar_path().

Referenced by _persist(), and delete_run().

◆ _runs_dir()

Path backend.routers.layerx._runs_dir ( UserSession session)
protected

Definition at line 221 of file layerx.py.

References _user_dir().

Referenced by _launch(), _load_saved(), _read_sidecar(), annotate_run(), delete_run(), and list_runs().

◆ _settings()

backend.routers.layerx._settings ( Settings raw)
protected

Definition at line 243 of file layerx.py.

Referenced by _prepare().

◆ _sidecar_path()

Path backend.routers.layerx._sidecar_path ( Path session_dir,
str run_id,
str name )
protected
A run's sidecar: beside the run file, in its own directory so a listing never reads it.

Definition at line 449 of file layerx.py.

Referenced by _persist(), _read_sidecar(), and _run_files().

◆ _store()

backend.routers.layerx._store ( UserSession session)
protected

Definition at line 227 of file layerx.py.

References _user_dir().

Referenced by _drawing(), drawings(), pid_import(), and upload_drawing().

◆ _user_dir()

Path backend.routers.layerx._user_dir ( UserSession session)
protected

Definition at line 217 of file layerx.py.

Referenced by _channels_path(), _measurements(), _runs_dir(), _store(), catalog(), and start_hardware().

◆ _warn_missing_sources()

None backend.routers.layerx._warn_missing_sources ( )
protected
Say at startup when a place Layer X reads drawings from is missing: it lists nothing from there,
silently, which is how production Layer X came to see neither the twin's library nor the featured stand.

Definition at line 61 of file layerx.py.

References _warn_missing_sources().

Referenced by _warn_missing_sources().

◆ _write_json()

None backend.routers.layerx._write_json ( Path path,
Dict[str, Any] data )
protected

Definition at line 434 of file layerx.py.

Referenced by _persist(), annotate_run(), list_runs(), and put_channels().

◆ annotate_run()

Dict[str, Any] backend.routers.layerx.annotate_run ( str run_id,
RunMeta body,
UserSession session = Depends(get_session) )
Name, note or pin a saved run. A pinned run is never pruned.

Definition at line 1313 of file layerx.py.

References _meta_path(), _read_json(), _runs_dir(), and _write_json().

◆ cancel_run()

Dict[str, Any] backend.routers.layerx.cancel_run ( str run_id,
UserSession session = Depends(get_session) )

Definition at line 1450 of file layerx.py.

◆ catalog()

Dict[str, Any] backend.routers.layerx.catalog ( UserSession session = Depends(get_session))
The parts Hardware mode may choose from (engine/layerx/catalog.py): the shipped catalogues
with this user's rows over them by id, the drill table, and any user file that did not read
(``problems``; its shipped rows stand). Read-only: the user adds rows as files.

Definition at line 1035 of file layerx.py.

References _json_safe(), and _user_dir().

◆ check_design_patch()

Optional[Dict[str, Dict[str, float]]] backend.routers.layerx.check_design_patch ( Optional[Dict[str, Dict[str, float]]] value)

◆ daq_channels()

Dict[str, Any] backend.routers.layerx.daq_channels ( )
The stand DAQ's channels (daq-server's ground config): name, what it reads, its range.
So a drawing's instrument can be paired with the channel that will record it.

Definition at line 1157 of file layerx.py.

◆ delete_run()

Dict[str, Any] backend.routers.layerx.delete_run ( str run_id,
UserSession session = Depends(get_session) )
Delete a saved run of this user's, with its index entry and notes.

Definition at line 1326 of file layerx.py.

References _run_files(), and _runs_dir().

◆ drawing_document()

Dict[str, Any] backend.routers.layerx.drawing_document ( str drawing_id,
UserSession session = Depends(get_session) )
The drawing itself (nodes with positions, edges with routes), read-only: the schematic is
drawn from its topology, never from a hand-made layout.

Definition at line 1142 of file layerx.py.

References _drawing().

◆ drawing_parameters()

Dict[str, Any] backend.routers.layerx.drawing_parameters ( str drawing_id,
UserSession session = Depends(get_session) )

Definition at line 1133 of file layerx.py.

References _drawing(), and _measurements().

◆ drawings()

List[Dict[str, Any]] backend.routers.layerx.drawings ( UserSession session = Depends(get_session))

Definition at line 570 of file layerx.py.

References _store().

◆ engine_card()

Dict[str, Any] backend.routers.layerx.engine_card ( Settings body,
UserSession session = Depends(get_session) )
The engine card a burn with these settings would use, as feedtwin reads it
(``feedtwin.engine.EngineCard.from_dict``): for the feed-twin cockpit, or for checking by hand.

Definition at line 688 of file layerx.py.

References _json_safe(), and _prepare().

◆ engine_card_for_config()

Dict[str, Any] backend.routers.layerx.engine_card_for_config ( CardRequest body)
The engine card for any engine config, sent as YAML: no session, no drawing. What the
feed-twin cockpit asks for when it imports an engine, so the stand fires EngineDesign's
engine rather than feedtwin's simplified one (``engine.layerx.card.card_for_config_text``).

Definition at line 704 of file layerx.py.

References _json_safe().

◆ export_config()

backend.routers.layerx.export_config ( ExportBody body,
UserSession session = Depends(get_session) )
The live design with an injector what-if (and, if given, the drawing's fitted feed)
written in, as a YAML file to download. The design itself is not changed.

Definition at line 1086 of file layerx.py.

References _config_and_runner().

◆ export_eng()

backend.routers.layerx.export_eng ( str run_id,
Optional[float] diameter_mm = Query(default=None, gt=0.0, lt=5000.0, allow_inf_nan=False),
Optional[float] length_mm = Query(default=None, gt=0.0, lt=10000.0, allow_inf_nan=False),
Optional[float] dry_kg = Query(default=None, ge=0.0, lt=10000.0, allow_inf_nan=False),
UserSession session = Depends(get_session) )
The burn's thrust curve as a RASP .eng file for OpenRocket (engine/layerx/eng.py).

Definition at line 1358 of file layerx.py.

References get_run().

◆ export_run()

backend.routers.layerx.export_run ( str run_id,
str fmt,
UserSession session = Depends(get_session) )
A finished burn as a file (engine/layerx/export.py): ``csv`` every signal on the twin's
steps (``name [unit]`` headers), ``parquet`` the same table typed, ``fea`` a zip of the
chamber pressure, thrust and axial heat flux against time, and the peak loads.

Definition at line 1415 of file layerx.py.

References _read_sidecar(), and get_run().

◆ get_channels()

Dict[str, Any] backend.routers.layerx.get_channels ( str drawing_id,
UserSession session = Depends(get_session) )
Which DAQ channel records each of this drawing's instruments.

Definition at line 1202 of file layerx.py.

References _channels_path(), and _read_json().

◆ get_run()

Dict[str, Any] backend.routers.layerx.get_run ( str run_id,
UserSession session = Depends(get_session) )

Definition at line 1344 of file layerx.py.

References _load_saved().

Referenced by export_eng(), and export_run().

◆ get_sidecar()

Dict[str, Any] backend.routers.layerx.get_sidecar ( str run_id,
str name,
UserSession session = Depends(get_session) )
A finished run's large side data (DATA-CONTRACT 4), loaded lazily by the page that draws it.
``axial``: ``{x_mm, t, q_MW_m2: [[...]], T_wall_K: [[...]]}``, rows on ``t``. 404 when the run
has none (a run saved before sidecars, a replay that did not run, or another kind of job).

Definition at line 1397 of file layerx.py.

References _read_sidecar().

◆ list_runs()

List[Dict[str, Any]] backend.routers.layerx.list_runs ( UserSession session = Depends(get_session))

◆ optimize_variables()

Dict[str, Any] backend.routers.layerx.optimize_variables ( Settings body,
UserSession session = Depends(get_session) )
The optimiser's decision variables for these settings: bounds, start, and why.

Definition at line 883 of file layerx.py.

References _prepare().

◆ pid_documents()

Dict[str, Any] backend.routers.layerx.pid_documents ( Request request)
pid-designer's documents this user can open: their own and those shared.
Sync, so FastAPI runs the two blocking GETs in a worker thread.

Definition at line 626 of file layerx.py.

References _pid_get().

◆ pid_import()

Dict[str, Any] backend.routers.layerx.pid_import ( PidImport body,
Request request,
UserSession session = Depends(get_session) )

Definition at line 653 of file layerx.py.

References _check_drawing(), _pid_get(), and _store().

◆ preflight()

Dict[str, Any] backend.routers.layerx.preflight ( Settings body,
UserSession session = Depends(get_session) )
Everything a run would start from, graded. Sync: FastAPI runs it in a worker
thread, so its ~3 s (one EngineDesign solve, two assemblies) blocks nobody.

Definition at line 680 of file layerx.py.

References _json_safe(), and _prepare().

◆ put_channels()

Dict[str, Any] backend.routers.layerx.put_channels ( str drawing_id,
ChannelMap body,
UserSession session = Depends(get_session) )
Pair the drawing's instruments with DAQ channels. Kept on the server with the drawing.

Definition at line 1208 of file layerx.py.

References _channels_path(), and _write_json().

◆ put_measurements()

Dict[str, Any] backend.routers.layerx.put_measurements ( str drawing_id,
MeasurementsBody body,
UserSession session = Depends(get_session) )

Definition at line 1219 of file layerx.py.

References _drawing(), _measurements(), and put().

◆ start_hardware()

Dict[str, Any] backend.routers.layerx.start_hardware ( HardwareBody body,
UserSession session = Depends(get_session),
str design = Depends(_design_label) )
Catalogue parts for the components marked free, each candidate a whole burn on an in-memory
copy of the drawing, ranked by the objective (engine/layerx/optimize.py run_hardware).

Definition at line 1009 of file layerx.py.

References _launch(), _prepare(), and _user_dir().

◆ start_optimize()

Dict[str, Any] backend.routers.layerx.start_optimize ( OptimizeBody body,
UserSession session = Depends(get_session),
str design = Depends(_design_label) )
Search the feed hardware (lockup, COPV fill, COPV volume) for the most impulse or apogee from
the fixed load, every candidate a whole burn (engine/layerx/optimize.py). Minutes.

Definition at line 899 of file layerx.py.

References _launch(), and _prepare().

◆ start_reconcile()

Dict[str, Any] backend.routers.layerx.start_reconcile ( ReconcileBody body,
UserSession session = Depends(get_session),
str design = Depends(_design_label) )
Resize the injector's holes (and, if asked, its jet angles) so the design point holds under
the drawing's feed, burning and refitting until they stop moving (engine/layerx/reconcile.py).

Definition at line 1053 of file layerx.py.

References _launch(), and _prepare().

◆ start_run()

Dict[str, Any] backend.routers.layerx.start_run ( Settings body,
UserSession session = Depends(get_session),
str design = Depends(_design_label) )

Definition at line 717 of file layerx.py.

References _design_snapshot(), _json_safe(), _launch(), and _prepare().

◆ start_setpoint()

Dict[str, Any] backend.routers.layerx.start_setpoint ( SetpointBody body,
UserSession session = Depends(get_session),
str design = Depends(_design_label) )
The dome dial, lockup and bottle fill that give a target mean thrust (engine/layerx/setpoint.py):
a secant on lockup, then the fill for a bottle margin, every point a whole burn. Minutes.

Definition at line 960 of file layerx.py.

References _launch(), and _prepare().

◆ start_uncertainty()

Dict[str, Any] backend.routers.layerx.start_uncertainty ( Settings body,
UserSession session = Depends(get_session),
str design = Depends(_design_label) )
One-at-a-time sweep of the unmeasured inputs (engine/layerx/uncertainty.py): the tornado
and the band. Parallel worker processes; ~30 s on the 6.8 kN stand.

Definition at line 831 of file layerx.py.

References _launch(), and _prepare().

◆ status()

Dict[str, Any] backend.routers.layerx.status ( )

Definition at line 547 of file layerx.py.

◆ upload_drawing()

Dict[str, Any] backend.routers.layerx.upload_drawing ( UploadFile file = File(...),
UserSession session = Depends(get_session) )

Definition at line 575 of file layerx.py.

References _check_drawing(), and _store().

Variable Documentation

◆ _CODE_AT_START

str backend.routers.layerx._CODE_AT_START = _describe()
protected

Definition at line 764 of file layerx.py.

◆ _JOB_SLOTS

backend.routers.layerx._JOB_SLOTS = threading.BoundedSemaphore(MAX_JOBS)
protected

Definition at line 75 of file layerx.py.

◆ _JOBS_LOCK

backend.routers.layerx._JOBS_LOCK = threading.Lock()
protected

Definition at line 395 of file layerx.py.

◆ _KIND_RE

backend.routers.layerx._KIND_RE = re.compile(r'"kind":"([a-z]+)"')
protected

Definition at line 398 of file layerx.py.

◆ DAQ_CONFIG

backend.routers.layerx.DAQ_CONFIG = Path(os.environ.get("DAQ_CONFIG") or (Path(__file__).resolve().parents[3] / "daq-server" / "config" / "config_ground_daq.toml"))

Definition at line 1153 of file layerx.py.

◆ EXPORTS

dict backend.routers.layerx.EXPORTS
Initial value:
1= {"csv": ("text/csv", "csv"), "parquet": ("application/vnd.apache.parquet", "parquet"),
2 "fea": ("application/zip", "zip")}

Definition at line 1410 of file layerx.py.

◆ KEEP_RUNS

backend.routers.layerx.KEEP_RUNS = int(os.environ.get("LAYERX_KEEP_RUNS", "25"))

Definition at line 79 of file layerx.py.

◆ LEGACY_KINDS

backend.routers.layerx.LEGACY_KINDS = frozenset({"trade", "optimize"})

Definition at line 923 of file layerx.py.

◆ MAX_JOBS

backend.routers.layerx.MAX_JOBS = int(os.environ.get("LAYERX_MAX_JOBS", "2"))

Definition at line 74 of file layerx.py.

◆ MAX_UPLOAD_BYTES

int backend.routers.layerx.MAX_UPLOAD_BYTES = 5_000_000

Definition at line 83 of file layerx.py.

◆ OPT_LIMITS

dict backend.routers.layerx.OPT_LIMITS = {"lockup_psia": (14.0, 5000.0), "copv_psig": (0.0, 12000.0), "copv_volume_L": (0.05, 500.0)}

Definition at line 851 of file layerx.py.

◆ PATCH_FIELDS

dict backend.routers.layerx.PATCH_FIELDS = {"d_jet": (1.0e-4, 0.02), "impingement_angle": (0.0, 80.0), "orifice_l_over_d": (0.5, 50.0)}

Definition at line 184 of file layerx.py.

◆ PID_DESIGNER_URL

tuple backend.routers.layerx.PID_DESIGNER_URL = (os.environ.get("PID_DESIGNER_URL") or "http://127.0.0.1:8001").rstrip("/")

Definition at line 80 of file layerx.py.

◆ PID_TIMEOUT_S

float backend.routers.layerx.PID_TIMEOUT_S = 8.0

Definition at line 81 of file layerx.py.

◆ router

backend.routers.layerx.router = APIRouter(prefix="/api/layerx", tags=["layerx"])

Definition at line 58 of file layerx.py.

◆ RUN_ID_RE

backend.routers.layerx.RUN_ID_RE = re.compile(r"^\d{8}-\d{6}-[0-9a-f]{6}$")

Definition at line 399 of file layerx.py.

◆ SIDECARS

tuple backend.routers.layerx.SIDECARS = ("axial",)

Definition at line 446 of file layerx.py.

◆ UNSAVED_KEPT

int backend.routers.layerx.UNSAVED_KEPT = 5

Definition at line 77 of file layerx.py.