Added unit test for outputting sorted GATKReport Tables

- Made few small modifications to code
- Replaced the two arguments in GATKReportTable constructor with an enum used to specify way of sorting the table
This commit is contained in:
Tad Jordan 2013-01-03 16:25:57 -05:00
parent c7039a9b71
commit c1ba12d71a
8 changed files with 185 additions and 109 deletions

View File

@ -117,7 +117,7 @@ public class GATKReport {
* @param numColumns the number of columns in this table * @param numColumns the number of columns in this table
*/ */
public void addTable(final String tableName, final String tableDescription, final int numColumns) { public void addTable(final String tableName, final String tableDescription, final int numColumns) {
addTable(tableName, tableDescription, numColumns, false, false); addTable(tableName, tableDescription, numColumns, GATKReportTable.TableSortingWay.DO_NOT_SORT);
} }
/** /**
@ -126,11 +126,10 @@ public class GATKReport {
* @param tableName the name of the table * @param tableName the name of the table
* @param tableDescription the description of the table * @param tableDescription the description of the table
* @param numColumns the number of columns in this table * @param numColumns the number of columns in this table
* @param sortByRowID whether to sort the rows by the row ID * @param sortingWay way to sort table
* @param sortByAllColumns whether to sort the rows by all columns starting from leftmost column
*/ */
public void addTable(final String tableName, final String tableDescription, final int numColumns, final boolean sortByRowID, final boolean sortByAllColumns) { public void addTable(final String tableName, final String tableDescription, final int numColumns, final GATKReportTable.TableSortingWay sortingWay) {
GATKReportTable table = new GATKReportTable(tableName, tableDescription, numColumns, sortByRowID, sortByAllColumns); GATKReportTable table = new GATKReportTable(tableName, tableDescription, numColumns, sortingWay);
tables.put(tableName, table); tables.put(tableName, table);
} }

View File

@ -46,8 +46,7 @@ public class GATKReportTable {
private final String tableName; private final String tableName;
private final String tableDescription; private final String tableDescription;
private final boolean sortByRowID; private final TableSortingWay sortingWay;
private final boolean sortByAllColumns;
private List<Object[]> underlyingData; private List<Object[]> underlyingData;
private final List<GATKReportColumn> columnInfo; private final List<GATKReportColumn> columnInfo;
@ -73,6 +72,12 @@ public class GATKReportTable {
public int index() { return index; } public int index() { return index; }
} }
public enum TableSortingWay {
SORT_BY_ROW,
SORT_BY_COLUMN,
DO_NOT_SORT
}
protected enum TableNameHeaderFields { protected enum TableNameHeaderFields {
NAME(2), NAME(2),
DESCRIPTION(3); DESCRIPTION(3);
@ -107,10 +112,7 @@ public class GATKReportTable {
tableDescription = (tableNameData.length <= TableNameHeaderFields.DESCRIPTION.index()) ? "" : tableNameData[TableNameHeaderFields.DESCRIPTION.index()]; // table may have no description! (and that's okay) tableDescription = (tableNameData.length <= TableNameHeaderFields.DESCRIPTION.index()) ? "" : tableNameData[TableNameHeaderFields.DESCRIPTION.index()]; // table may have no description! (and that's okay)
// when reading from a file, we do not re-sort the rows // when reading from a file, we do not re-sort the rows
sortByRowID = false; sortingWay = TableSortingWay.DO_NOT_SORT;
// when reading from a file, we do not re-sort the rows
sortByAllColumns = false;
// initialize the data // initialize the data
final int nColumns = Integer.parseInt(tableData[TableDataHeaderFields.COLS.index()]); final int nColumns = Integer.parseInt(tableData[TableDataHeaderFields.COLS.index()]);
@ -181,7 +183,7 @@ public class GATKReportTable {
* @param numColumns the number of columns in this table * @param numColumns the number of columns in this table
*/ */
public GATKReportTable(final String tableName, final String tableDescription, final int numColumns) { public GATKReportTable(final String tableName, final String tableDescription, final int numColumns) {
this(tableName, tableDescription, numColumns, true, false); this(tableName, tableDescription, numColumns, TableSortingWay.SORT_BY_ROW);
} }
/** /**
@ -190,10 +192,9 @@ public class GATKReportTable {
* @param tableName the name of the table * @param tableName the name of the table
* @param tableDescription the description of the table * @param tableDescription the description of the table
* @param numColumns the number of columns in this table * @param numColumns the number of columns in this table
* @param sortByRowID whether to sort rows by the row ID (instead of the order in which they were added) * @param sortingWay in what way to sort rows (instead of the order in which they were added)
* @param sortByAllColumns whether to sort rows by all columns (instead of the order in which they were added)
*/ */
public GATKReportTable(final String tableName, final String tableDescription, final int numColumns, final boolean sortByRowID, final boolean sortByAllColumns) { public GATKReportTable(final String tableName, final String tableDescription, final int numColumns, final TableSortingWay sortingWay) {
if ( !isValidName(tableName) ) { if ( !isValidName(tableName) ) {
throw new ReviewedStingException("Attempted to set a GATKReportTable name of '" + tableName + "'. GATKReportTable names must be purely alphanumeric - no spaces or special characters are allowed."); throw new ReviewedStingException("Attempted to set a GATKReportTable name of '" + tableName + "'. GATKReportTable names must be purely alphanumeric - no spaces or special characters are allowed.");
} }
@ -204,8 +205,7 @@ public class GATKReportTable {
this.tableName = tableName; this.tableName = tableName;
this.tableDescription = tableDescription; this.tableDescription = tableDescription;
this.sortByRowID = sortByRowID; this.sortingWay = sortingWay;
this.sortByAllColumns = sortByAllColumns;
underlyingData = new ArrayList<Object[]>(INITITAL_ARRAY_SIZE); underlyingData = new ArrayList<Object[]>(INITITAL_ARRAY_SIZE);
columnInfo = new ArrayList<GATKReportColumn>(numColumns); columnInfo = new ArrayList<GATKReportColumn>(numColumns);
@ -218,7 +218,7 @@ public class GATKReportTable {
* @param tableToCopy * @param tableToCopy
*/ */
public GATKReportTable(final GATKReportTable tableToCopy, final boolean copyData) { public GATKReportTable(final GATKReportTable tableToCopy, final boolean copyData) {
this(tableToCopy.getTableName(), tableToCopy.getTableDescription(), tableToCopy.getNumColumns(), tableToCopy.sortByRowID, tableToCopy.sortByAllColumns); this(tableToCopy.getTableName(), tableToCopy.getTableDescription(), tableToCopy.getNumColumns(), tableToCopy.sortingWay);
for ( final GATKReportColumn column : tableToCopy.getColumnInfo() ) for ( final GATKReportColumn column : tableToCopy.getColumnInfo() )
addColumn(column.getColumnName(), column.getFormat()); addColumn(column.getColumnName(), column.getFormat());
if ( copyData ) if ( copyData )
@ -569,7 +569,8 @@ public class GATKReportTable {
out.println(); out.println();
// write the table body // write the table body
if ( sortByAllColumns ) { switch (sortingWay) {
case SORT_BY_COLUMN:
Collections.sort(underlyingData, new Comparator<Object[]>() { Collections.sort(underlyingData, new Comparator<Object[]>() {
//INVARIANT the two arrays are of the same length and corresponding elements are of the same type //INVARIANT the two arrays are of the same length and corresponding elements are of the same type
@Override @Override
@ -582,27 +583,22 @@ public class GATKReportTable {
for (int x = 0; x < l; x++) { for (int x = 0; x < l; x++) {
if (objectArr1[x] instanceof Integer) { if (objectArr1[x] instanceof Integer) {
result = ((Integer)objectArr1[x]).compareTo((Integer)objectArr2[x]); result = ((Integer)objectArr1[x]).compareTo((Integer)objectArr2[x]);
if( result != EQUAL) {
return result;
}
} else if (objectArr1[x] instanceof Double) { } else if (objectArr1[x] instanceof Double) {
result = ((Double)objectArr1[x]).compareTo((Double)objectArr2[x]); result = ((Double)objectArr1[x]).compareTo((Double)objectArr2[x]);
if( result != EQUAL) {
return result;
}
} else { // default uses String comparison } else { // default uses String comparison
result = objectArr1[x].toString().compareTo(objectArr2[x].toString()); result = objectArr1[x].toString().compareTo(objectArr2[x].toString());
}
if( result != EQUAL) { if( result != EQUAL) {
return result; return result;
} }
} }
}
return result; return result;
} }
}); });
for ( final Object[] row : underlyingData ) for ( final Object[] row : underlyingData )
writeRow(out, row); writeRow(out, row);
} else if ( sortByRowID ) { break;
case SORT_BY_ROW:
// make sure that there are exactly the correct number of ID mappings // make sure that there are exactly the correct number of ID mappings
if ( rowIdToIndex.size() != underlyingData.size() ) if ( rowIdToIndex.size() != underlyingData.size() )
throw new ReviewedStingException("There isn't a 1-to-1 mapping from row ID to index; this can happen when rows are not created consistently"); throw new ReviewedStingException("There isn't a 1-to-1 mapping from row ID to index; this can happen when rows are not created consistently");
@ -615,7 +611,8 @@ public class GATKReportTable {
} }
for ( final Map.Entry<Object, Integer> rowKey : sortedMap.entrySet() ) for ( final Map.Entry<Object, Integer> rowKey : sortedMap.entrySet() )
writeRow(out, underlyingData.get(rowKey.getValue())); writeRow(out, underlyingData.get(rowKey.getValue()));
} else { break;
case DO_NOT_SORT:
for ( final Object[] row : underlyingData ) for ( final Object[] row : underlyingData )
writeRow(out, row); writeRow(out, row);
} }
@ -735,42 +732,33 @@ public class GATKReportTable {
} }
private List<Object[]> getOrderedRows() { private List<Object[]> getOrderedRows() {
if ( sortByAllColumns ) {
switch (sortingWay) {
case SORT_BY_COLUMN:
Collections.sort(underlyingData, new Comparator<Object[]>() { Collections.sort(underlyingData, new Comparator<Object[]>() {
//INVARIANT the two arrays are of the same length and corresponding elements are of the same type //INVARIANT the two arrays are of the same length and corresponding elements are of the same type
@Override @Override
public int compare(Object[] objectArr1, Object[] objectArr2) { public int compare(Object[] objectArr1, Object[] objectArr2) {
final int EQUAL = 0; final int EQUAL = 0;
int result = EQUAL; int result = EQUAL;
int l = objectArr1.length; int l = objectArr1.length;
for (int x = 0; x < l; x++) { for (int x = 0; x < l; x++) {
if (objectArr1[x] instanceof Integer) { if (objectArr1[x] instanceof Integer) {
result = ((Integer)objectArr1[x]).compareTo((Integer)objectArr2[x]); result = ((Integer)objectArr1[x]).compareTo((Integer)objectArr2[x]);
if( result != EQUAL) {
return result;
}
} else if (objectArr1[x] instanceof Double) { } else if (objectArr1[x] instanceof Double) {
result = ((Double)objectArr1[x]).compareTo((Double)objectArr2[x]); result = ((Double)objectArr1[x]).compareTo((Double)objectArr2[x]);
if( result != EQUAL) {
return result;
}
} else { // default uses String comparison } else { // default uses String comparison
result = objectArr1[x].toString().compareTo(objectArr2[x].toString()); result = objectArr1[x].toString().compareTo(objectArr2[x].toString());
}
if( result != EQUAL) { if( result != EQUAL) {
return result; return result;
} }
} }
}
return result; return result;
} }
}); });
return underlyingData; return underlyingData;
} else if ( !sortByRowID ) { case SORT_BY_ROW:
return underlyingData;
}
final TreeMap<Object, Integer> sortedMap; final TreeMap<Object, Integer> sortedMap;
try { try {
sortedMap = new TreeMap<Object, Integer>(rowIdToIndex); sortedMap = new TreeMap<Object, Integer>(rowIdToIndex);
@ -783,5 +771,8 @@ public class GATKReportTable {
orderedData.add(underlyingData.get(rowKey)); orderedData.add(underlyingData.get(rowKey));
return orderedData; return orderedData;
default:
return underlyingData;
}
} }
} }

View File

@ -207,7 +207,7 @@ public class RecalibrationArgumentCollection {
public GATKReportTable generateReportTable(final String covariateNames) { public GATKReportTable generateReportTable(final String covariateNames) {
GATKReportTable argumentsTable; GATKReportTable argumentsTable;
if(SORT_BY_ALL_COLUMNS) { if(SORT_BY_ALL_COLUMNS) {
argumentsTable = new GATKReportTable("Arguments", "Recalibration argument collection values used in this run", 2, false, true); argumentsTable = new GATKReportTable("Arguments", "Recalibration argument collection values used in this run", 2, GATKReportTable.TableSortingWay.SORT_BY_COLUMN);
} else { } else {
argumentsTable = new GATKReportTable("Arguments", "Recalibration argument collection values used in this run", 2); argumentsTable = new GATKReportTable("Arguments", "Recalibration argument collection values used in this run", 2);
} }

View File

@ -124,7 +124,7 @@ public class ErrorRatePerCycle extends LocusWalker<Integer, Integer> {
public void initialize() { public void initialize() {
report = new GATKReport(); report = new GATKReport();
report.addTable(reportName, reportDescription, 6, true, false); report.addTable(reportName, reportDescription, 6, GATKReportTable.TableSortingWay.SORT_BY_ROW);
table = report.getTable(reportName); table = report.getTable(reportName);
table.addColumn("readgroup"); table.addColumn("readgroup");
table.addColumn("cycle"); table.addColumn("cycle");

View File

@ -162,7 +162,7 @@ public class VariantEvalReportWriter {
// create the table // create the table
final String tableName = ve.getSimpleName(); final String tableName = ve.getSimpleName();
final String tableDesc = ve.getClass().getAnnotation(Analysis.class).description(); final String tableDesc = ve.getClass().getAnnotation(Analysis.class).description();
report.addTable(tableName, tableDesc, 1 + stratifiers.size() + (scanner.hasMoltenField() ? 2 : datamap.size()), true, false); report.addTable(tableName, tableDesc, 1 + stratifiers.size() + (scanner.hasMoltenField() ? 2 : datamap.size()), GATKReportTable.TableSortingWay.SORT_BY_ROW);
// grab the table, and add the columns we need to it // grab the table, and add the columns we need to it
final GATKReportTable table = report.getTable(tableName); final GATKReportTable table = report.getTable(tableName);

View File

@ -70,7 +70,7 @@ public class QuantizationInfo {
public GATKReportTable generateReportTable(boolean sortBycols) { public GATKReportTable generateReportTable(boolean sortBycols) {
GATKReportTable quantizedTable; GATKReportTable quantizedTable;
if(sortBycols) { if(sortBycols) {
quantizedTable = new GATKReportTable(RecalUtils.QUANTIZED_REPORT_TABLE_TITLE, "Quality quantization map", 3, false, true); quantizedTable = new GATKReportTable(RecalUtils.QUANTIZED_REPORT_TABLE_TITLE, "Quality quantization map", 3, GATKReportTable.TableSortingWay.SORT_BY_COLUMN);
} else { } else {
quantizedTable = new GATKReportTable(RecalUtils.QUANTIZED_REPORT_TABLE_TITLE, "Quality quantization map", 3); quantizedTable = new GATKReportTable(RecalUtils.QUANTIZED_REPORT_TABLE_TITLE, "Quality quantization map", 3);
} }

View File

@ -287,7 +287,7 @@ public class RecalUtils {
final GATKReportTable reportTable; final GATKReportTable reportTable;
if (tableIndex <= RecalibrationTables.TableType.OPTIONAL_COVARIATE_TABLES_START.index) { if (tableIndex <= RecalibrationTables.TableType.OPTIONAL_COVARIATE_TABLES_START.index) {
if(sortByCols) { if(sortByCols) {
reportTable = new GATKReportTable("RecalTable" + reportTableIndex++, "", columnNames.size(), false, true); reportTable = new GATKReportTable("RecalTable" + reportTableIndex++, "", columnNames.size(), GATKReportTable.TableSortingWay.SORT_BY_COLUMN);
} else { } else {
reportTable = new GATKReportTable("RecalTable" + reportTableIndex++, "", columnNames.size()); reportTable = new GATKReportTable("RecalTable" + reportTableIndex++, "", columnNames.size());
} }

View File

@ -32,6 +32,13 @@ import org.testng.annotations.Test;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.Random;
import java.io.FileInputStream;
import java.io.DataInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class GATKReportUnitTest extends BaseTest { public class GATKReportUnitTest extends BaseTest {
@Test @Test
@ -77,6 +84,85 @@ public class GATKReportUnitTest extends BaseTest {
Assert.assertEquals(GATKReportColumn.isRightAlign(value), expected, "right align of '" + value + "'"); Assert.assertEquals(GATKReportColumn.isRightAlign(value), expected, "right align of '" + value + "'");
} }
private GATKReportTable getTableWithRandomValues() {
Random number = new Random(123L);
final int VALUESRANGE = 10;
GATKReport report = GATKReport.newSimpleReport("TableName", "col1", "col2", "col3");
GATKReportTable table = new GATKReportTable("testSortingTable", "table with random values sorted by columns", 3, GATKReportTable.TableSortingWay.SORT_BY_COLUMN );
final int NUMROWS = 100;
for (int x = 0; x < NUMROWS; x++) {
report.addRow(number.nextInt(VALUESRANGE), number.nextInt(VALUESRANGE), number.nextInt(VALUESRANGE));
}
return table;
}
@Test(enabled = true)
public void testSortingByColumn() {
Assert.assertEquals(isSorted(getTableWithRandomValues()), true);
}
private boolean isSorted(GATKReportTable table) {
boolean result = true;
File testingSortingTableFile = new File("myFile.txt");
try {
// Connect print stream to the output stream
PrintStream ps = new PrintStream(testingSortingTableFile);
table.write(ps);
ps.close();
}
catch (Exception e){
System.err.println ("Error: " + e.getMessage());
}
ArrayList<int[]> rows = new ArrayList<int[]>();
try {
// Open the file
FileInputStream fStream = new FileInputStream(testingSortingTableFile);
// Get the object of DataInputStream
DataInputStream in = new DataInputStream(fStream);
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
String[] parts = strLine.split(" ");
int l = parts.length;
int[] row = new int[l];
for(int n = 0; n < l; n++) {
row[n] = Integer.parseInt(parts[n]);
}
rows.add(row);
}
//Close the input stream
in.close();
} catch (Exception e){//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
for (int x = 1; x < rows.size() && result; x++) {
result = checkRowOrder(rows.get(x - 1), rows.get(x));
}
return result;
}
private boolean checkRowOrder(int[] row1, int[] row2) {
int l = row1.length;
final int EQUAL = 0;
int result = EQUAL;
for(int x = 0; x < l && ( result <= EQUAL); x++) {
result = ((Integer)row1[x]).compareTo(row2[x]);
}
if (result <= EQUAL) {
return true;
} else {
return false;
}
}
private GATKReportTable makeBasicTable() { private GATKReportTable makeBasicTable() {
GATKReport report = GATKReport.newSimpleReport("TableName", "sample", "value"); GATKReport report = GATKReport.newSimpleReport("TableName", "sample", "value");
GATKReportTable table = report.getTable("TableName"); GATKReportTable table = report.getTable("TableName");
@ -168,7 +254,7 @@ public class GATKReportUnitTest extends BaseTest {
table.set("RZ", "SomeFloat", 535646345.657453464576); table.set("RZ", "SomeFloat", 535646345.657453464576);
table.set("RZ", "TrueFalse", true); table.set("RZ", "TrueFalse", true);
report1.addTable("Table3", "blah", 1, true, false); report1.addTable("Table3", "blah", 1, GATKReportTable.TableSortingWay.SORT_BY_ROW);
report1.getTable("Table3").addColumn("a"); report1.getTable("Table3").addColumn("a");
report1.getTable("Table3").addRowIDMapping("q", 2); report1.getTable("Table3").addRowIDMapping("q", 2);
report1.getTable("Table3").addRowIDMapping("5", 3); report1.getTable("Table3").addRowIDMapping("5", 3);