package picard.analysis;
import htsjdk.samtools.SAMFileHeader;
import htsjdk.samtools.SAMSequenceRecord;
import htsjdk.samtools.util.Histogram;
import htsjdk.samtools.util.Interval;
import htsjdk.samtools.util.IntervalList;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import picard.PicardException;
/**
* Tests for WgsMetrics.
*/
public class WgsMetricsTest {
private Histogram<Integer> emptyDepthHistogram() { return new Histogram<>(); }
private Histogram<Integer> singleDepthHistogram(final int depth, final int count) {
final Histogram<Integer> histogram = new Histogram<>();
histogram.increment(depth, count);
return histogram;
}
private Histogram<Integer> twoSiteDepthHistogram(final int depth1, final int count1, final int depth2, final int count2) {
final Histogram<Integer> histogram = new Histogram<>();
if (0 < depth1) histogram.increment(depth1, count1);
if (0 < depth2) histogram.increment(depth2, count2);
return histogram;
}
private IntervalList buildIntervalList(final int start, final int end) {
final SAMFileHeader header = new SAMFileHeader();
header.addSequence(new SAMSequenceRecord("CONTIG", 100000000));
final IntervalList intervals = new IntervalList(header);
if (0 < start) intervals.add(new Interval("CONTIG", start, end));
return intervals;
}
private CollectWgsMetrics.WgsMetrics emptyMetrics() {
return new CollectWgsMetrics.WgsMetrics(
buildIntervalList(-1, -1),
emptyDepthHistogram(), emptyDepthHistogram(),
0, 0, 0, 0, 0, 0, 0, 1000000,
null, -1
);
}
private CollectWgsMetrics.WgsMetrics singleDepthMetrics(final int depth, final int countScale, final int start) {
final int count = 100000 * countScale;
final int totalExcluded = (10 + 20 + 30 + 40 + 50 + 60) * countScale;
return new CollectWgsMetrics.WgsMetrics(
buildIntervalList(start, start),
singleDepthHistogram(depth, count),
singleDepthHistogram(depth, count),
10d * countScale / count, 20d * countScale / count, 30d * countScale / count,
40d * countScale / count, 50d * countScale / count, 60d * countScale / count,
totalExcluded / (double) (count + totalExcluded),
1000000,
null, -1
);
}
private CollectWgsMetrics.WgsMetrics twoSiteDepthMetrics(final int depth1, final int countScale1,
final int depth2, final int countScale2,
final int start) {
final int count1 = 100000 * countScale1;
final int count2 = 100000 * countScale2;
final int count = count1 + count2;
final int countScale = countScale1 + countScale2;
final int totalExcluded = (10 + 20 + 30 + 40 + 50 + 60) * countScale;
return new CollectWgsMetrics.WgsMetrics(
buildIntervalList(start, start+1),
twoSiteDepthHistogram(depth1, count1, depth2, count2),
twoSiteDepthHistogram(depth1, count1, depth2, count2),
10d * countScale / count, 20d * countScale / count, 30d * countScale / count,
40d * countScale / count, 50d * countScale / count, 60d * countScale / count,
totalExcluded / (double) (count + totalExcluded),
100000,
null, -1
);
}
@Test(dataProvider = "testWgsMetricsMergeDataProvider")
public void testWgsMetricsMerge(final CollectWgsMetrics.WgsMetrics left,
final CollectWgsMetrics.WgsMetrics right,
final CollectWgsMetrics.WgsMetrics expected) {
left.merge(right);
left.calculateDerivedFields();
Assert.assertTrue(left.equals(expected));
}
@DataProvider(name = "testWgsMetricsMergeDataProvider")
public Object[][] testWgsMetricsMergeDataProvider() {
return new Object[][] {
{emptyMetrics(), emptyMetrics(), emptyMetrics()},
{emptyMetrics(), singleDepthMetrics(1, 1, 1), singleDepthMetrics(1, 1, 1)},
{singleDepthMetrics(1, 1, 1), emptyMetrics(), singleDepthMetrics(1, 1, 1)},
{singleDepthMetrics(1, 1, 1), singleDepthMetrics(1, 1, 2), twoSiteDepthMetrics(1, 2, 0, 0, 1)},
{singleDepthMetrics(1, 1, 1), singleDepthMetrics(1, 2, 2), twoSiteDepthMetrics(1, 3, 0, 0, 1)},
{singleDepthMetrics(1, 1, 1), singleDepthMetrics(1, 1, 2), twoSiteDepthMetrics(1, 2, 0, 0, 1)},
{singleDepthMetrics(1, 1, 1), singleDepthMetrics(2, 1, 2), twoSiteDepthMetrics(1, 1, 2, 1, 1)},
{twoSiteDepthMetrics(1, 1, 2, 1, 1), twoSiteDepthMetrics(1, 1, 2, 1, 3), twoSiteDepthMetrics(1, 2, 2, 2, 1)}
};
}
@Test(expectedExceptions = {PicardException.class})
public void testMergeOverlappingIntervals() {
singleDepthMetrics(1, 1, 1).merge(singleDepthMetrics(1, 1, 1));
}
}