Skip to content

Commit

Permalink
Fixed a bug where invalid feature file intervals weren't being checke…
Browse files Browse the repository at this point in the history
…d for validity against the sequence dictionary (#7295)

* Fixed a bug where invalid feature file intervals weren't being checked for validity against the sequence dictionary

Resolves #7289
  • Loading branch information
jamesemery authored Jun 22, 2021
1 parent 56beec4 commit 7893010
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,10 @@ private boolean overlapsKnownCNV(VariantContext cnv, VariantEvalContext context)
if ( knownCNVs != null ) {
List<Feature> overlaps = context.queryFeaturesIncludingOverlapping(knownCNVs, new SimpleInterval(cnv.getContig(), cnv.getStart(), cnv.getEnd()));
GenomeLocParser parser = new GenomeLocParser(context.getSequenceDictionaryForDrivingVariants());
GenomeLoc loc1 = parser.createGenomeLoc(cnv);
// NOTE: by using this overload we are explicitly allowing variants that don't correctly overlap the reference intervals
GenomeLoc loc1 = parser.createGenomeLoc(cnv, false);
for (Feature vc : overlaps) {
GenomeLoc loc2 = parser.createGenomeLoc(vc);
GenomeLoc loc2 = parser.createGenomeLoc(vc, false);
final double overlapP = loc1.reciprocialOverlapFraction(loc2);
if ( overlapP > MIN_CNV_OVERLAP )
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,15 @@ public GenomeLoc createGenomeLoc( final GATKRead read ) {
* @return
*/
public GenomeLoc createGenomeLoc(final Feature feature) {
return createGenomeLoc(feature.getContig(), feature.getStart(), feature.getEnd());
return createGenomeLoc(feature.getContig(), feature.getStart(), feature.getEnd(), true);
}

/**
* Creates a GenomeLoc from a Tribble feature
* @return
*/
public GenomeLoc createGenomeLoc(final Feature feature, final boolean mustBeOnReference) {
return createGenomeLoc(feature.getContig(), feature.getStart(), feature.getEnd(), mustBeOnReference);
}

/**
Expand All @@ -405,7 +413,7 @@ public GenomeLoc createGenomeLoc(final Feature feature) {
*/
public GenomeLoc createGenomeLoc(final Locatable locatable) {
Utils.nonNull(locatable, "the input locatable cannot be null");
return createGenomeLoc(locatable.getContig(), locatable.getStart(), locatable.getEnd());
return createGenomeLoc(locatable.getContig(), locatable.getStart(), locatable.getEnd(), false);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ public static List<GenomeLoc> featureFileToIntervals( final GenomeLocParser pars
final List<GenomeLoc> featureIntervals = new ArrayList<>();

for ( final Feature feature : dataSource ) {
featureIntervals.add(parser.createGenomeLoc(feature));
featureIntervals.add(parser.createGenomeLoc(feature, true));
}
return featureIntervals;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,29 @@ public void testUseAllHG38ContigsInIntervalQuery() {
);
}

@Test(expectedExceptions = UserException.MalformedGenomeLoc.class)
public void testReasonableErrorWithInvalidBedFile() throws IOException {
File outOfBoundsBedFile = new File(INTERVAL_TEST_DATA + "bad_hg19_interval_span.bed"); // this bed file has a bogus interval the extends past the end chr1 and should throw an exception
// this should throw a user exception because of the invalid interval
IntervalUtils.parseIntervalArguments(hg19GenomeLocParser, outOfBoundsBedFile.getAbsolutePath());
}

@Test(expectedExceptions = UserException.MalformedGenomeLoc.class)
public void testReasonableErrorWithInvalidListFile() throws IOException {
File outOfBoundListFile = new File(INTERVAL_TEST_DATA + "bad_hg19_example_intervals.list"); // this list file has a bogus interval the extends past the end chr1 and should throw an exception
// this should throw a user exception because of the invalid interval
IntervalUtils.parseIntervalArguments(hg19GenomeLocParser, outOfBoundListFile.getAbsolutePath());
}

//NOTE the .interval_list style argument input gets handled differently from the other -L inputs but we still get a reasonable exception in this case
@Test(expectedExceptions = UserException.MalformedFile.class)
public void testReasonableErrorWithInvalidPicardListFile() throws IOException {
File outOfBoundsIntervalListFile = new File(INTERVAL_TEST_DATA + "bad_hg19.interval_list"); // this list file has a bogus interval the extends past the end chr1 and should throw an exception
// this should throw a user exception because of the invalid interval
IntervalUtils.parseIntervalArguments(hg19GenomeLocParser, outOfBoundsIntervalListFile.getAbsolutePath());
}


@Test
public void testResolveAmbiguousIntervalQueryUsingBEDFormat() throws IOException {
// For the rare case where an interval query is ambiguous, make sure it can be resolved by using a bed file.
Expand Down
Loading

0 comments on commit 7893010

Please sign in to comment.