plan
tit.server.routes.plan ¶
POST /api/plan/{kind} -- resolve what running a config would do.
For every kind this route builds the concrete output directory (or directories, for a batch of
subjects/montages) via :class:~tit.paths.PathManager -- the UI never recomputes a path
convention itself (design rule R1) -- reports whether it already exists, estimates the job's
resource cost from :mod:tit.jobs.costs, and checks for held lock conflicts via
:mod:tit.jobs.locks / :mod:tit.jobs.api (empty when the job manager, B1, is not wired up yet
in this environment).
config uses the same kind -> dataclass resolution as
:mod:tit.server.routes.validate (:func:~tit.server.routes.validate.cls_for) -- a body that
fails validation here fails with the same ValueError/TypeError a
POST /api/validate/{kind} call against it would report, just as a 422 instead of a 200
{ok: false} (a plan cannot be computed for a config that does not even deserialize).
Per-kind output-dir resolution¶
sim
One :class:PlanJob per (subject, montage). config.montages applies to every
subject in the plan; the request body's top-level montage_sources field
(contracts/openapi.yaml's MontageSources -- {"flex": [{"subject"?, "run",
"electrode_type"?, "eeg_net"?}], "freehand": [{"subject"?, "name"} | "name"]}) is
resolved via :mod:tit.sim.montage_sources into extra montages attached only to
their own subject (flex-search runs and freehand stim-configs are inherently
subject-scoped resources, unlike a plain montage_list.json entry). For one release,
the pre-contract convention of the same data nested under config["montage_sources"]
(with run_name/subject_id field names) is still read as a fallback when the
top-level field is absent -- see :func:_montage_sources_for_request. Either shape is
ignored by :func:~tit.config_io.deserialize_config when read from config (not a
SimulationConfig field).
flex / flex_adaptive / flex_pareto
config.output_folder when set, else a previewed
:func:~tit.opt.flex.utils.generate_run_dirname name under flex-search/<subject>/ (the
real run may pick a different timestamp if run later -- flagged as a warning).
ex / mex
config.run_name or a timestamp, under ex-search / m-ex-search.
resolved.search_space gives the exact combination count from
:mod:tit.opt.ex.logic / :mod:tit.opt.mex.logic (never materializing the search).
leadfield
Existing leadfield lookup via LeadfieldGenerator.list_leadfields (no SimNIBS import).
analyzer
config.output_dir when set, else :meth:PathManager.analysis_output_dir.
pre
:func:tit.jobs.plans.plan_preprocessing's G1-G6/report DAG, flattened to one
:class:PlanJob per stage per subject (not one per subject) -- exactly the granularity
POST /api/jobs/groups submits. Each stage's output_dir is a best-effort mapping to
the directory that stage's flag writes to (see :func:_pre_stage_output_dir) -- several
stages share a directory with other content (e.g. G2a and G6 both touch
m2m_<subject>/), so exists/will_overwrite there are coarser than for the
single-output kinds above. The stages run one at a time (one job per product), so the ETA
is their sum and the cost is one stage's.
source
forward mode: :meth:PathManager.forward per subject. fsavg_map mode:
:meth:PathManager.sim_fsaverage per (subject, simulation) pair.
stats
Project-level (PlanJob.subject is ""): :meth:PathManager.stats_output with the
literal analysis_type tit.stats.permutation itself uses ("group_comparison" /
"correlation").
blender
One :class:PlanJob whose output_dir is the directory the matching exporter will
write into -- see :func:_blender_output_dir, which restates each mode's own
_resolve_paths formula (the exporters cannot be imported here: they need
bpy/trimesh, which exist only inside the SimNIBS container).
nifti_average / nilearn
One project-level :class:PlanJob (subject="", like stats): output_dir mirrors
tit.stats.nifti_average.main / tit.plotting.nilearn.__main__.main's own formula
exactly (derivatives/ti-toolbox/{nifti_average,nilearn_visuals}/<output_name or
subdir_name>/). Real validation/planning since the runners lane registered
NiftiAverageConfig/NilearnConfig in
:data:tit.config_io.CONFIG_CLASS_REGISTRY -- NO_SCHEMA_KINDS (see
:mod:tit.server.routes.validate) is empty as a result, kept only as an extension point.
PlanSystem ¶
Bases: BaseModel
The machine an eta_minutes was computed for (:mod:tit.jobs.eta).