Skip to content

Type annotations and unit tests for the shared utils layer and rf3#320

Closed
lyskov-ai wants to merge 11 commits into
RosettaCommons:productionfrom
lyskov-ai:0037-foundry-alignment-weights-mypy-strict-and-tests
Closed

Type annotations and unit tests for the shared utils layer and rf3#320
lyskov-ai wants to merge 11 commits into
RosettaCommons:productionfrom
lyskov-ai:0037-foundry-alignment-weights-mypy-strict-and-tests

Conversation

@lyskov-ai

Copy link
Copy Markdown
Contributor

Adds type annotations and tests to the shared foundry.utils layer and CPU unit tests for rf3, with no intended behaviour change — part of an ongoing effort to get the codebase under type-checking and test coverage ahead of a larger refactor.

Shared layer (src/foundry/utils)

  • Fully annotated rigid.py, components.py, torch.py, alignment.py, and weights.py, and enabled strict type-checking for them (every function annotated, function bodies checked). Annotation-only, plus a couple of behaviour-preserving cleanups in components.py and an axis=dim= swap in get_rmsd (equivalent torch keyword).
  • New unit tests pinning the pure logic: rotation/rigid-transform geometry (test_rigid.py), the contig/component parsing grammar (test_components.py), tensor helpers (test_torch_utils.py), and the checkpoint weight-loading policies (test_weight_loading.py).

rf3

  • New fixture-backed CPU unit tests for pure rf3 logic (no source changes): the diffusion-sampler noise schedule, the outer-product / triangle-attention / mlff layers, closed-form loss gradients and util_module helpers, the af3_losses symmetry-resolution helpers, and the chiral / iPTM metric orchestration.
  • Annotating the shared weighted_rigid_align exposed a loosely-typed caller in rf3/utils/io.py (dump_trajectories); resolved with a documented cast at the call site.
  • Moved the type-check suppression for the (currently import-broken) rf3/data/paired_msa.py from a central config list into a file-level directive in the module, so the suppression sits where the affected code is.

All committed tests run on CPU with small inline fixtures (no cluster data, GPU, or checkpoints).

lyskov and others added 11 commits June 9, 2026 17:49
…_module

Cover the pure numeric helpers in rf3.loss.loss and rf3.util_module:

- calc_ddihedralmse_dxyz: the hand-derived closed-form dihedral-loss
  gradient, pinned against torch.autograd of a mirrored forward, plus
  zero-at-truth and leading-dim shape preservation.
- calc_chiral_grads_flat_impl: empty-centres, scatter routing onto only
  the centre atoms, index_add_ accumulation for shared atoms, and the
  no_grad_on_chiral_center flag.
- rbf: Gaussian distance-encoding (feature dim, exact values, [0,1]).
- init_lecun_normal: module returned, Parameter weight, +/-2*stddev
  bound, and Lecun std sqrt(scale/fan_in).

Test-only; both modules are already mypy-clean. Tests run in float32
(the production coordinate dtype).

Co-authored-by: lyskov-ai <277346777+lyskov-ai@users.noreply.github.com>
Co-authored-by: lyskov-ai <277346777+lyskov-ai@users.noreply.github.com>
…duct layer

Co-authored-by: lyskov-ai <277346777+lyskov-ai@users.noreply.github.com>
Co-authored-by: lyskov-ai <277346777+lyskov-ai@users.noreply.github.com>
…helpers

Co-authored-by: lyskov-ai <277346777+lyskov-ai@users.noreply.github.com>
Co-authored-by: lyskov-ai <277346777+lyskov-ai@users.noreply.github.com>
Replace the central pyproject ignore_errors override for rf3.data.paired_msa with a file-level '# mypy: ignore-errors' directive in the module itself. The module is broken against the installed atomworks (subclasses a now-function) and needs a PandasDataset-API refactor to clear honestly; keeping it in mypy's files scope with an in-file directive makes the suppression visible at the point of breakage and re-enables checking the moment the directive is removed.

Co-authored-by: lyskov-ai <277346777+lyskov-ai@users.noreply.github.com>
…it tests

Bring src/foundry/utils/rigid.py under a per-module disallow_untyped_defs +
check_untyped_defs override (the first Track 1 direction-(b) strictness slice) by
annotating its ~47 previously-untyped Rotation/Rigid methods and quaternion/matrix
helpers. Annotation-only, no behaviour change; self-references use string forward-refs
and the identity helpers' shape params are widened to Tuple[int, ...].

Add tests/test_rigid.py: 33 fixture-backed CPU unit tests pinning the pure geometry
(quat<->matrix round-trips, compose/invert, apply, the 4x4/7-vector encodings, and
from_3_points) against independent references.

Co-authored-by: lyskov-ai <277346777+lyskov-ai@users.noreply.github.com>
…g tests

Bring src/foundry/utils/components.py under the per-module disallow_untyped_defs +
check_untyped_defs override by annotating the contig parsers and mask getters.
Annotation-only apart from two behaviour-preserving refactors (collapse a str->int
variable reuse in split_contig; store fixed_parts as tuples to avoid object-typed
heterogeneous lists). Also widen get_name_mask's query_names to str | list[str] to
match the isinstance branch and docstring.

Add tests/test_components.py: 25 unit tests pinning the contig/component parsing
grammar (split_contig, extract_pn_unit_info, get_motif_components_and_breaks,
get_design_pattern_with_constraints) and the get_name_mask atom selector.

Co-authored-by: lyskov-ai <277346777+lyskov-ai@users.noreply.github.com>
Bring src/foundry/utils/torch.py under the per-module disallow_untyped_defs +
check_untyped_defs override by annotating map_to's kwargs, the tracer-warning
contextmanager, assert_shape, and the Timer/Timers methods. Annotation-only; the
two warnings.filters mutations carry a documented type: ignore[attr-defined]
(typeshed types it immutable, but it is a list at runtime).

Extend tests/test_torch_utils.py with 12 tests for the untested pure helpers:
scatter_mean, assert_shape/assert_same_shape, device_of, and Timer/Timers.

Co-authored-by: lyskov-ai <277346777+lyskov-ai@users.noreply.github.com>
…d unit tests

Add foundry.utils.alignment and foundry.utils.weights to the per-module
strict-mypy override (disallow_untyped_defs + check_untyped_defs) and
annotate their untyped definitions:

- alignment.py: weighted_rigid_align / get_rmsd / the dead superimpose
  stub. get_rmsd's torch.sum(..., axis=) -> dim= (torch numpy-compat
  alias; the stubs only declare dim, behaviour-identical).
- weights.py: -> None on the two __post_init__ methods.

Annotating weighted_rigid_align's params honestly as torch.Tensor
surfaced a real arg-type mismatch in rf3's dump_trajectories (param
loosely typed list[torch.Tensor | np.ndarray], body tensor-only);
resolved with documented cast(torch.Tensor, ...) at the alignment
call site.

Extend tests/test_weight_loading.py with 3 tests for documented but
untested behaviour: the '?' and '[...]' glob wildcards plus literal-dot
escaping, and the COPY-policy missing-parameter fallback chain.

Co-authored-by: lyskov-ai <277346777+lyskov-ai@users.noreply.github.com>
@lyskov-ai lyskov-ai requested a review from woodsh17 June 10, 2026 18:07
@lyskov-ai

Copy link
Copy Markdown
Contributor Author

Closing as redundant: this PR's cumulative diff is fully contained in #321, which was squash-merged into production (commit e412591). All of its changes are now in production.

@lyskov-ai lyskov-ai closed this Jun 16, 2026
@lyskov-ai lyskov-ai deleted the 0037-foundry-alignment-weights-mypy-strict-and-tests branch June 16, 2026 19:50
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.

2 participants