Skip to content

Question about SyncmerIterator #463

Description

@drtconway

Hi,

I'm studying your implementation of SyncmerIterator, and I'm a bit confused. It's possible there's a bug in the code, but I think it's much more likely that I just don't understand the intended semantics correctly.

The code runs accumulators for for the current k-mer and the current s-mer, keeping both the forward and reverse complement *-mers, which makes sense.

It then makes a canonical choice of which s-mer to hash, and adds that to the queue.

What follows is a set of cases that evaluate or re-evaluate the position of the minimising s-mer.

The first question I have is whether it matters that the branch at

if (qs.size() == k - s + 1) { // We are at the last s-mer within the first k-mer, need to decide if we add it
and the branch at
for (int j = qs.size() - 1; j >= 0; j--) { //Iterate in reverse to choose the rightmost minimizer in a window
iterate in opposite directions? In the case of equal hashes, they will select a different minimum position, which could result in the selection of different strobemers. It is a very corner case, I concede, since the former branch in the code handles the very first k-mer, but unless I'm wrong, this could result in inconsistent strobmer choice. This is really a very minor detail, but I mention it since I have been examining the area of the code in detail.

The more important question pertains to the canonical choice of k-mers. I note that the code at

uint64_t yk = std::min(xk[0], xk[1]);
makes a canonical choice between the forward and reverse complement sequences, and reports that hash as the syncmer.

However, if I present the code with the reverse complement of the original sequence, the same set of s-mers will be derived, but in the opposite order, so that the position of the minimiser will be at the opposite end of the queue, and so the test will not pass.

My understanding of the intended semantics is that the set of syncmers would be the same regardless of which strand the original sequence is on, and certainly by reporting the hash of the min k-mer, the code creates that impression.

I'd love to understand where my reasoning has gone off the rails!

Thanks,

Tom.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions