Validate recipe: Python API and file flow¶
For the database-backed assess_bias inputs, see
Providing bias training data.
These inputs include whole snapshot selection, the shared query cache, and a
prepared custom-complex supplement bundle.
This is a code-oriented reference for reconstructing the current Validate recipe
without going through the CLI. It describes the implementation as it exists in
src/cofolder/recipes/validate.py; it is not a promise that private helper names
will remain stable.
What Validate does¶
Validate is COFOLDER's foundational prediction workflow. It loads one molecular
system and one runner-options document, executes the selected backend for one or
more repeats, normalizes all successful backend outputs, applies shared analytics,
and writes the versioned public result bundle.
Screen and Oracle both delegate their actual prediction work to Validate.
Consequently, a replacement runner or shared analysis added at the Validate
boundary is normally inherited by those recipes as well.
Smallest Python call¶
from cofolder.recipes.validate import Validate
workflow = Validate(
wrk_dir="runs/example",
system_path="system.yaml",
options_path="options.yaml",
runner="boltz2",
repeats=1,
seed=1234,
)
workflow.run()
run() communicates through files and normally returns None. Read the canonical
outputs from <wrk_dir>/results/; do not expect the DataFrames to be returned.
The journey through the code and files¶
- Construction selects the runner.
Validate.__init__() stores all paths and requested analyses, assigns a run ID,
resolves the runner with cofolder.modules.runners.get_runner(), and creates the
initial public OutputIdentity. Runner discovery scans modules in
cofolder.modules.runners for a module-level RUNNER object.
- The working area is created.
run() enters _run_impl(). The recipe creates <wrk_dir>/raw/. Raw and
backend-private files live here; public files are written later under
<wrk_dir>/results/.
- Repeats and seeds become an explicit plan.
Without an injected RunnerExecutionPlan, helpers.get_seeds() resolves the
requested or generated base seed and one derived seed per repeat. The recipe
records these as SeedPlan and RepeatSeedProvenance objects. A runner may
adjust a backend-facing seed through resolve_effective_seed(), but it must
preserve the original provenance and state why it changed the seed.
- Runner options are loaded by the runner.
runner.load_options(options_path) parses and validates the options YAML using
that runner's schema. The supported current shape is a typed RunnerOptions or
a runner-owned wrapper around it. This is the first backend-specific seam.
- The system YAML is loaded and relative MSA paths are resolved.
load_yaml_document() reads the YAML and retains source locations for useful
validation errors. The mapping is wrapped in modules.input.system.System.
resolve_declared_msa_paths() resolves declared MSA files relative to the input
YAML's directory. A deep copy is used for the run so the source document is not
modified.
- The unprepared system is checked against runner capabilities.
runner.validate_system(..., check_atom_names=False) applies shared input
validation using the runner's declared entity and constraint capabilities. This
catches unsupported DNA, RNA, ligand, bond, pocket, or contact inputs before
backend preparation.
- Backend availability and provenance are established.
runner.ensure_available() checks that the backend can run.
runner.detect_backend_identity() records the runner name, backend distribution,
and installed version status in the public identity.
- The runner prepares the system.
runner.prepare_system() may convert conformers, populate backend-specific
chemistry data, or alter backend options. It returns RunnerPreparationResult:
the prepared system, prepared options, warnings, and typed RunnerRuntime
metadata such as cache path, sample count, and model name. Simple runners can use
the no-op implementation inherited from BaseRunner.
- The prepared system is validated and written.
The recipe validates again with check_atom_names=True, then writes the effective
system to <wrk_dir>/raw/<original-system-filename>. This generated YAML—not the
source YAML—is passed to the backend.
-
One typed runner request is executed per repeat.
For each seed, the recipe creates
<wrk_dir>/raw/repeat_<n>/and aRunnerExecutionRequest. The request contains the generated YAML, prepared options, repeat and seed provenance, backend identity, chain-identity mapping, runtime metadata, logger, and timing collector.runner.run(request)owns the backend invocation and normalization for that repeat.A runner writes its private normalized boundary under
raw/repeat_<n>/normalized/and returnsRunnerExecutionResult. If supported, generated protein MSAs are captured after a run and injected into later repeats. In a Screen parent workflow, the same cache is also shared between compounds. -
Every runner result is validated before analytics.
validate_runner_bundle()checks the normalized directory layout, canonical CSV columns, structures, sample records, chain identities, backend/seed provenance, companion artifacts, typed records, and explicit metric-group outcomes. A bad repeat becomes a typed output-validation failure. Other valid repeats may still continue; the recipe stops if none remain usable. -
Valid repeat outputs are gathered.
modules.analytics.aggregation.gather_structures()copies normalized structures into<wrk_dir>/results/structures/.merge_runner_results()merges repeat-levelsystem_metrics.csvandchain_metrics.csvinto DataFrames.add_chain_info()attaches semantic chain and entity identities. Unsupported optional runner metric groups receive explicit empty columns rather than invented values. -
Shared analytics run on the normalized DataFrames and structures.
Depending on configuration,
Structureadds distance or ProLIF interaction fingerprints and SASA metrics.scaffold_reproduction_metrics()handles the optional reference structure and custom-pocket comparisons. Optional bias usesBiasAssessmentWorkflow.apply(). Robustness aggregation runs when more than one repeat or diffusion sample exists. An analytics failure is recorded without necessarily discarding otherwise usable backend results. -
The public bundle is written.
_write_public_results()passes the final DataFrames, evidence, failures, artifacts, backend identity, and seed plan tobundle_from_frames(), followed bywrite_public_bundle(). The canonical public location is<wrk_dir>/results/, including the manifest andrecords.jsonl, derived metric tables, and any structure, alignment, matrix, IFP, or bias directories that were produced. -
Failures remain machine-readable.
A failure before a usable result is available is converted with
failure_from_exception(), written as a failed public bundle, and raised asWorkflowExecutionError. Inspectexc.failuresandexc.output_dirwhen using the API programmatically.
Where to replace one component¶
- Prediction backend: add or select another runner. This is the designed stable
extension seam and does not require rewriting
Validate. - Options interpretation or backend command: implement it inside the runner's
load_options()andrun()boundary. - Ligand/backend preparation: implement
runner.prepare_system()and declareligand_preparation_capabilities. - MSA reuse: implement the three optional runner MSA methods. The recipe owns when they are called.
- Bundle validation:
validate_runner_bundle()is the boundary shared by all runners. Replacing it changes the contract, not merely one backend. - Structure, reproduction, bias, or robustness analytics: these are currently
direct calls in
Validate, not injected plugins. To substitute only one while preserving behavior, keep its DataFrame inputs/outputs and typed failure handling equivalent. The proposed recipe refactor intends to make these boundaries smaller. - Public serialization: preserve
PublicOutputBundle, identities, provenance, metric states, andwrite_public_bundle()if downstream consumers must continue to read the same outputs.
Reconstruction checklist¶
A Python-only reconstruction is behaviorally equivalent when it preserves: typed option and system validation; runner capability checks; seed and backend provenance; preparation before final atom-name validation; one request per repeat; immediate normalized-bundle validation; partial-repeat behavior; chain identity; optional MSA reuse; requested-versus-unavailable metric states; analytics failure records; and the versioned public result bundle.