Skip to content

Commit b2e9e71

Browse files
authored
Merge pull request #387 from AdamaJava/qanno_miun_fix
fix(qannotate): MIUN was not being applied appropriately to SNPs
2 parents e3968a7 + 982f08c commit b2e9e71

File tree

2 files changed

+204
-45
lines changed

2 files changed

+204
-45
lines changed

qannotate/src/au/edu/qimr/qannotate/modes/ConfidenceMode.java

+34-27
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,11 @@
88

99
import java.io.File;
1010
import java.io.IOException;
11-
import java.util.ArrayList;
1211
import java.util.Arrays;
1312
import java.util.Collections;
1413
import java.util.List;
1514
import java.util.Map;
1615
import java.util.concurrent.atomic.AtomicInteger;
17-
import java.util.stream.Collectors;
1816

1917
import org.qcmg.common.log.QLogger;
2018
import org.qcmg.common.log.QLoggerFactory;
@@ -55,6 +53,8 @@ public class ConfidenceMode extends AbstractMode {
5553
public static final int sBiasAltPercentage = 5;
5654
public static final int sBiasCovPercentage = 5;
5755

56+
private static final int[] ZERO_ARRAY = {0, 0};
57+
5858
@Deprecated // using values (both hard cutoff and percentage) from MIN for MIUN annotation
5959
public static final int MIUN_CUTOFF = 2; // based on existing values
6060

@@ -230,7 +230,7 @@ void addAnnotation() {
230230
/*
231231
* look for MIUN, but only if we don't already have MIN
232232
*/
233-
checkMIUN(failedFilterStringBuilder, ffArr, i, alts, cov);
233+
checkMIUN(failedFilterStringBuilder, ffArr, i, alts, cov, alleleDist);
234234

235235
if (!failedFilterStringBuilder.toString().contains(VcfHeaderUtils.FILTER_COVERAGE) && cov < controlCovCutoffForSomaticCalls) {
236236
StringUtils.updateStringBuilder(failedFilterStringBuilder, VcfHeaderUtils.FILTER_COVERAGE, Constants.SEMI_COLON);
@@ -243,7 +243,7 @@ void addAnnotation() {
243243
String gt = gtArray[i];
244244
if ( ! StringUtils.isNullOrEmptyOrMissingData(gt) && ! "0/0".equals(gt)) {
245245
int index = gt.indexOf(Constants.SLASH);
246-
int[] gts = new int[]{Integer.parseInt(gt.substring(0, index)), Integer.parseInt(gt.substring(index + 1))};
246+
int[] gts = new int[]{Integer.parseInt(gt, 0, index, 10), Integer.parseInt(gt, index + 1, gt.length(), 10)};
247247

248248
if (!alleleDist.isEmpty() && !isGATKCall) {
249249
checkStrandBias(alts, failedFilterStringBuilder, alleleDist, gts, sBiasCovPercentage, sBiasAltPercentage);
@@ -304,12 +304,12 @@ void addAnnotation() {
304304
}
305305
}
306306

307-
private void checkMIUN(StringBuilder fSb, String[] ffArr, int i, String[] alts, int cov) {
307+
private void checkMIUN(StringBuilder fSb, String[] ffArr, int i, String[] alts, int cov, Map<String, int[]> alleleDist) {
308308
if (!fSb.toString().contains(VcfHeaderUtils.FILTER_MUTATION_IN_NORMAL)) {
309309
if (null != ffArr && ffArr.length > i) {
310310
String failedFilter = ffArr[i];
311311
// using the same values as for the MIN annotation
312-
checkMIUN(alts, cov, failedFilter, fSb, minCutoff, (float) minPercentage);
312+
checkMIUN(alts, cov, failedFilter, fSb, minCutoff, (float) minPercentage, alleleDist);
313313
}
314314
}
315315
}
@@ -385,7 +385,7 @@ public static void checkNNS(String nnsString, StringBuilder sb, int nnsCount) {
385385
public static void checkMIN(String[] alts, int coverage, Map<String, int[]> alleleDist, StringBuilder sb, int minCutoff, float minPercentage) {
386386
if (null != alts && null != alleleDist) {
387387
for (String alt : alts) {
388-
int altCov = Arrays.stream(alleleDist.getOrDefault(alt, new int[]{0, 0})).sum();
388+
int altCov = Arrays.stream(alleleDist.getOrDefault(alt, ZERO_ARRAY)).sum();
389389
boolean min = VcfUtils.mutationInNormal(altCov, coverage, minPercentage, minCutoff);
390390
if (min) {
391391
StringUtils.updateStringBuilder(sb, VcfHeaderUtils.FILTER_MUTATION_IN_NORMAL, Constants.SEMI_COLON);
@@ -407,25 +407,31 @@ public static void checkMIN(String[] alts, int coverage, Map<String, int[]> alle
407407
* @param miunCutoff The minimum coverage cutoff for MIUN
408408
* @param miunPercentage The minimum percentage cutoff for MIUN
409409
*/
410-
public static void checkMIUN(String[] alts, int coverage, String failedFilter, StringBuilder sb, int miunCutoff, float miunPercentage) {
411-
if (null != alts && !StringUtils.isNullOrEmptyOrMissingData(failedFilter)) {
410+
public static void checkMIUN(String[] alts, int coverage, String failedFilter, StringBuilder sb, int miunCutoff, float miunPercentage, Map<String, int[]> alleleDist) {
411+
if (alts == null || alts.length == 0 || StringUtils.isNullOrEmptyOrMissingData(failedFilter)) {
412+
return;
413+
}
412414

413-
int totalCoverage = coverage + getCoverageFromFailedFilterString(failedFilter);
414-
float cutoffToUse = Math.max(miunCutoff, (miunPercentage / 100) * totalCoverage);
415+
int totalCoverage = coverage + getCoverageFromFailedFilterString(failedFilter);
416+
float cutoffToUse = Math.max(miunCutoff, (miunPercentage / 100) * totalCoverage);
415417

418+
for (String alt : alts) {
419+
int altIndex = failedFilter.indexOf(alt);
420+
if (altIndex > -1) {
421+
/*
422+
* bases are separated by colons
423+
*/
424+
int semiColonIndex = failedFilter.indexOf(Constants.SEMI_COLON, altIndex);
425+
int failedFilterCount = Integer.parseInt(failedFilter, altIndex + alt.length(), semiColonIndex > -1 ? semiColonIndex : failedFilter.length(), 10);
416426

417-
for (String alt : alts) {
418-
int altIndex = failedFilter.indexOf(alt);
419-
if (altIndex > -1) {
420-
/*
421-
* bases are separated by colons
422-
*/
423-
int semiColonIndex = failedFilter.indexOf(Constants.SEMI_COLON, altIndex);
424-
int failedFilterCount = Integer.parseInt(failedFilter.substring(altIndex + alt.length(), semiColonIndex > -1 ? semiColonIndex : failedFilter.length()));
425-
if (failedFilterCount >= cutoffToUse) {
426-
StringUtils.updateStringBuilder(sb, VcfHeaderUtils.FILTER_MUTATION_IN_UNFILTERED_NORMAL, Constants.SEMI_COLON);
427-
break;
428-
}
427+
// Add coverage from alleleDist map
428+
int[] passedFilterCoverage = null != alleleDist ? alleleDist.getOrDefault(alt, ZERO_ARRAY) : ZERO_ARRAY;
429+
int passedFilterCoverageSum = passedFilterCoverage[0] + passedFilterCoverage[1];
430+
failedFilterCount += passedFilterCoverageSum;
431+
432+
if (failedFilterCount >= cutoffToUse) {
433+
StringUtils.updateStringBuilder(sb, VcfHeaderUtils.FILTER_MUTATION_IN_UNFILTERED_NORMAL, Constants.SEMI_COLON);
434+
break;
429435
}
430436
}
431437
}
@@ -451,8 +457,8 @@ public static int endsOfReads(String[] alts, String gt, Map<String, int[]> oabsM
451457
Map<String, int[]> eorMap = VcfUtils.getAllelicCoverageWithStrand(eor);
452458
for (String alt : alts) {
453459
if (gt.contains("" + i)) {
454-
int[] altCov = oabsMap.getOrDefault(alt, new int[]{0, 0});
455-
int[] altCovEOR = eorMap.getOrDefault(alt, new int[]{0, 0});
460+
int[] altCov = oabsMap.getOrDefault(alt, ZERO_ARRAY);
461+
int[] altCovEOR = eorMap.getOrDefault(alt, ZERO_ARRAY);
456462
int middleOfReadForwardStrand = altCov[0] - altCovEOR[0];
457463
int middleOfReadReverseStrand = altCov[1] - altCovEOR[1];
458464
int middleOfReadCount = middleOfReadForwardStrand + middleOfReadReverseStrand;
@@ -545,7 +551,8 @@ public static int[] getFieldOfInts(String value) {
545551
}
546552
int cI = value.indexOf(Constants.COMMA);
547553
if (cI == -1) return new int[]{Integer.parseInt(value)};
548-
return new int[]{Integer.parseInt(value.substring(0, cI)), Integer.parseInt(value.substring(cI + 1))};
554+
return new int[]{Integer.parseInt(value, 0, cI, 10), Integer.parseInt(value, cI + 1, value.length(), 10)};
555+
// return new int[]{Integer.parseInt(value.substring(0, cI)), Integer.parseInt(value.substring(cI + 1))};
549556
}
550557

551558
/**
@@ -566,7 +573,7 @@ public static int getCoverageFromFailedFilterString(String ff) {
566573
// could probably start this at 1....
567574
for (int i = 0; i < ff.length(); ) {
568575
if (Character.isDigit(ff.charAt(i))) {
569-
cov += Integer.parseInt(ff.substring(i, semiColonIndex > -1 ? semiColonIndex : ff.length()));
576+
cov += Integer.parseInt(ff, i, semiColonIndex > -1 ? semiColonIndex : ff.length(), 10);
570577
if (semiColonIndex == -1) {
571578
break;
572579
} else {

0 commit comments

Comments
 (0)