Split class names into stratification and metrics

Calling everything statistics was very confusing. Diagnose Targets stratifies the data three ways: Interval, Sample and Locus. Each stratification then has it's own set of metrics (plugin system) to calculate -- LocusMetric, SampleMetric, IntervalMetric.

 Metrics are generalized by the Metric interface. (for generic access)
 Stratifications are generalized by the AbstractStratification abstract class. (to aggressively limit code duplication)
This commit is contained in:
Mauricio Carneiro 2013-04-24 14:15:49 -04:00
parent 8f8f339e4b
commit 367f0c0ac1
18 changed files with 103 additions and 102 deletions

View File

@ -57,7 +57,7 @@ import java.util.Map;
* @author Mauricio Carneiro
* @since 4/23/13
*/
abstract class AbstractStatistics {
abstract class AbstractStratification {
private long preComputedTotalCoverage = -1;
private Map<CallableStatus, Integer> statusTally = null;
@ -93,9 +93,9 @@ abstract class AbstractStatistics {
*
* @return the total coverage
*/
private long calculateTotalCoverage(Iterable<AbstractStatistics> elements) {
private long calculateTotalCoverage(Iterable<AbstractStratification> elements) {
long cov = 0;
for (AbstractStatistics element : elements) {
for (AbstractStratification element : elements) {
cov += element.getCoverage();
}
return cov;
@ -109,7 +109,7 @@ abstract class AbstractStatistics {
*
* @return the corresponding list of elements of the extending class
*/
public abstract Iterable<AbstractStatistics> getElements();
public abstract Iterable<AbstractStratification> getElements();
/**
* Calculates the Callable statuses for the statistic as a whole (interval, sample or locus)
@ -127,7 +127,7 @@ abstract class AbstractStatistics {
public Map<CallableStatus, Integer> getStatusTally() {
if (statusTally == null) {
statusTally = new HashMap<CallableStatus, Integer>(CallableStatus.values().length);
for (AbstractStatistics stats : getElements()) {
for (AbstractStratification stats : getElements()) {
for (CallableStatus status : stats.callableStatuses()) {
statusTally.put(status, !statusTally.containsKey(status) ? 1 : statusTally.get(status) + 1);
}
@ -136,9 +136,9 @@ abstract class AbstractStatistics {
return statusTally;
}
public static List<CallableStatus> queryStatus(List<Statistic> statList, AbstractStatistics stratification) {
public static List<CallableStatus> queryStatus(List<Metric> statList, AbstractStratification stratification) {
List<CallableStatus> output = new LinkedList<CallableStatus>();
for (Statistic stat : statList) {
for (Metric stat : statList) {
final CallableStatus status = stat.status(stratification);
if (status != null) {
output.add(status);

View File

@ -119,7 +119,7 @@ public class DiagnoseTargets extends LocusWalker<Long, Long> {
@ArgumentCollection
private ThresHolder thresholds = new ThresHolder();
private Map<GenomeLoc, IntervalStatistics> intervalMap = null; // maps each interval => statistics
private Map<GenomeLoc, IntervalStratification> intervalMap = null; // maps each interval => statistics
private PeekableIterator<GenomeLoc> intervalListIterator; // an iterator to go over all the intervals provided as we traverse the genome
private Set<String> samples = null; // all the samples being processed
private static final Allele SYMBOLIC_ALLELE = Allele.create("<DT>", false); // avoid creating the symbolic allele multiple times
@ -134,7 +134,7 @@ public class DiagnoseTargets extends LocusWalker<Long, Long> {
if (getToolkit().getIntervals() == null || getToolkit().getIntervals().isEmpty())
throw new UserException("This tool only works if you provide one or more intervals (use the -L argument). If you want to run whole genome, use -T DepthOfCoverage instead.");
intervalMap = new HashMap<GenomeLoc, IntervalStatistics>(INITIAL_HASH_SIZE);
intervalMap = new HashMap<GenomeLoc, IntervalStratification>(INITIAL_HASH_SIZE);
intervalListIterator = new PeekableIterator<GenomeLoc>(getToolkit().getIntervals().iterator());
// get all of the unique sample names for the VCF Header
@ -155,8 +155,8 @@ public class DiagnoseTargets extends LocusWalker<Long, Long> {
addNewOverlappingIntervals(refLocus);
// at this point, all intervals in intervalMap overlap with this locus, so update all of them
for (IntervalStatistics intervalStatistics : intervalMap.values())
intervalStatistics.addLocus(context);
for (IntervalStratification intervalStratification : intervalMap.values())
intervalStratification.addLocus(context);
return 1L;
}
@ -207,7 +207,7 @@ public class DiagnoseTargets extends LocusWalker<Long, Long> {
// output empty statistics for uncovered intervals
while (interval != null && interval.isBefore(refLocus)) {
final IntervalStatistics stats = intervalMap.get(interval);
final IntervalStratification stats = intervalMap.get(interval);
outputStatsToVCF(stats != null ? stats : createIntervalStatistic(interval), UNCOVERED_ALLELE);
if (stats != null) intervalMap.remove(interval);
intervalListIterator.next();
@ -243,7 +243,7 @@ public class DiagnoseTargets extends LocusWalker<Long, Long> {
* @param stats The statistics of the interval
* @param refAllele the reference allele
*/
private void outputStatsToVCF(IntervalStatistics stats, Allele refAllele) {
private void outputStatsToVCF(IntervalStratification stats, Allele refAllele) {
GenomeLoc interval = stats.getInterval();
@ -265,7 +265,7 @@ public class DiagnoseTargets extends LocusWalker<Long, Long> {
for (String sample : samples) {
final GenotypeBuilder gb = new GenotypeBuilder(sample);
SampleStatistics sampleStat = stats.getSampleStatistics(sample);
SampleStratification sampleStat = stats.getSampleStatistics(sample);
gb.attribute(AVG_INTERVAL_DP_KEY, sampleStat.averageCoverage(interval.size()));
gb.filters(statusToStrings(stats.getSampleStatistics(sample).callableStatuses(), false));
@ -293,36 +293,36 @@ public class DiagnoseTargets extends LocusWalker<Long, Long> {
return output;
}
private IntervalStatistics createIntervalStatistic(GenomeLoc interval) {
return new IntervalStatistics(samples, interval, thresholds);
private IntervalStratification createIntervalStatistic(GenomeLoc interval) {
return new IntervalStratification(samples, interval, thresholds);
}
protected static void loadAllPlugins(final ThresHolder thresholds) {
for (Class<?> stat : new PluginManager<Locus>(Locus.class).getPlugins()) {
for (Class<?> stat : new PluginManager<LocusMetric>(LocusMetric.class).getPlugins()) {
try {
final Locus stats = (Locus) stat.newInstance();
final LocusMetric stats = (LocusMetric) stat.newInstance();
stats.initialize(thresholds);
thresholds.locusStatisticList.add(stats);
thresholds.locusMetricList.add(stats);
} catch (Exception e) {
throw new DynamicClassResolutionException(stat, e);
}
}
for (Class<?> stat : new PluginManager<Sample>(Sample.class).getPlugins()) {
for (Class<?> stat : new PluginManager<SampleMetric>(SampleMetric.class).getPlugins()) {
try {
final Sample stats = (Sample) stat.newInstance();
final SampleMetric stats = (SampleMetric) stat.newInstance();
stats.initialize(thresholds);
thresholds.sampleStatisticList.add(stats);
thresholds.sampleMetricList.add(stats);
} catch (Exception e) {
throw new DynamicClassResolutionException(stat, e);
}
}
for (Class<?> stat : new PluginManager<Interval>(Interval.class).getPlugins()) {
for (Class<?> stat : new PluginManager<IntervalMetric>(IntervalMetric.class).getPlugins()) {
try {
final Interval stats = (Interval) stat.newInstance();
final IntervalMetric stats = (IntervalMetric) stat.newInstance();
stats.initialize(thresholds);
thresholds.intervalStatisticList.add(stats);
thresholds.intervalMetricList.add(stats);
} catch (Exception e) {
throw new DynamicClassResolutionException(stat, e);
}

View File

@ -53,5 +53,5 @@ package org.broadinstitute.sting.gatk.walkers.diagnostics.diagnosetargets;
* Time: 11:30 PM
* To change this template use File | Settings | File Templates.
*/
interface Sample extends Statistic {
interface IntervalMetric extends Metric {
}

View File

@ -53,21 +53,21 @@ import org.broadinstitute.sting.utils.pileup.ReadBackedPileup;
import java.util.*;
final class IntervalStatistics extends AbstractStatistics{
private final Map<String, AbstractStatistics> samples;
final class IntervalStratification extends AbstractStratification {
private final Map<String, AbstractStratification> samples;
private final GenomeLoc interval;
private final ThresHolder thresholds;
public IntervalStatistics(Set<String> samples, GenomeLoc interval, ThresHolder thresholds) {
public IntervalStratification(Set<String> samples, GenomeLoc interval, ThresHolder thresholds) {
this.interval = interval;
this.thresholds = thresholds;
this.samples = new HashMap<String, AbstractStatistics>(samples.size());
this.samples = new HashMap<String, AbstractStratification>(samples.size());
for (String sample : samples)
this.samples.put(sample, new SampleStatistics(interval, thresholds));
this.samples.put(sample, new SampleStratification(interval, thresholds));
}
public SampleStatistics getSampleStatistics(String sample) {
return (SampleStatistics) samples.get(sample);
public SampleStratification getSampleStatistics(String sample) {
return (SampleStratification) samples.get(sample);
}
public GenomeLoc getInterval() {
@ -92,12 +92,12 @@ final class IntervalStatistics extends AbstractStatistics{
for (Map.Entry<String, ReadBackedPileup> entry : samplePileups.entrySet()) {
String sample = entry.getKey();
ReadBackedPileup samplePileup = entry.getValue();
SampleStatistics sampleStatistics = (SampleStatistics) samples.get(sample);
SampleStratification sampleStratification = (SampleStratification) samples.get(sample);
if (sampleStatistics == null)
if (sampleStratification == null)
throw new ReviewedStingException(String.format("Trying to add locus statistics to a sample (%s) that doesn't exist in the Interval.", sample));
sampleStatistics.addLocus(context.getLocation(), samplePileup);
sampleStratification.addLocus(context.getLocation(), samplePileup);
}
}
@ -106,7 +106,7 @@ final class IntervalStatistics extends AbstractStatistics{
* {@inheritDoc}
*/
@Override
public Iterable<AbstractStatistics> getElements() {
public Iterable<AbstractStratification> getElements() {
return samples.values();
}
@ -125,7 +125,7 @@ final class IntervalStatistics extends AbstractStatistics{
}
}
output.addAll(queryStatus(thresholds.intervalStatisticList, this));
output.addAll(queryStatus(thresholds.intervalMetricList, this));
return output;
}

View File

@ -53,6 +53,6 @@ package org.broadinstitute.sting.gatk.walkers.diagnostics.diagnosetargets;
* Time: 11:29 PM
* To change this template use File | Settings | File Templates.
*/
interface Locus extends Statistic {
public CallableStatus sampleStatus (SampleStatistics sampleStatistics);
interface LocusMetric extends Metric {
public CallableStatus sampleStatus (SampleStratification sampleStratification);
}

View File

@ -51,7 +51,7 @@ package org.broadinstitute.sting.gatk.walkers.diagnostics.diagnosetargets;
* Date: 4/20/13
* Time: 11:44 PM
*/
final class LocusCoverageGap implements Locus {
final class LocusMetricCoverageGap implements LocusMetric {
private double threshold;
private static final CallableStatus CALL = CallableStatus.COVERAGE_GAPS;
@ -61,13 +61,13 @@ final class LocusCoverageGap implements Locus {
}
@Override
public CallableStatus status(AbstractStatistics statistics) {
final LocusStatistics locusStatistics = (LocusStatistics) statistics;
return locusStatistics.getRawCoverage() == 0 ? CALL : null;
public CallableStatus status(AbstractStratification statistics) {
final LocusStratification locusStratification = (LocusStratification) statistics;
return locusStratification.getRawCoverage() == 0 ? CALL : null;
}
@Override
public CallableStatus sampleStatus(SampleStatistics sampleStatistics) {
return PluginUtils.genericSampleStatus(sampleStatistics, CALL, threshold);
public CallableStatus sampleStatus(SampleStratification sampleStratification) {
return PluginUtils.genericSampleStatus(sampleStratification, CALL, threshold);
}
}

View File

@ -51,7 +51,7 @@ package org.broadinstitute.sting.gatk.walkers.diagnostics.diagnosetargets;
* Date: 4/20/13
* Time: 11:44 PM
*/
final class LocusExcessiveCoverage implements Locus {
final class LocusMetricExcessiveCoverage implements LocusMetric {
private int excessiveCoverage;
private double threshold;
private static final CallableStatus CALL = CallableStatus.EXCESSIVE_COVERAGE ;
@ -63,13 +63,13 @@ final class LocusExcessiveCoverage implements Locus {
}
@Override
public CallableStatus status(AbstractStatistics statistics) {
final LocusStatistics locusStatistics = (LocusStatistics) statistics;
return locusStatistics.getCoverage() > excessiveCoverage ? CALL : null;
public CallableStatus status(AbstractStratification statistics) {
final LocusStratification locusStratification = (LocusStratification) statistics;
return locusStratification.getCoverage() > excessiveCoverage ? CALL : null;
}
@Override
public CallableStatus sampleStatus(SampleStatistics sampleStatistics) {
return PluginUtils.genericSampleStatus(sampleStatistics, CALL, threshold);
public CallableStatus sampleStatus(SampleStratification sampleStratification) {
return PluginUtils.genericSampleStatus(sampleStratification, CALL, threshold);
}
}

View File

@ -51,7 +51,7 @@ package org.broadinstitute.sting.gatk.walkers.diagnostics.diagnosetargets;
* Date: 4/20/13
* Time: 11:44 PM
*/
final class LocusLowCoverage implements Locus {
final class LocusMetricLowCoverage implements LocusMetric {
private int minCoverage;
private double threshold;
private static final CallableStatus CALL = CallableStatus.LOW_COVERAGE ;
@ -63,14 +63,14 @@ final class LocusLowCoverage implements Locus {
}
@Override
public CallableStatus status(AbstractStatistics statistics) {
final LocusStatistics locusStatistics = (LocusStatistics) statistics;
final long raw = locusStatistics.getRawCoverage();
public CallableStatus status(AbstractStratification statistics) {
final LocusStratification locusStratification = (LocusStratification) statistics;
final long raw = locusStratification.getRawCoverage();
return raw > 0 && raw < minCoverage ? CALL: null;
}
@Override
public CallableStatus sampleStatus(SampleStatistics sampleStatistics) {
return PluginUtils.genericSampleStatus(sampleStatistics, CALL, threshold);
public CallableStatus sampleStatus(SampleStratification sampleStratification) {
return PluginUtils.genericSampleStatus(sampleStratification, CALL, threshold);
}
}

View File

@ -51,7 +51,7 @@ package org.broadinstitute.sting.gatk.walkers.diagnostics.diagnosetargets;
* Date: 4/20/13
* Time: 11:44 PM
*/
final class LocusPoorQuality implements Locus {
final class LocusMetricPoorQuality implements LocusMetric {
private int minCoverage;
private double threshold;
private static final CallableStatus CALL = CallableStatus.POOR_QUALITY ;
@ -63,13 +63,13 @@ final class LocusPoorQuality implements Locus {
}
@Override
public CallableStatus status(AbstractStatistics statistics) {
final LocusStatistics locusStatistics = (LocusStatistics) statistics;
return locusStatistics.getCoverage() < minCoverage && locusStatistics.getRawCoverage() >= minCoverage ? CALL: null;
public CallableStatus status(AbstractStratification statistics) {
final LocusStratification locusStratification = (LocusStratification) statistics;
return locusStratification.getCoverage() < minCoverage && locusStratification.getRawCoverage() >= minCoverage ? CALL: null;
}
@Override
public CallableStatus sampleStatus(SampleStatistics sampleStatistics) {
return PluginUtils.genericSampleStatus(sampleStatistics, CALL, threshold);
public CallableStatus sampleStatus(SampleStratification sampleStratification) {
return PluginUtils.genericSampleStatus(sampleStratification, CALL, threshold);
}
}

View File

@ -49,19 +49,19 @@ package org.broadinstitute.sting.gatk.walkers.diagnostics.diagnosetargets;
import java.util.LinkedList;
import java.util.List;
final class LocusStatistics extends AbstractStatistics{
final class LocusStratification extends AbstractStratification {
private long coverage;
private long rawCoverage;
private final List<Statistic> locusStatisticsList;
private final List<Metric> locusStatisticsList;
public LocusStatistics(ThresHolder thresholds) {
public LocusStratification(ThresHolder thresholds) {
this(0,0,thresholds);
}
protected LocusStatistics(int coverage, int rawCoverage, ThresHolder thresholds) {
protected LocusStratification(int coverage, int rawCoverage, ThresHolder thresholds) {
this.coverage = coverage;
this.rawCoverage = rawCoverage;
this.locusStatisticsList = thresholds.locusStatisticList;
this.locusStatisticsList = thresholds.locusMetricList;
}
@Override
@ -80,7 +80,7 @@ final class LocusStatistics extends AbstractStatistics{
*/
public List<CallableStatus> callableStatuses() {
List<CallableStatus> output = new LinkedList<CallableStatus>();
for (Statistic stats : locusStatisticsList) {
for (Metric stats : locusStatisticsList) {
CallableStatus status = stats.status(this);
if (status != null) {
output.add(status);
@ -90,7 +90,7 @@ final class LocusStatistics extends AbstractStatistics{
}
@Override
public Iterable<AbstractStatistics> getElements() {
public Iterable<AbstractStratification> getElements() {
return null;
}

View File

@ -51,7 +51,7 @@ package org.broadinstitute.sting.gatk.walkers.diagnostics.diagnosetargets;
* @author Mauricio Carneiro
* @since 4/23/13
*/
interface Statistic {
interface Metric {
public void initialize(ThresHolder thresholds);
public CallableStatus status (AbstractStatistics statistic);
public CallableStatus status (AbstractStratification statistic);
}

View File

@ -54,9 +54,9 @@ import java.util.Map;
* Time: 11:23 AM
*/
final class PluginUtils {
public static CallableStatus genericSampleStatus (final SampleStatistics sampleStatistics, final CallableStatus CALL, final double threshold) {
final Map<CallableStatus, Integer> totals = sampleStatistics.getStatusTally();
final int size = sampleStatistics.getIntervalSize();
public static CallableStatus genericSampleStatus (final SampleStratification sampleStratification, final CallableStatus CALL, final double threshold) {
final Map<CallableStatus, Integer> totals = sampleStratification.getStatusTally();
final int size = sampleStratification.getIntervalSize();
final int statusCount = totals.containsKey(CALL) ? totals.get(CALL) : 0;
return ( (double) statusCount / size) >= threshold ? CALL: null;
}

View File

@ -53,5 +53,5 @@ package org.broadinstitute.sting.gatk.walkers.diagnostics.diagnosetargets;
* Time: 11:30 PM
* To change this template use File | Settings | File Templates.
*/
interface Interval extends Statistic {
interface SampleMetric extends Metric {
}

View File

@ -51,7 +51,7 @@ package org.broadinstitute.sting.gatk.walkers.diagnostics.diagnosetargets;
* Date: 4/20/13
* Time: 11:44 PM
*/
final class SampleBadMates implements Sample {
final class SampleMetricBadMates implements SampleMetric {
private static final CallableStatus CALL = CallableStatus.NO_READS ;
private double threshold;
@ -64,10 +64,10 @@ final class SampleBadMates implements Sample {
}
@Override
public CallableStatus status(AbstractStatistics statistics) {
final SampleStatistics sampleStatistics = (SampleStatistics) statistics;
final int nReads = sampleStatistics.getnReads();
return nReads > 0 && (double) sampleStatistics.getnBadMates() / nReads > threshold ? CALL : null;
public CallableStatus status(AbstractStratification statistics) {
final SampleStratification sampleStratification = (SampleStratification) statistics;
final int nReads = sampleStratification.getnReads();
return nReads > 0 && (double) sampleStratification.getnBadMates() / nReads > threshold ? CALL : null;
}
}

View File

@ -51,16 +51,16 @@ package org.broadinstitute.sting.gatk.walkers.diagnostics.diagnosetargets;
* Date: 4/20/13
* Time: 11:44 PM
*/
final class SampleNoReads implements Sample {
final class SampleMetricNoReads implements SampleMetric {
private static final CallableStatus CALL = CallableStatus.NO_READS;
@Override
public void initialize(ThresHolder thresholds) {
}
@Override
public CallableStatus status(AbstractStatistics statistics) {
final SampleStatistics sampleStatistics = (SampleStatistics) statistics;
return sampleStatistics.getnReads() == 0 ? CALL : null;
public CallableStatus status(AbstractStratification statistics) {
final SampleStratification sampleStratification = (SampleStratification) statistics;
return sampleStratification.getnReads() == 0 ? CALL : null;
}
}

View File

@ -51,30 +51,31 @@ import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
import org.broadinstitute.sting.utils.pileup.ReadBackedPileup;
import org.broadinstitute.sting.utils.sam.GATKSAMRecord;
import java.util.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
/**
* The statistics calculator for a specific sample given the interval
*/
final class SampleStatistics extends AbstractStatistics {
final class SampleStratification extends AbstractStratification {
private final GenomeLoc interval;
private final ArrayList<AbstractStatistics> loci;
private final ArrayList<AbstractStratification> loci;
private final ThresHolder thresholds;
private Map<CallableStatus, Integer> locusStatusTally = null;
private int nReads = -1;
private int nBadMates = -1;
public SampleStatistics(final GenomeLoc interval, final ThresHolder thresholds) {
public SampleStratification(final GenomeLoc interval, final ThresHolder thresholds) {
this.interval = interval;
this.loci = new ArrayList<AbstractStatistics>(interval.size());
this.loci = new ArrayList<AbstractStratification>(interval.size());
this.thresholds = thresholds;
nReads = 0;
nBadMates = 0;
// Initialize every loci (this way we don't have to worry about non-existent loci in the object
for (int i = 0; i < interval.size(); i++)
this.loci.add(new LocusStatistics(thresholds));
this.loci.add(new LocusStratification(thresholds));
}
/**
@ -99,7 +100,7 @@ final class SampleStatistics extends AbstractStatistics {
final int locusIndex = locus.getStart() - interval.getStart();
final int rawCoverage = pileup.depthOfCoverage();
final int coverage = pileup.getBaseAndMappingFilteredPileup(thresholds.minimumBaseQuality, thresholds.minimumMappingQuality).depthOfCoverage();
final LocusStatistics locusData = (LocusStatistics) loci.get(locusIndex);
final LocusStratification locusData = (LocusStratification) loci.get(locusIndex);
locusData.addLocus(coverage, rawCoverage);
// process all the reads in this pileup (tallying number of reads and bad mates)
@ -109,7 +110,7 @@ final class SampleStatistics extends AbstractStatistics {
}
@Override
public Iterable<AbstractStatistics> getElements() {
public Iterable<AbstractStratification> getElements() {
return loci;
}
@ -121,15 +122,15 @@ final class SampleStatistics extends AbstractStatistics {
final List<CallableStatus> output = new LinkedList<CallableStatus>();
// get the tally of all the locus callable statuses
for (Statistic locusStat : thresholds.locusStatisticList) {
final CallableStatus status = ((Locus) locusStat).sampleStatus(this);
for (Metric locusStat : thresholds.locusMetricList) {
final CallableStatus status = ((LocusMetric) locusStat).sampleStatus(this);
if (status != null) {
output.add(status);
}
}
// get the sample specific statitics statuses
for (Statistic sampleStat : thresholds.sampleStatisticList) {
for (Metric sampleStat : thresholds.sampleMetricList) {
final CallableStatus status = sampleStat.status(this);
if (status != null) {
output.add(status);

View File

@ -114,9 +114,9 @@ final class ThresHolder {
@Argument(fullName = "quality_status_threshold", shortName = "stQ", doc = "The proportion of the loci needed for calling POOR_QUALITY", required = false)
public double qualityStatusThreshold = 0.50;
public final List<Statistic> locusStatisticList = new LinkedList<Statistic>();
public final List<Statistic> sampleStatisticList = new LinkedList<Statistic>();
public final List<Statistic> intervalStatisticList = new LinkedList<Statistic>();
public final List<Metric> locusMetricList = new LinkedList<Metric>();
public final List<Metric> sampleMetricList = new LinkedList<Metric>();
public final List<Metric> intervalMetricList = new LinkedList<Metric>();
public ThresHolder() {}

View File

@ -64,7 +64,7 @@ public class LocusStatisticsUnitTest {
@Test(dataProvider = "StatusTestValues")
public void testCallableStatuses(int coverage, int rawCoverage, CallableStatus status) {
List<CallableStatus> statuses = new LocusStatistics(coverage, rawCoverage, thresholds).callableStatuses();
List<CallableStatus> statuses = new LocusStratification(coverage, rawCoverage, thresholds).callableStatuses();
Assert.assertTrue((status == null) ? statuses.isEmpty() : (statuses.contains(status) && statuses.size() == 1));
}