Promote secondary when primary alignment fails to surject#4973
Promote secondary when primary alignment fails to surject#4973gaoj66-roche wants to merge 4 commits into
Conversation
Add --promote-secondary to vg surject, giraffe, map, and mpmap. When a read's primary alignment fails to surject (becomes unmapped) but a secondary surjects, the best-scoring mapped, non-supplementary secondary is promoted to primary instead of emitting an unmapped primary alongside mapped secondaries. Only alignments already present are considered with --max-multimaps > 1. For standalone vg surject, input must be collated by read name. A grouped parallel reader keeps each read's primary and secondaries in one batch, never splitting a group across worker threads (may exceed the batch size, enabled only when promotion is on). A one-time warning explains when no surjectable secondary is found: input not collated, or reads generated without secondaries (--max-multimaps). Point the libvgio submodule at the fork branch carrying the group-aware parallel iterator. Promote best surjectable secondary pair when paired primary fails to surject Extend --promote-secondary to paired-end HTSlib output. When both mates of a read pair's primary alignment fail to surject but a secondary pair surjects, the secondary pair with the highest summed mapped-mate score is promoted into the primary slot (ties broken toward fully-mapped pairs), instead of emitting an unmapped primary pair alongside mapped secondaries. A candidate pair is eligible if at least one mate surjected; half-mapped pairs are used only when no fully-mapped secondary pair exists. Mates are kept index-aligned and is_secondary flags updated on both promoted and demoted pairs. Only alignments already present are considered; no realignment is performed. Supports subcommands that can produce SAM/BAM/CRAM output. vg surject with GAF input is not supported because GAF does not handle secondary alignments.
|
A few questions and thoughts
|
|
I think promoting the secondary alignment to the primary surjection is the right idea, at least in some workflows like copy number calling where you don't actually want the read to be at its true location when the true location is not in the linear reference. @Sagorikanag in our lab has been thinking about this in the context of surjecting to a diploid reference, and has some ideas on handling mapping quality in a way that can encompass both uncertainty around which graph placement is the true source and uncertainty around which surjection is the true source. Maybe she has ideas here? |
|
I have been working on a related approach for diploid surjection (Mapping to a pangenome graph containing a donor specific diploid assembly (DSA) and linear references, then surjecting back to the diploid DSA) that may also help with the promoted-secondary MAPQ problem. I group all consecutive GAM/GAF records with the same read name so that the primary and retained secondary graph placements are processed together. Each graph placement is then surjected to all overlapping target paths (Anything that is set as REF in the graph, for me that is the DSA). For every individual graph placement, I calculate a haplotype quality (HQ) by comparing the scores of that placement's haplotype-path surjections. I also add haplotype tags identifying the preferred and alternative haplotype surjections, currently represented as After that, I pool the surjections produced from all graph placements for the read and calculate a separate global quality across the complete retained candidate set. This global step selects exactly one overall primary surjection and marks the remaining non-supplementary candidates as secondary. The original graph mapping quality is also retained in a separate tag before the output MAPQ is replaced. (Right now we cap the Global Quality at the reads' Mapping Quality, but that is something we're working on) So in this step we see many secondary graph placements yielding us the global primary surjection including when the primary graph placement remains unsurjected. For paired-end reads, the implementation also incorporates the estimated fragment-length distribution when evaluating the paired candidates. This would not recreate the mapper's original MAPQ exactly, because at the surjection stage we still only have the retained Would you be interested in this? |
|
@gaoj66-roche I also checked with @Sagorikanag and as part of the work she's been doing here at UCSC on her thesis project, involving diploid-reference surjection and these new notions of quality, she also has her own implementation of the grouped IO stuff that you're proposing in vgteam/libvgio#92, to support her in-progress implementation of a diploid mode for I haven't seen her code recently, but apparently her grouped input implementation in libvgio handles both GAF and GAM and shares a little more code with the existing codepaths, so I think it might be better to take her implementation instead, depending on what it looks like, and then get your feature here to sit on top of that. It might be possible that, if we can land her diploid surject changes in vg soon, the whole I talked to her and she's going to get that work up as PRs as soon as she can. Then we can read through everything and figure out how to merge everything together in the most parsimonious way. I want to get you all at Roche the feature you need, without creating a jillion merge conflicts between our grad student and her thesis. |
|
Thanks both! I am happy to put this PR on hold till @Sagorikanag 's grouping iterator implementation and everything else is merged and rebase my PR with that. I also agree with @adamnovak that the MAPQ should ideally capture the confidence of both the mapping in the graph space and the linear space but it could potentially be a larger change than what is necessary to address the current issue of secondary with unmapped primary. In my current PR, I also added a tag to the primary alignments promoted from a secondary due to the original primary failing surjection so that downstream tools can decide if they want to treat them differently or even use them at all. I think it would be useful (at least until we can figure out how to assign a consistent and meaningful MAPQ to promoted secondaries) to have some way of distinguishing promoted primaries from a real primary. Another possiblity would be to not strip the secondary flag at all and only append a tag to let downstream tools decide whether it wants to treat it as a secondary or primary. This is probably the lowest-risk approach since many variant callers already discard secondary alignments by default so the secondary promotion feature would be less likely to cause any regression in other tools that use vg aligned BAMs as input, unless they deliberately decide to use the promoted alignments. Please let me know what you all think and keep me posted on any discussion/decision related to this. Thanks! |
Changelog Entry
To be copied to the draft changelog by merger:
--promote-secondarytovg surject,giraffe,map, andmpmapfor promoting a read's secondary alignment to primary alignment when the primary alignment fails to surject (becomes unmapped)Description
When a read's primary alignment fails to surject (becomes unmapped) but a secondary surjects, the best-scoring mapped, non-supplementary secondary is promoted to primary instead of emitting an unmapped primary alongside mapped secondaries, which can be considered a violation of the BAM/SAM spec and cause issues with variant calling in regions where a duplication event is present in the pangenome but not the linear reference. This PR adds a CLI option to handle this situation. When enabled, we will "promote" the surjectable secondary alignment and replace the unsurjectable (unmapped) primary alignment with an auxiliary tag
ps(promoted secondary) to indicate that it is promoted from a secondary alignment.Only alignments already present are considered with --max-multimaps > 1 (and the user will be warned if
--promote-secondaryis enabled without--max-multimaps> 1).For standalone
vg surject, input must be collated by read name. A grouped parallel reader keeps each read's primary and secondaries in the same group within a batch, never splitting a group across worker threads. In order to support this new type of parallelism, a group-aware parallel iterator is added to libvgio (See vgteam/libvgio#92). vg surject with GAF input is not supported because GAF does not handle secondary alignments and it is not possible to distinguish a secondary alignment from a primary alignment in a GAF file.One important caveat for the
vg surjectcommand is that the input has to be collated (alignments with the same query name must be adjacent to each other). I admit that this is a bit awkward since we don't have a tool for sorting GAM by query name so the only way to get a collated GAM right now is directly from output of the aligner. Once a GAM file is sorted by graph position, it would not possible to recover the collated GAM if the user deletes the original aligner output. I might add the ability to sort alignments by query name or collate alignments to gamsort in the future to keep the scope of this PR focused on secondary promotion during surjection.