Skip to content

fix: per-fold model flags, and an AF3 pipeline seam that is not a global - #640

Merged
DimaMolod merged 2 commits into
mainfrom
fix/per-fold-flags-and-af3-pipeline-seam
Sep 6, 2026
Merged

fix: per-fold model flags, and an AF3 pipeline seam that is not a global#640
DimaMolod merged 2 commits into
mainfrom
fix/per-fold-flags-and-af3-pipeline-seam

Conversation

@DimaMolod

Copy link
Copy Markdown
Collaborator

Two findings from an architecture review of the recently merged batch work. Both are in already-merged code, not in #638 or #639.

1. Model flags followed the last fold, not the object (a correctness bug)

run_structure_prediction.main() decided final_model_flags inside its loop over folds and read it after the loop, so one flag set — whichever the last fold with protein objects produced — was applied to every object.

Queue a monomer behind a multimer and the monomer was predicted with model_name: "multimer". Nothing raised; it silently predicted the wrong thing.

This is the same failure fold_preparation.py was extracted to fix, where metadata was reassigned inside a loop and read outside it. That instance was found and fixed; this sibling survived because the batch path computes flags per job and only this copy did not.

Each job now carries the flags it needs, and inference_flags.group_by_model_flags batches jobs by flag set — so like folds still share a single predict_structure call and unlike folds are no longer forced to.

A test changed rather than being preserved. test_main_routes_protein_and_json_jobs_to_predict_structure asserted one call in which an AlphaFold 3 JSON input inherited model_name: "multimer" from the protein fold beside it. That expectation was the bug.

2. The batch scripts' interface to the CLI was a global

create_batch_features.py and finalize_batch_features.py both called legacy_features.create_arguments() — whose job is to mutate module-global FLAGS with resolved database paths — and then called create_pipeline_af3() and get_af3_feature_metadata(), which read that mutation back. A wide, ordering-dependent, implicit interface across a script boundary.

alphapulldown/af3_pipeline.py states it as data instead. AF3PipelineSettings.from_flags resolves every binary and database path once and writes nothing back; it also carries resolved_flag_values, so provenance metadata records the paths actually used without a global having been rewritten to hold them. The path resolver is injected, so the new module does not depend on the CLI it came out of.

Backwards compatible: create_pipeline_af3() keeps its signature and its ImportError; get_af3_feature_metadata() gains an optional flag_values. Neither batch script calls create_arguments() any more.

Deliberately not included

Unifying run_structure_prediction_batch.py with main(). The two carry near-identical bodies, but they have already diverged in ways that need a decision rather than a merge — main() supports shared_output_root=True and the batch adapter hardcodes False. Folding them together would silently pick a winner for real prediction behaviour.

create_batch_features.py was also flagged as having no Snakemake consumer, but it is documented in the wiki and in workflows/mmseqs2-gpu.md as the supported one-process mode. Having no scheduler consumer is the design, so it stays.

Tests

564 passed, 7 skipped, 0 failed. New: test_model_flag_grouping.py (5) and test_af3_pipeline_settings.py (5), both free of heavy dependencies.

🤖 Generated with Claude Code

DimaMolod and others added 2 commits September 6, 2026 08:25
run_structure_prediction.main() decided final_model_flags inside its loop over
folds and read it after the loop, so one flag set -- whichever the last fold with
protein objects produced -- was applied to every object. Queue a monomer behind a
multimer and the monomer was predicted with model_name "multimer". Nothing
raised; it silently predicted the wrong thing.

This is the same failure fold_preparation.py was extracted to fix, where metadata
was reassigned inside a loop and read outside it. That one was found and fixed;
this sibling survived because the batch path computes flags per job and only this
copy did not.

Each job now carries the flags it needs, and inference_flags.group_by_model_flags
batches jobs by flag set, so like folds still share one predict_structure call
while unlike folds no longer have to.

test_main_routes_protein_and_json_jobs_to_predict_structure asserted the old
behaviour -- one call in which an AlphaFold 3 JSON input inherited model_name
"multimer" from the protein fold beside it. That expectation was the bug, so it
is updated rather than preserved.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…obal

Both batch scripts imported a 1027-line CLI as a library and called
create_arguments(), whose job is to mutate the module-global FLAGS by filling in
database paths, then called create_pipeline_af3() and get_af3_feature_metadata(),
which read that mutation back. The interface between the scripts was the shape of
a global and was correct only if the three calls happened in that order.

alphapulldown/af3_pipeline.py states the same thing as data: AF3PipelineSettings
resolves every binary and database path once and writes nothing back, and carries
resolved_flag_values so provenance can record the paths actually used without a
global having been rewritten to hold them. The database path resolver is injected,
so the module does not depend on the CLI it came out of.

create_pipeline_af3() keeps its signature and error, so existing callers are
unaffected; get_af3_feature_metadata() gains an optional flag_values argument. The
batch scripts no longer call create_arguments() at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@DimaMolod
DimaMolod marked this pull request as ready for review September 6, 2026 06:59
@DimaMolod
DimaMolod merged commit 2a99ad0 into main Sep 6, 2026
6 checks passed
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@DimaMolod
DimaMolod deleted the fix/per-fold-flags-and-af3-pipeline-seam branch September 6, 2026 06:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant