Skip to content

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).