Skip to content

Move brwt and row_diff_brwt annotations to an equal-k-mer graph with transform_anno --remap-graph - #729

Merged
adamant-pwn merged 5 commits into
masterfrom
remap-annotation-rows
Nov 9, 2026
Merged

adamant-pwn merged 5 commits into
masterfrom
remap-annotation-rows

Conversation

@adamant-pwn

@adamant-pwn adamant-pwn commented Nov 8, 2026 •

Copy link
Copy Markdown
Member

Existing annotations can now move to another graph with the same k-mers without annotating it again. The motivating case is serving the UHGG and gnomAD indexes with SSHash graphs. Re-annotating them would need the original genome files, could take days, and would not reproduce the relaxed and relabeled production annotation.

metagraph transform_anno --remap-graph old.dbg -i new.sshashdbg -o out anno.row_diff_brwt.annodbg matches rows by k-mer. It keeps the BRWT tree, the column order and every relation. Dropped rows, such as succinct dummy nodes, lose nothing because they hold no k-mer. For row_diff_brwt, each row keeps its successor from the old graph. The command writes those successors as the new successor bitmap, so query results are identical. The command stops if the graphs differ in any k-mer or if a non-anchor row would lose its successor.

Both graphs must be in basic mode. The row map is saved as out.rowmap. A rerun with the same output name reuses it and skips matching the rows again. Before reusing it, the command checks the row counts and 10,000 sample rows against both graphs.

With --anno-type row_diff_flat or row_diff_disk, a remapped row_diff_brwt annotation is converted in the same run, after the row map and the old graph are freed. Any other --anno-type is rejected.

I tested the same remap code on gnomAD, built on the older SSHash version that made its graph. The source had 29.0 B rows and the SSHash graph had 23.1 B nodes. The remap took 2 h 45 min on 32 threads with a peak RSS of 172 GB, of which about 2 h was the row map. --query-mode labels output for 5,747 contigs was identical before and after.

The full UHGG annotation (33.0 B nodes, 287 k labels) took 1 h 42 min on 64 threads with a peak RSS of 249 GB. Query output on two disjoint samples of about 5,100 contigs each was identical before and after.

I used Claude Code to write this change.

🤖 Generated with Claude Code

…ap-graph

Remaps a brwt or row_diff_brwt annotation from one basic-mode graph to
another with the same k-mers, for example from a succinct graph to an
SSHash graph, without rebuilding the annotation. Rows are matched by
k-mer, the BRWT keeps its topology and column order, and row-diff
successors are carried over from the source graph. The row map is saved
next to the output and reused on a rerun.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 11 files

Architecture diagram
sequenceDiagram
    participant CLI as CLI transform_anno
    participant Cfg as Config
    participant Src as Source Graph (basic)
    participant Tgt as Target Graph (SSHash)
    participant RM as Row Map (.rowmap)
    participant Ann as Annotation (BRWT/RowDiff)
    participant BRWT as BRWT Matrix
    participant RD as RowDiff Matrix

    CLI->>Cfg: Parse --remap-graph <src> -i <tgt>
    Cfg->>CLI: Validate args (remap_graph set, one anno, -i graph)
    CLI->>CLI: Check annotation type is BRWT or RowDiffBRWT

    CLI->>Src: Load source graph
    alt Row map file exists
        CLI->>RM: Load .rowmap
        RM-->>CLI: row_map + target_num_rows + target_file_size
        CLI->>CLI: Verify row_map size == source.max_index()
        CLI->>CLI: Verify target_file_size == file_size(-i graph)
    else No row map file
        CLI->>Tgt: Load target graph
        CLI->>Src: map_rows_to_graph(source, target, threads)
        Src->>Src: call_sequences over source
        Src->>Tgt: map_to_nodes_sequentially per k-mer
        Tgt-->>Src: target node index per source row
        Src->>Src: Build row_map (source row -> target row + 1)
        Src->>Tgt: Verify all target nodes matched exactly once
        alt Missing/repeated k-mers
            Src-->>CLI: Error: "graphs have different k-mers"
            CLI->>CLI: exit(1)
        end
        CLI->>RM: Serialize row_map + target_num_rows + target file size
    end

    CLI->>Ann: Load annotation from file
    CLI->>CLI: remap_annotation_rows(annotation, source, row_map, target_num_rows)

    alt Annotation is BRWT
        Ann->>BRWT: remap_rows(row_map, target_num_rows)
        BRWT->>BRWT: Remap root nonzero_rows index
        BRWT->>BRWT: Recursively remap children in parallel (OpenMP tasks)
        BRWT-->>CLI: New BRWT matrix with reordered rows
    else Annotation is RowDiffBRWT
        Ann->>RD: Access anchor + fork_succ bitmaps
        RD->>RD: For each row: find successor in source graph
        RD->>CLI: Build new_anchor + new_succ bitmaps for target
        alt Non-anchor row loses successor
            RD-->>CLI: Error: "rows have dropped successor"
            CLI->>CLI: exit(1)
        end
        RD->>BRWT: remap_rows(row_map, target_num_rows) for diffs
        CLI->>RD: Set new anchor and successor bitmaps
        RD-->>CLI: New RowDiff matrix
    end

    CLI->>CLI: Serialize remapped annotation to output
    CLI-->>CLI: Success
Loading

Shadow auto-approve: would not auto-approve because issues were found.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread metagraph/docs/source/quick_start.rst Resolved
… checking it

A reused row map is now checked against both graphs: row counts and a
sample of 10,000 rows looked up by k-mer. This replaces the target file
size check. Also close the row map stream before checking for write
errors, document the lost-successor error and list the RowMap types that
remap_rows supports.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 7 files (changes from recent commits).

Shadow auto-approve: would not auto-approve because issues were found.

View guided diff | Turn on auto-fix | Re-trigger cubic

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would require human review. Adds a new transform_anno --remap-graph feature for moving BRWT/row_diff_brwt annotations between same-k-mer graphs, with row-map reuse and tests. This is a new user-facing feature with complex annotation-core semantics and operational tradeoffs, so a human should review the design before merging.

View guided diff | Turn on auto-fix | Re-trigger cubic

…iff_disk in the same run

With --remap-graph, --anno-type row_diff_flat or row_diff_disk converts the
remapped annotation in memory after the row map and source graph are freed.
Any other --anno-type is rejected instead of being ignored.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files (changes from recent commits).

Shadow auto-approve: would not auto-approve because issues were found.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread metagraph/docs/source/quick_start.rst Resolved
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 1 file (changes from recent commits).

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Shadow auto-approve: would require human review. New transform_anno --remap-graph feature moves BRWT/row_diff_brwt annotations between equal-k-mer graphs and converts them in the same run. User-facing feature with core data-integrity semantics and heavy operational tradeoffs; needs human design review.

View guided diff | Turn on auto-fix | Re-trigger cubic

@adamant-pwn
adamant-pwn merged commit 011b311 into master Nov 9, 2026
54 checks passed
@adamant-pwn
adamant-pwn deleted the remap-annotation-rows branch November 9, 2026 15:15
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