Skip to content
This repository has been archived by the owner on Jan 24, 2024. It is now read-only.

Commit

Permalink
Adding explicit support for SV/CNV calling tools (#68)
Browse files Browse the repository at this point in the history
Closes: #68
Related-Issue: #68
Projected-Results-Impact: none
  • Loading branch information
holtgrewe committed Sep 13, 2022
1 parent 753aea5 commit e09f0d4
Show file tree
Hide file tree
Showing 18 changed files with 893 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.github.bihealth.varfish_annotator.annotate_svs;

import htsjdk.variant.vcf.VCFHeader;

public abstract class CallerSupportBase {
public abstract SvCaller getSvCaller();

public abstract boolean isCompatible(VCFHeader vcfHeader);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.github.bihealth.varfish_annotator.annotate_svs;

import htsjdk.variant.vcf.VCFFilterHeaderLine;
import htsjdk.variant.vcf.VCFHeader;
import htsjdk.variant.vcf.VCFInfoHeaderLine;

/** Import SV caller support for Delly2. */
public class CallerSupportDelly2 extends CallerSupportBase {

public SvCaller getSvCaller() {
return SvCaller.DELLY2_SV;
}

public boolean isCompatible(VCFHeader vcfHeader) {
final VCFFilterHeaderLine lowQualFilter = vcfHeader.getFilterHeaderLine("LowQual");
boolean seenLowQualFilter = (lowQualFilter != null);
final VCFInfoHeaderLine ctInfo = vcfHeader.getInfoHeaderLine("CT");
boolean seenCtInfo = (ctInfo != null);
final VCFInfoHeaderLine impreciseInfo = vcfHeader.getInfoHeaderLine("IMPRECISE");
boolean seenImpreciseInfo = (impreciseInfo != null);

return seenLowQualFilter && seenCtInfo && seenImpreciseInfo;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.github.bihealth.varfish_annotator.annotate_svs;

import htsjdk.variant.vcf.VCFFilterHeaderLine;
import htsjdk.variant.vcf.VCFHeader;
import htsjdk.variant.vcf.VCFHeaderLine;

/** Import SV caller support for Dragen CNV. */
public class CallerSupportDragenCnv extends CallerSupportBase {

public SvCaller getSvCaller() {
return SvCaller.DRAGEN_CNV;
}

public boolean isCompatible(VCFHeader vcfHeader) {
boolean seenDragenVersionHeaderLine = false;
boolean seenDragenCommandLineHeaderLine = false;
for (VCFHeaderLine headerLine : vcfHeader.getOtherHeaderLines()) {
if (headerLine.getKey().equals("DRAGENVersion")) {
seenDragenVersionHeaderLine = true;
} else if (headerLine.getKey().equals("DRAGENCommandLine")) {
seenDragenCommandLineHeaderLine = true;
}
}

final VCFFilterHeaderLine cnvBinSupportRatio =
vcfHeader.getFilterHeaderLine("cnvBinSupportRatio");
boolean seenCnvBinSupportRatioFilter = (cnvBinSupportRatio != null);

return seenDragenVersionHeaderLine
&& seenDragenCommandLineHeaderLine
&& seenCnvBinSupportRatioFilter;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.github.bihealth.varfish_annotator.annotate_svs;

import com.github.bihealth.varfish_annotator.utils.HtsjdkUtils;
import htsjdk.variant.vcf.VCFFilterHeaderLine;
import htsjdk.variant.vcf.VCFHeader;
import htsjdk.variant.vcf.VCFHeaderLine;
import htsjdk.variant.vcf.VCFInfoHeaderLine;

/** Import SV caller support for Dragen SV. */
public class CallerSupportDragenSv extends CallerSupportBase {

public SvCaller getSvCaller() {
return SvCaller.DRAGEN_SV;
}

public boolean isCompatible(VCFHeader vcfHeader) {
boolean seenSourceDragen = false;
for (VCFHeaderLine headerLine : HtsjdkUtils.getSourceHeaderLines(vcfHeader)) {
final String value = headerLine.getValue();
if (value.startsWith("DRAGEN")) {
seenSourceDragen = true;
}
}

final VCFFilterHeaderLine minQualFilter = vcfHeader.getFilterHeaderLine("MinQUAL");
boolean seenMinQualFilter = (minQualFilter != null);
final VCFInfoHeaderLine mateIdInfo = vcfHeader.getInfoHeaderLine("MATEID");
boolean seenMateIdInfo = (mateIdInfo != null);

return seenSourceDragen && seenMinQualFilter && seenMateIdInfo;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.github.bihealth.varfish_annotator.annotate_svs;

import htsjdk.variant.vcf.VCFHeader;
import htsjdk.variant.vcf.VCFInfoHeaderLine;

/** Import SV caller support for generic SV callers. */
public class CallerSupportGeneric extends CallerSupportBase {

public SvCaller getSvCaller() {
return SvCaller.GENERIC;
}

public boolean isCompatible(VCFHeader vcfHeader) {
final VCFInfoHeaderLine svTypeInfo = vcfHeader.getInfoHeaderLine("SVTYPE");
boolean seenSvTypeInfo = (svTypeInfo != null);
final VCFInfoHeaderLine svEndInfo = vcfHeader.getInfoHeaderLine("END");
boolean seenSvTypeEnd = (svEndInfo != null);
final VCFInfoHeaderLine svLenInfo = vcfHeader.getInfoHeaderLine("SVLEN");
boolean seenSvLenEnd = (svLenInfo != null);

return seenSvTypeInfo && seenSvTypeEnd && seenSvLenEnd;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.github.bihealth.varfish_annotator.annotate_svs;

import com.github.bihealth.varfish_annotator.utils.HtsjdkUtils;
import htsjdk.variant.vcf.VCFHeader;
import htsjdk.variant.vcf.VCFHeaderLine;

/** Import SV caller support for Manta. */
public class CallerSupportManta extends CallerSupportBase {

public SvCaller getSvCaller() {
return SvCaller.MANTA;
}

public boolean isCompatible(VCFHeader vcfHeader) {
for (VCFHeaderLine headerLine : HtsjdkUtils.getSourceHeaderLines(vcfHeader)) {
final String value = headerLine.getValue();
if (value.startsWith("GenerateSVCandidates")) {
return true;
}
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.github.bihealth.varfish_annotator.annotate_svs;

/** Enum with explicitely supported SV callers and generic support. */
public enum SvCaller {
DELLY2_SV,
DRAGEN_CNV,
DRAGEN_SV,
GATK_GCNV,
GENERIC,
MANTA,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.github.bihealth.varfish_annotator.utils;

import htsjdk.variant.vcf.VCFHeader;
import htsjdk.variant.vcf.VCFHeaderLine;
import java.util.ArrayList;
import java.util.List;

public class HtsjdkUtils {
public static List<VCFHeaderLine> getSourceHeaderLines(VCFHeader vcfHeader) {
final ArrayList<VCFHeaderLine> result = new ArrayList<>();
for (VCFHeaderLine headerLine : vcfHeader.getOtherHeaderLines()) {
if (headerLine.getKey().equals("source")) {
result.add(headerLine);
}
}
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.github.bihealth.varfish_annotator;

import java.io.*;
import java.util.zip.GZIPInputStream;
import org.apache.commons.io.IOUtils;

/**
* Helper class with static methods for handling resources in tests
*
* @author <a href="mailto:[email protected]">Manuel Holtgrewe</a>
*/
public class ResourceUtils {

/** Helper function for reading resources into memory */
public static String readResource(String path) {
StringWriter writer = new StringWriter();
try {
IOUtils.copy(ResourceUtils.class.getResourceAsStream(path), writer, "UTF-8");
} catch (IOException e) {
throw new RuntimeException("Problem reading resource " + path, e);
}
return writer.toString();
}

/** Copy resource at the given path to the given output {@link File}. */
public static void copyResourceToFile(String path, File outFile) {
try (InputStream input = ResourceUtils.class.getResourceAsStream(path);
OutputStream os = new FileOutputStream(outFile)) {
byte[] buffer = new byte[1024];
int length;
while ((length = input.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} catch (IOException e) {
throw new RuntimeException("Problem with copying resource to file", e);
}
}

/** gzunip resource at the given path to the given output {@link File}. */
public static void gunzipResourceToFile(String path, File outFile) {
try (InputStream inputRaw = ResourceUtils.class.getResourceAsStream(path);
GZIPInputStream input = new GZIPInputStream(inputRaw);
OutputStream os = new FileOutputStream(outFile)) {
byte[] buffer = new byte[1024];
int length;
while ((length = input.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} catch (IOException e) {
throw new RuntimeException("Problem with copying resource to file", e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.github.bihealth.varfish_annotator.annotate_svs;

import com.github.bihealth.varfish_annotator.ResourceUtils;
import htsjdk.variant.vcf.VCFFileReader;
import htsjdk.variant.vcf.VCFHeader;
import java.io.File;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

public class CallerSupportDellySvTest {

@TempDir public File tmpFolder;
File vcfFile;
File otherVcfFile;
CallerSupportDelly2 callerSupport;

@BeforeEach
void initEach() {
vcfFile = new File(tmpFolder + "/vcf-header.vcf");
ResourceUtils.copyResourceToFile("/callers-sv/delly2-head.vcf", vcfFile);
otherVcfFile = new File(tmpFolder + "/incompatible.vcf");
ResourceUtils.copyResourceToFile("/callers-sv/manta-head.vcf", otherVcfFile);
callerSupport = new CallerSupportDelly2();
}

@Test
void testGetSvCaller() {
Assertions.assertEquals(SvCaller.DELLY2_SV, callerSupport.getSvCaller());
}

@Test
void testIsCompatiblePositive() {
final VCFFileReader vcfReader = new VCFFileReader(vcfFile, false);
final VCFHeader vcfHeader = vcfReader.getHeader();

Assertions.assertTrue(callerSupport.isCompatible(vcfHeader));
}

@Test
void testIsCompatibleNegative() {
final VCFFileReader vcfReader = new VCFFileReader(vcfFile, false);
final VCFHeader vcfHeader = vcfReader.getHeader();

Assertions.assertTrue(callerSupport.isCompatible(vcfHeader));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.github.bihealth.varfish_annotator.annotate_svs;

import com.github.bihealth.varfish_annotator.ResourceUtils;
import htsjdk.variant.vcf.VCFFileReader;
import htsjdk.variant.vcf.VCFHeader;
import java.io.File;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

public class CallerSupportDragenCnvTest {

@TempDir public File tmpFolder;
File vcfFile;
File otherVcfFile;
CallerSupportDragenCnv callerSupport;

@BeforeEach
void initEach() {
vcfFile = new File(tmpFolder + "/vcf-header.vcf");
ResourceUtils.copyResourceToFile("/callers-sv/dragen-cnv-head.vcf", vcfFile);
otherVcfFile = new File(tmpFolder + "/incompatible.vcf");
ResourceUtils.copyResourceToFile("/callers-sv/delly2-head.vcf", otherVcfFile);
callerSupport = new CallerSupportDragenCnv();
}

@Test
void testGetSvCaller() {
Assertions.assertEquals(SvCaller.DRAGEN_CNV, callerSupport.getSvCaller());
}

@Test
void testIsCompatiblePositive() {
final VCFFileReader vcfReader = new VCFFileReader(vcfFile, false);
final VCFHeader vcfHeader = vcfReader.getHeader();

Assertions.assertTrue(callerSupport.isCompatible(vcfHeader));
}

@Test
void testIsCompatibleNegative() {
final VCFFileReader vcfReader = new VCFFileReader(vcfFile, false);
final VCFHeader vcfHeader = vcfReader.getHeader();

Assertions.assertTrue(callerSupport.isCompatible(vcfHeader));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.github.bihealth.varfish_annotator.annotate_svs;

import com.github.bihealth.varfish_annotator.ResourceUtils;
import htsjdk.variant.vcf.VCFFileReader;
import htsjdk.variant.vcf.VCFHeader;
import java.io.File;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

public class CallerSupportDragenSvTest {

@TempDir public File tmpFolder;
File vcfFile;
File otherVcfFile;
CallerSupportDragenSv callerSupport;

@BeforeEach
void initEach() {
vcfFile = new File(tmpFolder + "/vcf-header.vcf");
ResourceUtils.copyResourceToFile("/callers-sv/dragen-sv-head.vcf", vcfFile);
otherVcfFile = new File(tmpFolder + "/incompatible.vcf");
ResourceUtils.copyResourceToFile("/callers-sv/delly2-head.vcf", otherVcfFile);
callerSupport = new CallerSupportDragenSv();
}

@Test
void testGetSvCaller() {
Assertions.assertEquals(SvCaller.DRAGEN_SV, callerSupport.getSvCaller());
}

@Test
void testIsCompatiblePositive() {
final VCFFileReader vcfReader = new VCFFileReader(vcfFile, false);
final VCFHeader vcfHeader = vcfReader.getHeader();

Assertions.assertTrue(callerSupport.isCompatible(vcfHeader));
}

@Test
void testIsCompatibleNegative() {
final VCFFileReader vcfReader = new VCFFileReader(vcfFile, false);
final VCFHeader vcfHeader = vcfReader.getHeader();

Assertions.assertTrue(callerSupport.isCompatible(vcfHeader));
}
}
Loading

0 comments on commit e09f0d4

Please sign in to comment.