Add Harun's redone aligner as opt-in engine with pymetagraph bindings

Draft
AD
18h ago
+7107-47

Add Harun's redone alignment engine (graph/alignment_redone) as opt-in code, together with the pymetagraph Python binding that adaptive-sampling experiments use. metagraph align, the server and query --align keep using the existing aligner, so default behaviour does not change.

This replaces the previous contents of this branch. The branch now merges Harun's last align_refactor commit (2d1734717, Nov 2025) into current master, plus Sayan's LabeledSeeder::get_anchors fix. Sayan's experiments ran on exactly this engine. The October 2026 changes are preserved on codex/align_refactor-oct2026 and can come back one at a time where they are worth keeping.

Changes relative to Harun's commit:

  • SSHash sub-k seeding removed. It depended on an SSHash fork commit that master no longer pins. SSHash graphs now seed like hash graphs.
  • --separate-header left out. That annotation feature is ported separately on feature/separate-header.
  • One shared options initialiser. The old and new engines' identical option initialisers now share one template; initialize_redone_aligner_config serves the new engine.
  • One canonical-graph test skipped for protein, as the existing aligner tests already do.

The Python extension builds only with -DBUILD_PYTHON_BINDINGS=ON. That option compiles position-independent static libraries, uses shared Boost and drops jemalloc. The default static build is unchanged.

Local checks (GCC 16, Release):

  • DNA unit tests: 3904/3904
  • Protein unit tests: 3197/3197
  • Alignment tests: DNA 368/368, Protein 337/337
  • Compared with a build of sg/readfish-bindings on the same k=31 graph, annotation and 350 simulated reads, per-read results are byte-identical in five of the six binding modes (align, query, align without annotation, without extension, full-k seeds). connect_anchors=False now differs by design: before the fix below it was ignored when chains were extended. 278/350 rows are identical and 342/350 have the same label; the differing rows report shorter spans.

Fixes from a review of this PR (all also present in Harun's commit):

  • connect_anchors=False was ignored with extension. align_query now passes it on. Chains whose anchors are not connected keep placeholder nodes between anchors; the extender reports those chains unextended instead of crashing on them.
  • Query::generate_rc reverse-complemented the not-yet-constructed member instead of the local copy. It worked only because the compiler constructs the result in place; the tests now cover reverse-complement queries on BASIC graphs.
  • query_batch: a read that throws (for example "Failed to connect anchors") is now logged and reported as unmapped instead of failing the batch while other tasks still write into it.
  • The binding docs no longer claim that metagraph align or the server's /align use this engine.

Known limitations:

  • Invalid options or missing graph/annotation files make metagraph's config parser and loaders call exit(), which ends the Python process instead of raising.
  • The engine ignores the alignment work caps (alternative paths, nodes per query character, RAM per alignment). The binding accepts max_alternative_alignments and max_num_nodes_per_seq_char without effect.

Not yet tested: integration tests, Sayan's real data, and installing the binding with pip.

AnnotationKeyMapper came from #683, now merged into master. The new engine maps its annotation rows through it, and this PR only adds the mapper's SSHash shortcut (DBGSSHash::get_base_node).

šŸ¤– Generated with Claude Code