Closed rickymagner closed 7 months ago
nice sleuthing work @rickymagner! IIANM, I'm largely responsible for the lift-over of indels, and so if I can help, let me know.
Hi @yfarjoun, if you do have some time to look at this, that would be great. I suspect the part of the code causing this error is located in LiftoverUtils.java
at L389 here:
// 5. if there exists an empty allele then
if (alleleBasesMap.values().stream()
.map(a -> a.length)
.anyMatch(l -> l == 0)) {
// 6. extend alleles 1 nucleotide to the left
for (final Allele allele : alleleBasesMap.keySet()) {
// the first -1 for zero-base (getBases) versus 1-based (variant position)
// another -1 to get the base prior to the location of the start of the allele
final byte extraBase = (theStart > 1) ?
referenceSequence.getBases()[theStart - 2] :
referenceSequence.getBases()[theEnd];
alleleBasesMap.put(allele, extendOneBase(alleleBasesMap.get(allele), extraBase));
}
changesInAlleles = true;
theStart--;
// 7. end if
}
The theStart - 2
looks like it could suspiciously lead to a string index becoming -1 when theStart == 1
, but this could also be a red herring since the conditional which triggers this block might not be satisfied by the given variant. I haven't been able to look too deeply at the code around here to understand what's actually happening.
This is not the moment the stacktrace is thrown of course, but I'm wondering if it's the place where that -1 appears and then propagates further to the moment later in tryToAddVariant
where the string constructor is given index -1 to start which triggers the error. Otherwise I'm not sure how that number would ever become -1 yet.
I'll see what I can do. do you have a test-case that fails? I know you got a vcf from a user, but have you converted it to an additional unit test? I think that would be a good first step, so if you did it, please point me to it, if not, I can try my hand.
Thanks. Yes, I would take the files from the issue above (the JP ref + chain file linked from the public URL; should be small enough to download), and then take the bad deletion variant I wrote on chr17 and add an hg38 header to it. Any header should be fine, but didn't want to post a complete example since there's 3k contigs there. I haven't turned it into a formal Java test yet, but might be able to try that this week (using the example above, or rewriting one using whatever resource files we already have in the test suite).
This is resolved by #1933
I suppose it is resolved by https://github.com/broadinstitute/picard/pull/1956
I hope so! Let us know, please.
On Fri, Apr 12, 2024 at 1:54 AM Sergey Mitrofanov @.***> wrote:
I suppose it is resolved by #1956 https://github.com/broadinstitute/picard/pull/1956
— Reply to this email directly, view it on GitHub https://github.com/broadinstitute/picard/issues/1951#issuecomment-2051029310, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAU6JURFL67VLRTLE4XI523Y45ZIJAVCNFSM6AAAAABFEGIHP6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANJRGAZDSMZRGA . You are receiving this because you were mentioned.Message ID: @.***>
@serge2016 I checked it works for the specific edge case variant I found before. Let us know if there are any other variants that give an issue if you try to rerun on it. I'm not sure when the next Picard release will be, but you can test building from master
if you're interested in seeing if the new version of the tool can get through your entire file.
Bug Report
Affected tool(s)
LiftoverVcf
Affected version(s)
Description
This was discovered in trying to debug #1933. There is an edge case in lifting over deletions when they contract a tandem repeat close to the edge of the resulting liftover contig. Consider the entry in a real chain file (details in the steps to reproduce below on where files live):
Next consider the variant:
The 7 bases on chr17 from 22533036 are: GTATATG, and the first 6 bases on contig unplaced_85 are: ATATACAT. The chain file says that the GTATAT on chr17 corresponds to ATATAC on unplaced_85. The deletion as written in the input VCF corresponds to ATA--C in unplaced_85. When left aligned (as happens in the algorithm), this looks like A--TAC, so should be recorded as:
But instead, LiftoverVcf throws an error (see stacktrace below) about a string index out of bounds.
I suspect there is a bug in our left aligning step, but can't see it yet from the code. There is a
start - 2
inLiftoverUtils.leftAlignVariant
which looks suspicious, but I haven't pinned that down as the direct cause yet.Here are some experiments playing with the DEL length:
The fact that the smaller "odd" deletions work but the full contractions don't highly suggests something strange is happening during the left alignment after liftover. But the code is a bit complex so it'll take some digging.
Steps to reproduce
Grab an hg38 VCF header and record this variant as the sites-only VCF
special_variant.vcf.gz
:Then take the JG2.1.0 reference here with chain file here. Save these to
ref.fa.gz
andlift.chain
. Get the right ref indices ready. Then runYou will see the stacktrace:
Expected behavior
If a variant gets left aligned to the start of a contig, we should handle that either with a uniform algorithm that works everywhere or as a special case.
Actual behavior
The user sees an uninformative stack trace.