BQSR optimization: read group x quality score calibration table is thread-local

-- AdvancedRecalibrationEngine now uses a thread-local table for the quality score table, and in finalizeData merges these thread-local tables into the final table.  Radically reduces the contention for RecalDatum in this very highly used table
-- Refactored the utility function to combine two tables into RecalUtils, and created UnitTests for this function, as well as all of RecalibrationTables.  Updated combine in RecalibrationReport to use this table combiner function
-- Made several core functions in RecalDatum into final methods for performance
-- Added RecalibrationTestUtils, a home for recalibration testing utilities
This commit is contained in:
Mark DePristo 2012-12-24 10:46:47 -05:00
parent 7d250a789a
commit 7bf1f67273
8 changed files with 414 additions and 41 deletions

View File

@ -25,16 +25,35 @@ package org.broadinstitute.sting.gatk.walkers.bqsr;
* OTHER DEALINGS IN THE SOFTWARE.
*/
import org.apache.log4j.Logger;
import org.broadinstitute.sting.utils.classloader.ProtectedPackageSource;
import org.broadinstitute.sting.utils.collections.NestedIntegerArray;
import org.broadinstitute.sting.utils.recalibration.EventType;
import org.broadinstitute.sting.utils.recalibration.ReadCovariates;
import org.broadinstitute.sting.utils.recalibration.RecalDatum;
import org.broadinstitute.sting.utils.sam.GATKSAMRecord;
import java.util.LinkedList;
import java.util.List;
public class AdvancedRecalibrationEngine extends StandardRecalibrationEngine implements ProtectedPackageSource {
private final static Logger logger = Logger.getLogger(AdvancedRecalibrationEngine.class);
final List<NestedIntegerArray<RecalDatum>> allThreadLocalQualityScoreTables = new LinkedList<NestedIntegerArray<RecalDatum>>();
private ThreadLocal<NestedIntegerArray<RecalDatum>> threadLocalQualityScoreTables = new ThreadLocal<NestedIntegerArray<RecalDatum>>() {
@Override
protected synchronized NestedIntegerArray<RecalDatum> initialValue() {
final NestedIntegerArray<RecalDatum> table = recalibrationTables.makeQualityScoreTable();
allThreadLocalQualityScoreTables.add(table);
return table;
}
};
@Override
public void updateDataForRead( final ReadRecalibrationInfo recalInfo ) {
final GATKSAMRecord read = recalInfo.getRead();
final ReadCovariates readCovariates = recalInfo.getCovariatesValues();
final NestedIntegerArray<RecalDatum> qualityScoreTable = getThreadLocalQualityScoreTable();
for( int offset = 0; offset < read.getReadBases().length; offset++ ) {
if( ! recalInfo.skip(offset) ) {
@ -45,7 +64,7 @@ public class AdvancedRecalibrationEngine extends StandardRecalibrationEngine imp
final byte qual = recalInfo.getQual(eventType, offset);
final double isError = recalInfo.getErrorFraction(eventType, offset);
incrementDatumOrPutIfNecessary(recalibrationTables.getQualityScoreTable(), qual, isError, keys[0], keys[1], eventIndex);
incrementDatumOrPutIfNecessary(qualityScoreTable, qual, isError, keys[0], keys[1], eventIndex);
for (int i = 2; i < covariates.length; i++) {
if (keys[i] < 0)
@ -57,4 +76,24 @@ public class AdvancedRecalibrationEngine extends StandardRecalibrationEngine imp
}
}
}
/**
* Get a NestedIntegerArray for a QualityScore table specific to this thread
* @return a non-null NestedIntegerArray ready to be used to collect calibration info for the quality score covariate
*/
private NestedIntegerArray<RecalDatum> getThreadLocalQualityScoreTable() {
return threadLocalQualityScoreTables.get();
}
@Override
public void finalizeData() {
// merge in all of the thread local tables
logger.info("Merging " + allThreadLocalQualityScoreTables.size() + " thread-local quality score tables");
for ( final NestedIntegerArray<RecalDatum> localTable : allThreadLocalQualityScoreTables ) {
recalibrationTables.combineQualityScoreTable(localTable);
}
allThreadLocalQualityScoreTables.clear(); // cleanup after ourselves
super.finalizeData();
}
}

View File

@ -212,49 +212,49 @@ public class RecalDatum {
//
//---------------------------------------------------------------------------------------------------------------
public double getNumObservations() {
public final double getNumObservations() {
return numObservations;
}
public synchronized void setNumObservations(final double numObservations) {
public final synchronized void setNumObservations(final double numObservations) {
if ( numObservations < 0 ) throw new IllegalArgumentException("numObservations < 0");
this.numObservations = numObservations;
empiricalQuality = UNINITIALIZED;
}
public double getNumMismatches() {
public final double getNumMismatches() {
return numMismatches;
}
@Requires({"numMismatches >= 0"})
public synchronized void setNumMismatches(final double numMismatches) {
public final synchronized void setNumMismatches(final double numMismatches) {
if ( numMismatches < 0 ) throw new IllegalArgumentException("numMismatches < 0");
this.numMismatches = numMismatches;
empiricalQuality = UNINITIALIZED;
}
@Requires({"by >= 0"})
public synchronized void incrementNumObservations(final double by) {
public final synchronized void incrementNumObservations(final double by) {
numObservations += by;
empiricalQuality = UNINITIALIZED;
}
@Requires({"by >= 0"})
public synchronized void incrementNumMismatches(final double by) {
public final synchronized void incrementNumMismatches(final double by) {
numMismatches += by;
empiricalQuality = UNINITIALIZED;
}
@Requires({"incObservations >= 0", "incMismatches >= 0"})
@Ensures({"numObservations == old(numObservations) + incObservations", "numMismatches == old(numMismatches) + incMismatches"})
public synchronized void increment(final double incObservations, final double incMismatches) {
public final synchronized void increment(final double incObservations, final double incMismatches) {
numObservations += incObservations;
numMismatches += incMismatches;
empiricalQuality = UNINITIALIZED;
}
@Ensures({"numObservations == old(numObservations) + 1", "numMismatches >= old(numMismatches)"})
public synchronized void increment(final boolean isError) {
public final synchronized void increment(final boolean isError) {
increment(1, isError ? 1 : 0.0);
}

View File

@ -769,4 +769,28 @@ public class RecalUtils {
return base;
}
}
/**
* Combines the recalibration data for table1 and table2 into table1
*
* Note that table1 is the destination, so it is modified
*
* @param table1 the destination table to merge table2 into
* @param table2 the source table to merge into table1
*/
public static void combineTables(final NestedIntegerArray<RecalDatum> table1, final NestedIntegerArray<RecalDatum> table2) {
if ( table1 == null ) throw new IllegalArgumentException("table1 cannot be null");
if ( table2 == null ) throw new IllegalArgumentException("table2 cannot be null");
if ( ! Arrays.equals(table1.getDimensions(), table2.getDimensions()))
throw new IllegalArgumentException("Table1 " + Utils.join(",", table1.getDimensions()) + " not equal to " + Utils.join(",", table2.getDimensions()));
for (final NestedIntegerArray.Leaf<RecalDatum> row : table2.getAllLeaves()) {
final RecalDatum myDatum = table1.get(row.keys);
if (myDatum == null)
table1.put(row.value, row.keys);
else
myDatum.combine(row.value);
}
}
}

View File

@ -81,7 +81,7 @@ public class RecalibrationReport {
/**
* Counts the number of unique read groups in the table
*
* @param reportTable the GATKReport table containing data for this table
* @param reportTable the GATKReport table containing data for this table
* @return the number of unique read groups
*/
private int countReadGroups(final GATKReportTable reportTable) {
@ -105,19 +105,10 @@ public class RecalibrationReport {
* @param other the recalibration report to combine with this one
*/
public void combine(final RecalibrationReport other) {
for ( int tableIndex = 0; tableIndex < recalibrationTables.numTables(); tableIndex++ ) {
final NestedIntegerArray<RecalDatum> myTable = recalibrationTables.getTable(tableIndex);
final NestedIntegerArray<RecalDatum> otherTable = other.recalibrationTables.getTable(tableIndex);
for (final NestedIntegerArray.Leaf row : otherTable.getAllLeaves()) {
final RecalDatum myDatum = myTable.get(row.keys);
if (myDatum == null)
myTable.put((RecalDatum)row.value, row.keys);
else
myDatum.combine((RecalDatum)row.value);
}
RecalUtils.combineTables(myTable, otherTable);
}
}

View File

@ -25,11 +25,13 @@
package org.broadinstitute.sting.utils.recalibration;
import com.google.java.contract.Ensures;
import org.broadinstitute.sting.utils.collections.LoggingNestedIntegerArray;
import org.broadinstitute.sting.utils.recalibration.covariates.Covariate;
import org.broadinstitute.sting.utils.collections.NestedIntegerArray;
import java.io.PrintStream;
import java.util.ArrayList;
/**
* Utility class to facilitate on-the-fly base quality score recalibration.
@ -38,8 +40,7 @@ import java.io.PrintStream;
* Date: 6/20/12
*/
public class RecalibrationTables {
public final class RecalibrationTables {
public enum TableType {
READ_GROUP_TABLE(0),
QUALITY_SCORE_TABLE(1),
@ -52,49 +53,82 @@ public class RecalibrationTables {
}
}
private final NestedIntegerArray[] tables;
private final ArrayList<NestedIntegerArray<RecalDatum>> tables;
private final int qualDimension;
private final int eventDimension = EventType.values().length;
private final int numReadGroups;
private final PrintStream log;
public RecalibrationTables(final Covariate[] covariates) {
this(covariates, covariates[TableType.READ_GROUP_TABLE.index].maximumKeyValue() + 1, null);
}
public RecalibrationTables(final Covariate[] covariates, final PrintStream log) {
this(covariates, covariates[TableType.READ_GROUP_TABLE.index].maximumKeyValue() + 1, log);
}
public RecalibrationTables(final Covariate[] covariates, final int numReadGroups) {
this(covariates, numReadGroups, null);
}
public RecalibrationTables(final Covariate[] covariates, final int numReadGroups, final PrintStream log) {
tables = new NestedIntegerArray[covariates.length];
tables = new ArrayList<NestedIntegerArray<RecalDatum>>(covariates.length);
for ( int i = 0; i < covariates.length; i++ )
tables.add(i, null); // initialize so we can set below
final int qualDimension = covariates[TableType.QUALITY_SCORE_TABLE.index].maximumKeyValue() + 1;
final int eventDimension = EventType.values().length;
qualDimension = covariates[TableType.QUALITY_SCORE_TABLE.index].maximumKeyValue() + 1;
this.numReadGroups = numReadGroups;
this.log = log;
tables.set(TableType.READ_GROUP_TABLE.index,
log == null ? new NestedIntegerArray<RecalDatum>(numReadGroups, eventDimension) :
new LoggingNestedIntegerArray<RecalDatum>(log, "READ_GROUP_TABLE", numReadGroups, eventDimension));
tables.set(TableType.QUALITY_SCORE_TABLE.index, makeQualityScoreTable());
tables[TableType.READ_GROUP_TABLE.index] = log == null ? new NestedIntegerArray<RecalDatum>(numReadGroups, eventDimension) :
new LoggingNestedIntegerArray<RecalDatum>(log, "READ_GROUP_TABLE", numReadGroups, eventDimension);
tables[TableType.QUALITY_SCORE_TABLE.index] = log == null ? new NestedIntegerArray<RecalDatum>(numReadGroups, qualDimension, eventDimension) :
new LoggingNestedIntegerArray<RecalDatum>(log, "QUALITY_SCORE_TABLE", numReadGroups, qualDimension, eventDimension);
for (int i = TableType.OPTIONAL_COVARIATE_TABLES_START.index; i < covariates.length; i++)
tables[i] = log == null ? new NestedIntegerArray<RecalDatum>(numReadGroups, qualDimension, covariates[i].maximumKeyValue()+1, eventDimension) :
new LoggingNestedIntegerArray<RecalDatum>(log, String.format("OPTIONAL_COVARIATE_TABLE_%d", i - TableType.OPTIONAL_COVARIATE_TABLES_START.index + 1),
numReadGroups, qualDimension, covariates[i].maximumKeyValue()+1, eventDimension);
tables.set(i,
log == null ? new NestedIntegerArray<RecalDatum>(numReadGroups, qualDimension, covariates[i].maximumKeyValue()+1, eventDimension) :
new LoggingNestedIntegerArray<RecalDatum>(log, String.format("OPTIONAL_COVARIATE_TABLE_%d", i - TableType.OPTIONAL_COVARIATE_TABLES_START.index + 1),
numReadGroups, qualDimension, covariates[i].maximumKeyValue()+1, eventDimension));
}
@Ensures("result != null")
public NestedIntegerArray<RecalDatum> getReadGroupTable() {
return (NestedIntegerArray<RecalDatum>)tables[TableType.READ_GROUP_TABLE.index];
return getTable(TableType.READ_GROUP_TABLE.index);
}
@Ensures("result != null")
public NestedIntegerArray<RecalDatum> getQualityScoreTable() {
return (NestedIntegerArray<RecalDatum>)tables[TableType.QUALITY_SCORE_TABLE.index];
return getTable(TableType.QUALITY_SCORE_TABLE.index);
}
@Ensures("result != null")
public NestedIntegerArray<RecalDatum> getTable(final int index) {
return (NestedIntegerArray<RecalDatum>)tables[index];
return tables.get(index);
}
@Ensures("result >= 0")
public int numTables() {
return tables.length;
return tables.size();
}
/**
* Allocate a new quality score table, based on requested parameters
* in this set of tables, without any data in it. The return result
* of this table is suitable for acting as a thread-local cache
* for quality score values
* @return a newly allocated, empty read group x quality score table
*/
public NestedIntegerArray<RecalDatum> makeQualityScoreTable() {
return log == null
? new NestedIntegerArray<RecalDatum>(numReadGroups, qualDimension, eventDimension)
: new LoggingNestedIntegerArray<RecalDatum>(log, "QUALITY_SCORE_TABLE", numReadGroups, qualDimension, eventDimension);
}
/**
* Merge in the quality score table information from qualityScoreTable into this
* recalibration table's quality score table.
*
* @param qualityScoreTable the quality score table we want to merge in
*/
public void combineQualityScoreTable(final NestedIntegerArray<RecalDatum> qualityScoreTable) {
RecalUtils.combineTables(getQualityScoreTable(), qualityScoreTable);
}
}

View File

@ -0,0 +1,152 @@
/*
* Copyright (c) 2012 The Broad Institute
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.broadinstitute.sting.utils.recalibration;
import org.broadinstitute.sting.BaseTest;
import org.broadinstitute.sting.utils.Utils;
import org.broadinstitute.sting.utils.collections.NestedIntegerArray;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
public final class RecalUtilsUnitTest extends BaseTest {
private class Row {
int rg, qual, ne, no;
private Row(final Row copy) {
this(copy.rg, copy.qual, copy.ne, copy.no);
}
private Row(int rg, int qual, int ne, int no) {
this.rg = rg;
this.qual = qual;
this.ne = ne;
this.no = no;
}
@Override
public String toString() {
return "Row{" +
"" + rg +
", " + qual +
", " + ne +
", " + no +
'}';
}
}
@DataProvider(name = "CombineTablesProvider")
public Object[][] createCombineTablesProvider() {
List<Object[]> tests = new ArrayList<Object[]>();
final List<Row> rows = new ArrayList<Row>();
for ( final int rg : Arrays.asList(0, 1) ) {
for ( final int qual : Arrays.asList(0, 1) ) {
rows.add(new Row(rg, qual, 1, 10));
}
}
logger.warn("Number of rows " + rows.size());
List<List<Row>> permutations = new LinkedList<List<Row>>();
permutations.addAll(Utils.makePermutations(rows, 1, false));
permutations.addAll(Utils.makePermutations(rows, 2, false));
permutations.addAll(Utils.makePermutations(rows, 3, false));
// adding 1 row to 2
for ( final List<Row> table1 : permutations ) {
for ( final Row table2 : rows ) {
tests.add(new Object[]{table1, Arrays.asList(table2)});
}
}
// adding 2 rows to 1
for ( final List<Row> table1 : permutations ) {
for ( final Row table2 : rows ) {
tests.add(new Object[]{Arrays.asList(table2), table1});
}
}
for ( final List<Row> table1 : permutations ) {
for ( final List<Row> table2 : permutations ) {
tests.add(new Object[]{table1, table2});
}
}
return tests.toArray(new Object[][]{});
}
@Test(dataProvider = "CombineTablesProvider")
public void testCombineTables(final List<Row> table1, final List<Row> table2) {
final NestedIntegerArray<RecalDatum> nia1 = makeTable(table1);
final NestedIntegerArray<RecalDatum> nia2 = makeTable(table2);
final List<Row> expectedRows = makeExpected(table1, table2);
final NestedIntegerArray<RecalDatum> expected = makeTable(expectedRows);
RecalUtils.combineTables(nia1, nia2);
Assert.assertEquals(nia1.getDimensions(), expected.getDimensions());
Assert.assertEquals(nia1.getAllValues().size(), expected.getAllValues().size());
for ( final NestedIntegerArray.Leaf<RecalDatum> leaf : expected.getAllLeaves() ) {
final RecalDatum actual = nia1.get(leaf.keys);
Assert.assertEquals(actual.getNumMismatches(), leaf.value.getNumMismatches());
Assert.assertEquals(actual.getNumObservations(), leaf.value.getNumObservations());
}
}
public List<Row> makeExpected(final List<Row> table1, final List<Row> table2) {
final List<Row> combined = new LinkedList<Row>();
for ( final Row t1 : table1 ) combined.add(new Row(t1));
for ( final Row t2 : table2 ) {
combine(combined, t2);
}
return combined;
}
private void combine(final List<Row> combined, final Row row) {
for ( final Row c : combined ) {
if ( c.rg == row.rg && c.qual == row.qual ) {
c.ne += row.ne;
c.no += row.no;
return;
}
}
combined.add(new Row(row));
}
public NestedIntegerArray<RecalDatum> makeTable(final List<Row> rows) {
final NestedIntegerArray<RecalDatum> x = new NestedIntegerArray<RecalDatum>(3, 3);
for ( final Row r : rows )
x.put(new RecalDatum(r.no, r.ne, (byte)10), r.rg, r.qual);
return x;
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2012 The Broad Institute
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.broadinstitute.sting.utils.recalibration;
import org.broadinstitute.sting.BaseTest;
import org.broadinstitute.sting.utils.collections.NestedIntegerArray;
import org.broadinstitute.sting.utils.recalibration.covariates.*;
import org.testng.Assert;
import org.testng.annotations.Test;
public final class RecalibrationTablesUnitTest extends BaseTest {
@Test
public void basicTest() {
final Covariate[] covariates = RecalibrationTestUtils.makeInitializedStandardCovariates();
final int numReadGroups = 6;
final RecalibrationTables tables = new RecalibrationTables(covariates, numReadGroups);
final Covariate qualCov = covariates[1];
final Covariate cycleCov = covariates[2];
final Covariate contextCov = covariates[3];
Assert.assertEquals(tables.numTables(), covariates.length);
Assert.assertNotNull(tables.getReadGroupTable());
Assert.assertEquals(tables.getReadGroupTable(), tables.getTable(RecalibrationTables.TableType.READ_GROUP_TABLE.index));
testDimensions(tables.getReadGroupTable(), numReadGroups);
Assert.assertNotNull(tables.getQualityScoreTable());
Assert.assertEquals(tables.getQualityScoreTable(), tables.getTable(RecalibrationTables.TableType.QUALITY_SCORE_TABLE.index));
testDimensions(tables.getQualityScoreTable(), numReadGroups, qualCov.maximumKeyValue() + 1);
Assert.assertNotNull(tables.getTable(2));
testDimensions(tables.getTable(2), numReadGroups, qualCov.maximumKeyValue() + 1, cycleCov.maximumKeyValue() + 1);
Assert.assertNotNull(tables.getTable(3));
testDimensions(tables.getTable(3), numReadGroups, qualCov.maximumKeyValue() + 1, contextCov.maximumKeyValue() + 1);
}
private void testDimensions(final NestedIntegerArray<RecalDatum> table, final int ... dimensions) {
final int[] dim = new int[dimensions.length+1];
System.arraycopy(dimensions, 0, dim, 0, dimensions.length);
dim[dimensions.length] = EventType.values().length;
Assert.assertEquals(table.getDimensions().length, dim.length);
for ( int i = 0; i < dim.length; i++ ) {
Assert.assertEquals(table.getDimensions()[i], dim[i], "Table dimensions not expected at dim " + i);
}
}
@Test
public void basicMakeQualityScoreTable() {
final Covariate[] covariates = RecalibrationTestUtils.makeInitializedStandardCovariates();
final int numReadGroups = 6;
final RecalibrationTables tables = new RecalibrationTables(covariates, numReadGroups);
final Covariate qualCov = covariates[1];
final NestedIntegerArray<RecalDatum> copy = tables.makeQualityScoreTable();
testDimensions(copy, numReadGroups, qualCov.maximumKeyValue()+1);
Assert.assertEquals(copy.getAllValues().size(), 0);
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2012 The Broad Institute
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.broadinstitute.sting.utils.recalibration;
import org.broadinstitute.sting.gatk.walkers.bqsr.RecalibrationArgumentCollection;
import org.broadinstitute.sting.utils.recalibration.covariates.*;
/**
* Created with IntelliJ IDEA.
* User: depristo
* Date: 12/23/12
* Time: 1:06 PM
* To change this template use File | Settings | File Templates.
*/
public class RecalibrationTestUtils {
public static Covariate[] makeInitializedStandardCovariates() {
final RecalibrationArgumentCollection RAC = new RecalibrationArgumentCollection();
final Covariate[] covariates = new Covariate[4];
covariates[0] = new ReadGroupCovariate();
covariates[1] = new QualityScoreCovariate();
covariates[2] = new ContextCovariate();
covariates[3] = new CycleCovariate();
for ( Covariate cov : covariates ) cov.initialize(RAC);
return covariates;
}
}