Skip to content

Commit

Permalink
tools: store DP field in the VAF normaliser extension #195
Browse files Browse the repository at this point in the history
  • Loading branch information
imedina committed Jan 12, 2021
1 parent d0b60e1 commit c9f6212
Showing 1 changed file with 54 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
public class VafVariantNormalizerExtension extends VariantNormalizerExtension {

private String caller;
private boolean canCalculateVaf;
private boolean calculateVaf;
private boolean calculateDp;
private static final Map<String, List<String>> supportedCallers;

private static final String EXT_VAF = "EXT_VAF";
Expand All @@ -55,11 +56,11 @@ public VafVariantNormalizerExtension(String caller) {

@Override
public void init() {
this.canCalculateVaf = false;
this.calculateVaf = false;

// Check if a supported variant caller parameter has been provided in the constructor
if (StringUtils.isNotEmpty(caller) && supportedCallers.containsKey(caller)) {
canCalculateVaf = true;
calculateVaf = true;
return;
}

Expand All @@ -75,7 +76,7 @@ public void init() {
// Check if we can calculate the VAF
if (StringUtils.isNotEmpty(caller)) {
// Good news, a valid caller found
canCalculateVaf = true;
calculateVaf = true;
} else {
// No caller found, but we can still calculate VAF if standard fields AD and DP are found
// let's check if can find the fields needed to calculate the VAF
Expand Down Expand Up @@ -106,33 +107,47 @@ public void init() {
}

if (containsFormatAD && (containsFormatDP || containsInfoDP)) {
canCalculateVaf = true;
calculateVaf = true;
if (!containsFormatDP) {
calculateDp = true;
}
}

// Important: If EXT_VAF filter already exist in the VCF header we cannot do anything
if (containsFormatExtVaf) {
canCalculateVaf = false;
calculateVaf = false;
}
}
}

@Override
protected boolean canUseExtension(VariantFileMetadata fileMetadata) {
// canCalculateVaf is calculated in the init() method after checking the VCF header fields
return canCalculateVaf;
return calculateVaf;
}

@Override
protected void normalizeHeader(VariantFileMetadata fileMetadata) {
if (canCalculateVaf) {
if (calculateVaf) {
// Add EXT_VAF
VariantFileHeaderComplexLine newSampleMetadataLine = new VariantFileHeaderComplexLine( "FORMAT",
"EXT_VAF",
"Variant Allele Fraction (VAF), several variant callers supported. This is a OpenCB extension field.",
"Variant Allele Fraction (VAF), several variant callers supported. NOTE: this is a OpenCB extension field.",
"1",
"Float",
Collections.emptyMap());
fileMetadata.getHeader().getComplexLines().add(newSampleMetadataLine);

if (calculateDp) {
// Add DP to FORMAT
newSampleMetadataLine = new VariantFileHeaderComplexLine( "FORMAT",
"DP",
"Variant Depth (DP), several variant callers supported. NOTE: this is a OpenCB extension field.",
"1",
"Integer",
Collections.emptyMap());
fileMetadata.getHeader().getComplexLines().add(newSampleMetadataLine);
}
}
}

Expand All @@ -142,6 +157,11 @@ protected void normalizeSample(Variant variant, StudyEntry study, FileEntry file
if (pair != null) {
study.addSampleDataKey(EXT_VAF);
study.addSampleData(sampleId, EXT_VAF, String.valueOf(pair.getLeft()));

if (calculateDp) {
study.addSampleDataKey("DP");
study.addSampleData(sampleId, "DP", String.valueOf(pair.getRight()));
}
}
}

Expand All @@ -153,9 +173,9 @@ private MutablePair<Float, Integer> calculateVaf(Variant variant, StudyEntry stu
MutablePair<Float, Integer> pair = null;
if (StringUtils.isEmpty(caller)) {
// We assume AD and DP fields exist because canCalculateVaf is true and no caller has been found
// Get AD
// 1. Get AD
int AD = 0;
Integer adIndex = study.getSampleDataKeyPositions().get("AD");
Integer adIndex = study.getSampleDataKeyPosition("AD");
if (adIndex != null && adIndex >= 0) {
String adString = sample.getData().get(adIndex);
if (StringUtils.isNotEmpty(adString) && !adString.equals(".")) {
Expand All @@ -166,7 +186,9 @@ private MutablePair<Float, Integer> calculateVaf(Variant variant, StudyEntry stu
}
}

// Get DEPTH
// 2. Get DEPTH
// DP field can be located in the FORMAT (preferred) or in the INFO columns.
// If DP is not found we can calculate it from AD
// First, search in the FORMAT field
if (study.getSampleDataKeyPositions().containsKey("DP")) {
Integer depthIndex = study.getSampleDataKeyPosition("DP");
Expand All @@ -177,10 +199,23 @@ private MutablePair<Float, Integer> calculateVaf(Variant variant, StudyEntry stu
}
}
} else {
// Second, search in the INFO field
String depthString = file.getData().getOrDefault("DP", "");
if (StringUtils.isNotEmpty(depthString) && !depthString.equals(".")) {
DP = Integer.parseInt(depthString);
// Second, some callers store DP in the INFO field when there is ONLY one sample per VCF
if (study.getSamples().size() == 1 && file.getData().containsKey("DP")) {
String depthString = file.getData().getOrDefault("DP", "");
if (StringUtils.isNotEmpty(depthString) && !depthString.equals(".")) {
DP = Integer.parseInt(depthString);
}
} else {
// Third, try to calculate DP from AD field
if (adIndex != null && adIndex >= 0) {
String adString = sample.getData().get(adIndex);
if (StringUtils.isNotEmpty(adString) && !adString.equals(".")) {
String[] ads = adString.split(",");
for (String ad : ads) {
DP += Integer.parseInt(ad);
}
}
}
}
}

Expand Down Expand Up @@ -218,7 +253,7 @@ private MutablePair<Float, Integer> calculateVaf(Variant variant, StudyEntry stu
}

// Create pair object with VAF and DEPTH
if (VAF >=0 && DP >= 0) {
if (VAF >= 0 && DP >= 0) {
pair = new MutablePair<>(VAF, DP);
}

Expand Down Expand Up @@ -252,7 +287,8 @@ private boolean checkCaller(String caller, List<String> keys) {
public String toString() {
final StringBuilder sb = new StringBuilder("VafVariantNormalizerExtension{");
sb.append("caller='").append(caller).append('\'');
sb.append(", canCalculateVaf=").append(canCalculateVaf);
sb.append(", calculateVaf=").append(calculateVaf);
sb.append(", calculateDp=").append(calculateDp);
sb.append('}');
return sb.toString();
}
Expand Down

0 comments on commit c9f6212

Please sign in to comment.