diff --git a/public/java/src/org/broadinstitute/sting/gatk/report/GATKReport.java b/public/java/src/org/broadinstitute/sting/gatk/report/GATKReport.java index 009137ac7..7edadfc4b 100755 --- a/public/java/src/org/broadinstitute/sting/gatk/report/GATKReport.java +++ b/public/java/src/org/broadinstitute/sting/gatk/report/GATKReport.java @@ -25,7 +25,6 @@ package org.broadinstitute.sting.gatk.report; import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; -import org.broadinstitute.sting.utils.exceptions.StingException; import org.broadinstitute.sting.utils.exceptions.UserException; import java.io.*; @@ -43,7 +42,7 @@ public class GATKReport { private static final String SEPARATOR = ":"; private GATKReportVersion version = LATEST_REPORT_VERSION; - private final TreeMap tables = new TreeMap(); + private final TreeMap tables = new TreeMap(); /** * Create a new, empty GATKReport. @@ -73,8 +72,8 @@ public class GATKReport { * Create a new GATK report from GATK report tables * @param tables Any number of tables that you want to add to the report */ - public GATKReport(GATKReportTableV2... tables) { - for( GATKReportTableV2 table: tables) + public GATKReport(GATKReportTable... tables) { + for( GATKReportTable table: tables) addTable(table); } @@ -106,7 +105,7 @@ public class GATKReport { // Read each table according ot the number of tables for (int i = 0; i < nTables; i++) { - addTable(new GATKReportTableV2(reader, version)); + addTable(new GATKReportTable(reader, version)); } } @@ -130,7 +129,7 @@ public class GATKReport { * @param sortByRowID whether to sort the rows by the row ID */ public void addTable(final String tableName, final String tableDescription, final int numColumns, final boolean sortByRowID) { - GATKReportTableV2 table = new GATKReportTableV2(tableName, tableDescription, numColumns, sortByRowID); + GATKReportTable table = new GATKReportTable(tableName, tableDescription, numColumns, sortByRowID); tables.put(tableName, table); } @@ -139,12 +138,12 @@ public class GATKReport { * * @param table the table to add */ - public void addTable(GATKReportTableV2 table) { + public void addTable(GATKReportTable table) { tables.put(table.getTableName(), table); } - public void addTables(List gatkReportTableV2s) { - for ( GATKReportTableV2 table : gatkReportTableV2s ) + public void addTables(List gatkReportTableV2s) { + for ( GATKReportTable table : gatkReportTableV2s ) addTable(table); } @@ -164,8 +163,8 @@ public class GATKReport { * @param tableName the name of the table * @return the table object */ - public GATKReportTableV2 getTable(String tableName) { - GATKReportTableV2 table = tables.get(tableName); + public GATKReportTable getTable(String tableName) { + GATKReportTable table = tables.get(tableName); if (table == null) throw new ReviewedStingException("Table is not in GATKReport: " + tableName); return table; @@ -178,11 +177,11 @@ public class GATKReport { */ public void print(PrintStream out) { out.println(GATKREPORT_HEADER_PREFIX + getVersion().toString() + SEPARATOR + getTables().size()); - for (GATKReportTableV2 table : tables.values()) + for (GATKReportTable table : tables.values()) table.write(out); } - public Collection getTables() { + public Collection getTables() { return tables.values(); } @@ -198,7 +197,7 @@ public class GATKReport { throw new ReviewedStingException("Failed to combine GATKReport, format doesn't match!"); } - for ( Map.Entry table : tables.entrySet() ) { + for ( Map.Entry table : tables.entrySet() ) { table.getValue().concat(input.getTable(table.getKey())); } } @@ -272,7 +271,7 @@ public class GATKReport { * @return a simplified GATK report */ public static GATKReport newSimpleReport(final String tableName, final String... columns) { - GATKReportTableV2 table = new GATKReportTableV2(tableName, "A simplified GATK table report", columns.length); + GATKReportTable table = new GATKReportTable(tableName, "A simplified GATK table report", columns.length); for (String column : columns) { table.addColumn(column, ""); @@ -296,7 +295,7 @@ public class GATKReport { if ( tables.size() != 1 ) throw new ReviewedStingException("Cannot write a row to a complex GATK Report"); - GATKReportTableV2 table = tables.firstEntry().getValue(); + GATKReportTable table = tables.firstEntry().getValue(); if ( table.getNumColumns() != values.length ) throw new ReviewedStingException("The number of arguments in writeRow() must match the number of columns in the table"); diff --git a/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportColumn.java b/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportColumn.java index 1e798143a..c4ec8bdd6 100755 --- a/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportColumn.java +++ b/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportColumn.java @@ -28,20 +28,17 @@ import org.apache.commons.lang.math.NumberUtils; import java.util.Arrays; import java.util.Collection; -import java.util.LinkedHashMap; /** - * Holds values for a column in a GATK report table + * column information within a GATK report table */ -public class GATKReportColumn extends LinkedHashMap { +public class GATKReportColumn { final private String columnName; - final private Object defaultValue; final private String format; - final private boolean display; final private GATKReportDataType dataType; private GATKReportColumnFormat columnFormat; - private GATKReportColumnFormat.Alignment alignment = GATKReportColumnFormat.Alignment.RIGHT; // default alignment is to the right unless values added ask for a left alignment + private GATKReportColumnFormat.Alignment alignment = GATKReportColumnFormat.Alignment.RIGHT; // default alignment is to the right unless values added ask for a left alignment private int maxWidth = 0; /** @@ -49,72 +46,21 @@ public class GATKReportColumn extends LinkedHashMap { * displayed, and the format string. This cannot be null. * * @param columnName the name of the column - * @param defaultValue the default value of the column - * @param display if true, the column will be displayed in the final output * @param format format string */ - public GATKReportColumn(String columnName, Object defaultValue, boolean display, String format) { + public GATKReportColumn(final String columnName, final String format) { this.columnName = columnName; this.maxWidth = columnName.length(); - this.display = display; if ( format.equals("") ) { this.format = "%s"; this.dataType = GATKReportDataType.Unknown; - this.defaultValue = (defaultValue != null) ? defaultValue : ""; } else { this.format = format; this.dataType = GATKReportDataType.fromFormatString(format); - this.defaultValue = (defaultValue != null) ? defaultValue : dataType.getDefaultValue(); } } - /** - * Initialize an element in the column with a default value - * - * @param primaryKey the primary key position in the column that should be set - */ - public void initialize(Object primaryKey) { - this.put(primaryKey, defaultValue); - } - - /** - * Return an object from the column, but if it doesn't exist, return the default value. This is useful when writing - * tables, as the table gets written properly without having to waste storage for the unset elements (usually the - * zero - * values) in the table. - * - * @param primaryKey the primary key position in the column that should be retrieved - * @return the value at the specified position in the column, or the default value if the element is not set - */ - private Object getWithoutSideEffects(Object primaryKey) { - if (!this.containsKey(primaryKey)) { - return defaultValue; - } - - return this.get(primaryKey); - } - - /** - * Return an object from the column, but if it doesn't exist, return the default value. - * - * @param primaryKey the primary key position in the column that should be retrieved - * @return the string value at the specified position in the column, or the default value if the element is not set - */ - public String getStringValue(Object primaryKey) { - return formatValue(getWithoutSideEffects(primaryKey)); - } - - /** - * Return the displayable property of the column. If true, the column will be displayed in the final output. - * If not, printing will be suppressed for the contents of the table. - * - * @return true if the column will be displayed, false if otherwise - */ - public boolean isDisplayable() { - return display; - } - /** * Get the display width for this column. This allows the entire column to be displayed with the appropriate, fixed * width. @@ -143,7 +89,7 @@ public class GATKReportColumn extends LinkedHashMap { * @param value to check * @return true if the value is a right alignable */ - protected static boolean isRightAlign(String value) { + protected static boolean isRightAlign(final String value) { return value == null || RIGHT_ALIGN_STRINGS.contains(value) || NumberUtils.isNumber(value.trim()); } @@ -153,7 +99,7 @@ public class GATKReportColumn extends LinkedHashMap { * @param obj The object to convert to a string * @return The string representation of the column */ - private String formatValue(Object obj) { + private String formatValue(final Object obj) { String value; if (obj == null) { value = "null"; @@ -171,61 +117,29 @@ public class GATKReportColumn extends LinkedHashMap { return dataType; } - public boolean isSameFormat(GATKReportColumn that) { - return (dataType.equals(that.dataType) && - columnName.equals(that.columnName) && - display == that.display && - format.equals(that.format) && - defaultValue.equals(that.defaultValue) ); - } - - boolean equals(GATKReportColumn that) { - if ( !this.keySet().equals(that.keySet()) ) { - return false; - } - - for (Object key : keySet()) { - Object ValueA = this.get(key); - Object ValueB = that.get(key); - - //if the value is not equal, (use data type to get the right comparison) - if (!dataType.isEqual(ValueA, ValueB)) { - return false; - } - } - - return true; - } - public String getColumnName() { return columnName; } public String getFormat() { - if ( dataType.equals(GATKReportDataType.Unknown) ) { - return ""; - } - else - return format; + return dataType.equals(GATKReportDataType.Unknown) ? "%s" : format; } - @Override - public Object put(Object key, Object value) { + public void updateFormatting(final Object value) { if (value != null) { - String formatted = formatValue(value); - if (!formatted.equals("")) { + final String formatted = formatValue(value); + if ( formatted.length() > 0 ) { updateMaxWidth(formatted); updateFormat(formatted); } } - return super.put(key, value); } - private void updateMaxWidth(String formatted) { + private void updateMaxWidth(final String formatted) { maxWidth = Math.max(formatted.length(), maxWidth); } - private void updateFormat(String formatted) { + private void updateFormat(final String formatted) { if (alignment == GATKReportColumnFormat.Alignment.RIGHT) alignment = isRightAlign(formatted) ? GATKReportColumnFormat.Alignment.RIGHT : GATKReportColumnFormat.Alignment.LEFT; } diff --git a/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportColumnV2.java b/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportColumnV2.java deleted file mode 100755 index d7200fd56..000000000 --- a/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportColumnV2.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * 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.gatk.report; - -import org.apache.commons.lang.math.NumberUtils; - -import java.util.Arrays; -import java.util.Collection; - -/** - * column information within a GATK report table - */ -public class GATKReportColumnV2 { - final private String columnName; - final private String format; - final private GATKReportDataType dataType; - - private GATKReportColumnFormat columnFormat; - private GATKReportColumnFormat.Alignment alignment = GATKReportColumnFormat.Alignment.RIGHT; // default alignment is to the right unless values added ask for a left alignment - private int maxWidth = 0; - - /** - * Construct the column object, specifying the column name, default value, whether or not the column should be - * displayed, and the format string. This cannot be null. - * - * @param columnName the name of the column - * @param format format string - */ - public GATKReportColumnV2(final String columnName, final String format) { - this.columnName = columnName; - this.maxWidth = columnName.length(); - if ( format.equals("") ) { - this.format = "%s"; - this.dataType = GATKReportDataType.Unknown; - } - else { - this.format = format; - this.dataType = GATKReportDataType.fromFormatString(format); - } - } - - /** - * Get the display width for this column. This allows the entire column to be displayed with the appropriate, fixed - * width. - * - * @return the format string for this column - */ - public GATKReportColumnFormat getColumnFormat() { - if (columnFormat != null) - return columnFormat; - - columnFormat = new GATKReportColumnFormat(maxWidth, alignment); - return columnFormat; - } - - private static final Collection RIGHT_ALIGN_STRINGS = Arrays.asList( - "null", - "NA", - String.valueOf(Double.POSITIVE_INFINITY), - String.valueOf(Double.NEGATIVE_INFINITY), - String.valueOf(Double.NaN)); - - /** - * Check if the value can be right aligned. Does not trim the values before checking if numeric since it assumes - * the spaces mean that the value is already padded. - * - * @param value to check - * @return true if the value is a right alignable - */ - protected static boolean isRightAlign(final String value) { - return value == null || RIGHT_ALIGN_STRINGS.contains(value) || NumberUtils.isNumber(value.trim()); - } - - /** - * Returns a string version of the values. - * - * @param obj The object to convert to a string - * @return The string representation of the column - */ - private String formatValue(final Object obj) { - String value; - if (obj == null) { - value = "null"; - } - else if ( dataType.equals(GATKReportDataType.Unknown) && (obj instanceof Double || obj instanceof Float) ) { - value = String.format("%.8f", obj); - } - else - value = String.format(format, obj); - - return value; - } - - public GATKReportDataType getDataType() { - return dataType; - } - - public String getColumnName() { - return columnName; - } - - public String getFormat() { - return dataType.equals(GATKReportDataType.Unknown) ? "%s" : format; - } - - public void updateFormatting(final Object value) { - if (value != null) { - final String formatted = formatValue(value); - if ( formatted.length() > 0 ) { - updateMaxWidth(formatted); - updateFormat(formatted); - } - } - } - - private void updateMaxWidth(final String formatted) { - maxWidth = Math.max(formatted.length(), maxWidth); - } - - private void updateFormat(final String formatted) { - if (alignment == GATKReportColumnFormat.Alignment.RIGHT) - alignment = isRightAlign(formatted) ? GATKReportColumnFormat.Alignment.RIGHT : GATKReportColumnFormat.Alignment.LEFT; - } -} diff --git a/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportColumns.java b/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportColumns.java deleted file mode 100755 index bb6e3a4f1..000000000 --- a/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportColumns.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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.gatk.report; - -import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; - -import java.util.*; - -/** - * Tracks a linked list of GATKReportColumn in order by name. - */ -public class GATKReportColumns extends LinkedHashMap implements Iterable { - private final List columnNames = new ArrayList(); - - /** - * Returns the column by index - * - * @param i the index - * @return The column - */ - public GATKReportColumn getByIndex(int i) { - return get(columnNames.get(i)); - } - - @Override - public GATKReportColumn remove(Object columnName) { - if ( !(columnName instanceof String) ) { - throw new ReviewedStingException("The column name must be a String!"); - } - columnNames.remove(columnName.toString()); - return super.remove(columnName); - } - - @Override - public GATKReportColumn put(String key, GATKReportColumn value) { - columnNames.add(key); - return super.put(key, value); - } - - @Override - public Iterator iterator() { - return new Iterator() { - int offset = 0; - - public boolean hasNext() { - return offset < columnNames.size(); - } - - public GATKReportColumn next() { - return getByIndex(offset++); - } - - public void remove() { - throw new UnsupportedOperationException("Cannot remove from a GATKReportColumn iterator"); - } - }; - } - - public boolean isSameFormat(GATKReportColumns that) { - if (!columnNames.equals(that.columnNames)) { - return false; - } - for (String columnName : columnNames) { - if (!this.get(columnName).isSameFormat(that.get(columnName))) { - return false; - } - } - return true; - } - - boolean equals(GATKReportColumns that) { - for (Map.Entry pair : entrySet()) { - // Make sure that every column is the same, we know that the # of columns - // is the same from isSameFormat() - String key = pair.getKey(); - - if (!get(key).equals(that.get(key))) { - return false; - } - } - - return true; - } -} diff --git a/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportTable.java b/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportTable.java index 6551bf376..2f1b6b602 100755 --- a/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportTable.java +++ b/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportTable.java @@ -24,7 +24,6 @@ package org.broadinstitute.sting.gatk.report; -import org.apache.commons.lang.ObjectUtils; import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; import org.broadinstitute.sting.utils.text.TextFormattingUtils; @@ -44,123 +43,162 @@ public class GATKReportTable { private static final String SEPARATOR = ":"; private static final String ENDLINE = ":;"; - private String tableName; - private String tableDescription; + private final String tableName; + private final String tableDescription; + private final boolean sortByRowID; - private String primaryKeyName; - private Collection primaryKeyColumn; - private boolean primaryKeyDisplay; - private boolean sortByPrimaryKey = true; - - private GATKReportColumns columns; + private List underlyingData; + private final List columnInfo; + private final Map columnNameToIndex; + private final HashMap rowIdToIndex; private static final String COULD_NOT_READ_HEADER = "Could not read the header of this file -- "; private static final String COULD_NOT_READ_COLUMN_NAMES = "Could not read the column names of this file -- "; private static final String COULD_NOT_READ_DATA_LINE = "Could not read a data line of this table -- "; private static final String COULD_NOT_READ_EMPTY_LINE = "Could not read the last empty line of this table -- "; private static final String OLD_GATK_TABLE_VERSION = "We no longer support older versions of the GATK Tables"; - + + private static final int INITITAL_ARRAY_SIZE = 10000; private static final String NUMBER_CONVERSION_EXCEPTION = "String is a number but is not a long or a double: "; - public GATKReportTable(BufferedReader reader, GATKReportVersion version) { - int counter = 0; + protected enum TableDataHeaderFields { + COLS(2), + ROWS(3), + FORMAT_START(4); - switch (version) { - case V1_0: - int nHeaders = 2; - String[] tableHeaders = new String[nHeaders]; - - // Read in the headers - for (int i = 0; i < nHeaders; i++) { - try { - tableHeaders[i] = reader.readLine(); - } catch (IOException e) { - throw new ReviewedStingException(COULD_NOT_READ_HEADER + e.getMessage()); - } - } - String[] tableData = tableHeaders[0].split(":"); - String[] userData = tableHeaders[1].split(":"); - - // Fill in the fields - tableName = userData[2]; - tableDescription = (userData.length <= 3) ? "" : userData[3]; // table may have no description! (and that's okay) - primaryKeyDisplay = Boolean.parseBoolean(tableData[2]); - columns = new GATKReportColumns(); - - int nColumns = Integer.parseInt(tableData[3]); - int nRows = Integer.parseInt(tableData[4]); - - - // Read column names - String columnLine; + private final int index; + TableDataHeaderFields(int index) { this.index = index; } + public int index() { return index; } + } + + protected enum TableNameHeaderFields { + NAME(2), + DESCRIPTION(3); + + private final int index; + TableNameHeaderFields(int index) { this.index = index; } + public int index() { return index; } + } + + public GATKReportTable(BufferedReader reader, GATKReportVersion version) { + + switch ( version ) { + case V1_1: + // read in the header lines + final String[] tableData, tableNameData; try { - columnLine = reader.readLine(); + tableData = reader.readLine().split(SEPARATOR); + tableNameData = reader.readLine().split(SEPARATOR); + } catch (IOException e) { + throw new ReviewedStingException(COULD_NOT_READ_HEADER + e.getMessage()); + } + + // parse the header fields + tableName = tableNameData[TableNameHeaderFields.NAME.index()]; + 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 + sortByRowID = false; + + // initialize the data + final int nColumns = Integer.parseInt(tableData[TableDataHeaderFields.COLS.index()]); + final int nRows = Integer.parseInt(tableData[TableDataHeaderFields.ROWS.index()]); + underlyingData = new ArrayList(nRows); + columnInfo = new ArrayList(nColumns); + columnNameToIndex = new HashMap(nColumns); + + // when reading from a file, the row ID mapping is just the index + rowIdToIndex = new HashMap(); + for ( int i = 0; i < nRows; i++ ) + rowIdToIndex.put(i, i); + + // read the column names + final String columnLine; + try { + columnLine = reader.readLine(); } catch (IOException e) { throw new ReviewedStingException(COULD_NOT_READ_COLUMN_NAMES); } - - List columnStarts = TextFormattingUtils.getWordStarts(columnLine); - String[] columnNames = TextFormattingUtils.splitFixedWidth(columnLine, columnStarts); - - if (primaryKeyDisplay) { - addPrimaryKey(columnNames[0]); - - } else { - sortByPrimaryKey = true; - addPrimaryKey("id", false); - counter = 1; - } + + final List columnStarts = TextFormattingUtils.getWordStarts(columnLine); + final String[] columnNames = TextFormattingUtils.splitFixedWidth(columnLine, columnStarts); + // Put in columns using the format string from the header - for (int i = 0; i < nColumns; i++) { - String format = tableData[5 + i]; - if (primaryKeyDisplay) - addColumn(columnNames[i + 1], true, format); - else - addColumn(columnNames[i], true, format); + for ( int i = 0; i < nColumns; i++ ) { + final String format = tableData[TableDataHeaderFields.FORMAT_START.index() + i]; + addColumn(columnNames[i], format); } - - for (int i = 0; i < nRows; i++) { - // read line - String dataLine; - try { - dataLine = reader.readLine(); - } catch (IOException e) { - throw new ReviewedStingException(COULD_NOT_READ_DATA_LINE + e.getMessage()); - } - List lineSplits = Arrays.asList(TextFormattingUtils.splitFixedWidth(dataLine, columnStarts)); - - for (int columnIndex = 0; columnIndex < nColumns; columnIndex++) { - - //Input all the remaining values - GATKReportDataType type = getColumns().getByIndex(columnIndex).getDataType(); - - if (primaryKeyDisplay) { - String columnName = columnNames[columnIndex + 1]; - String primaryKey = lineSplits.get(0); - set(primaryKey, columnName, type.Parse(lineSplits.get(columnIndex + 1))); - } else { - String columnName = columnNames[columnIndex]; - set(counter, columnName, type.Parse(lineSplits.get(columnIndex))); + + // fill in the table + try { + for ( int i = 0; i < nRows; i++ ) { + // read a data line + final String dataLine = reader.readLine(); + final List lineSplits = Arrays.asList(TextFormattingUtils.splitFixedWidth(dataLine, columnStarts)); + + underlyingData.add(new Object[nColumns]); + for ( int columnIndex = 0; columnIndex < nColumns; columnIndex++ ) { + + final GATKReportDataType type = columnInfo.get(columnIndex).getDataType(); + final String columnName = columnNames[columnIndex]; + set(i, columnName, type.Parse(lineSplits.get(columnIndex))); + } - } - counter++; + } catch (IOException e) { + throw new ReviewedStingException(COULD_NOT_READ_DATA_LINE + e.getMessage()); } - - + try { reader.readLine(); } catch (IOException e) { throw new ReviewedStingException(COULD_NOT_READ_EMPTY_LINE + e.getMessage()); - } + } break; - - default: + + default: throw new ReviewedStingException(OLD_GATK_TABLE_VERSION); } } + /** + * Construct a new GATK report table with the specified name and description + * + * @param tableName the name of the table + * @param tableDescription the description of the table + * @param numColumns the number of columns in this table + */ + public GATKReportTable(final String tableName, final String tableDescription, final int numColumns) { + this(tableName, tableDescription, numColumns, true); + } + + /** + * Construct a new GATK report table with the specified name and description and whether to sort rows by the row ID. + * + * @param tableName the name of the table + * @param tableDescription the description of the 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) + */ + public GATKReportTable(final String tableName, final String tableDescription, final int numColumns, final boolean sortByRowID) { + 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."); + } + + if ( !isValidDescription(tableDescription) ) { + throw new ReviewedStingException("Attempted to set a GATKReportTable description of '" + tableDescription + "'. GATKReportTable descriptions must not contain newlines."); + } + + this.tableName = tableName; + this.tableDescription = tableDescription; + this.sortByRowID = sortByRowID; + + underlyingData = new ArrayList(INITITAL_ARRAY_SIZE); + columnInfo = new ArrayList(numColumns); + columnNameToIndex = new HashMap(numColumns); + rowIdToIndex = new HashMap(); + } /** * Verifies that a table or column name has only alphanumeric characters - no spaces or special characters allowed @@ -189,106 +227,50 @@ public class GATKReportTable { } /** - * Construct a new GATK report table with the specified name and description + * Add a mapping from ID to the index of a new row added to the table. * - * @param tableName the name of the table - * @param tableDescription the description of the table + * @param ID the unique ID */ - public GATKReportTable(String tableName, String tableDescription) { - this(tableName, tableDescription, true); + public void addRowID(final String ID) { + addRowID(ID, false); } /** - * Construct a new GATK report table with the specified name and description and whether to sort rows by the primary - * key + * Add a mapping from ID to the index of a new row added to the table. * - * @param tableName the name of the table - * @param tableDescription the description of the table - * @param sortByPrimaryKey whether to sort rows by the primary key (instead of order added) + * @param ID the unique ID + * @param populateFirstColumn should we automatically populate the first column with the row's ID? */ - public GATKReportTable(String tableName, String tableDescription, boolean sortByPrimaryKey) { - 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."); - } - - if (!isValidDescription(tableDescription)) { - throw new ReviewedStingException("Attempted to set a GATKReportTable description of '" + tableDescription + "'. GATKReportTable descriptions must not contain newlines."); - } - - this.tableName = tableName; - this.tableDescription = tableDescription; - this.sortByPrimaryKey = sortByPrimaryKey; - - columns = new GATKReportColumns(); + public void addRowID(final String ID, final boolean populateFirstColumn) { + addRowIDMapping(ID, underlyingData.size(), populateFirstColumn); } /** - * Add a primary key column. This becomes the unique identifier for every column in the table. + * Add a mapping from ID to row index. * - * @param primaryKeyName the name of the primary key column + * @param ID the unique ID + * @param index the index associated with the ID */ - public void addPrimaryKey(String primaryKeyName) { - addPrimaryKey(primaryKeyName, true); + public void addRowIDMapping(final String ID, final int index) { + addRowIDMapping(ID, index, false); } /** - * Add an optionally visible primary key column. This becomes the unique identifier for every column in the table, - * and will always be printed as the first column. + * Add a mapping from ID to row index. * - * @param primaryKeyName the name of the primary key column - * @param display should this primary key be displayed? + * @param ID the unique ID + * @param index the index associated with the ID + * @param populateFirstColumn should we automatically populate the first column with the row's ID? */ - public void addPrimaryKey(String primaryKeyName, boolean display) { - if (!isValidName(primaryKeyName)) { - throw new ReviewedStingException("Attempted to set a GATKReportTable primary key name of '" + primaryKeyName + "'. GATKReportTable primary key names must be purely alphanumeric - no spaces or special characters are allowed."); - } + public void addRowIDMapping(final Object ID, final int index, final boolean populateFirstColumn) { + if ( populateFirstColumn && !isValidName(ID.toString()) ) + throw new ReviewedStingException("Attempted to set a GATKReportTable ID of '" + ID + "'; GATKReportTable IDs must be purely alphanumeric - no spaces or special characters are allowed."); - this.primaryKeyName = primaryKeyName; + expandTo(index, false); + rowIdToIndex.put(ID, index); - primaryKeyColumn = sortByPrimaryKey ? new TreeSet() : new LinkedList(); - primaryKeyDisplay = display; - } - - /** - * Returns the first primary key matching the column values. - * Ex: "CountVariants", "dbsnp", "eval", "called", "all", "novel", "all" - * @param columnValues column values. - * @return The first primary key matching the column values or throws an exception. - */ - public Object getPrimaryKeyByData(Object... columnValues) { - Object key = findPrimaryKeyByData(columnValues); - if (key == null) - throw new ReviewedStingException("Attempted to get non-existent GATKReportTable key for values: " + Arrays.asList(columnValues)); - return key; - } - - /** - * Returns the first primary key matching the column values. - * Ex: "CountVariants", "dbsnp", "eval", "called", "all", "novel", "all" - * - * @param columnValues column values. - * @return The first primary key matching the column values or null if the key does not exist. - */ - public Object findPrimaryKeyByData(Object... columnValues) { - if (columnValues == null) - throw new NullPointerException("Column values is null"); - if (columnValues.length == 0) - throw new IllegalArgumentException("Column values is empty"); - int columnCount = columns.size(); - for (Object primaryKey : primaryKeyColumn) { - boolean matching = true; - // i --> index into columnValues parameter - // j --> index into columns collection - for (int i = 0, j = 0; matching && i < columnValues.length && j < columnCount; j++) { - if (!columns.getByIndex(j).isDisplayable()) - continue; - matching = ObjectUtils.equals(columnValues[i], get(primaryKey, i)); - i++; - } - if (matching) - return primaryKey; - } - return null; + if ( populateFirstColumn ) + set(index, 0, ID); } /** @@ -296,49 +278,9 @@ public class GATKReportTable { * is never explicitly set. * * @param columnName the name of the column - * @param defaultValue the default value for the column */ - public void addColumn(String columnName, Object defaultValue) { - addColumn(columnName, defaultValue, true); - } - - /** - * Add a column to the report, specify the default column value, and specify whether the column should be displayed - * in the final output (useful when intermediate columns are necessary for later calculations, but are not required - * to be in the output file. - * - * @param columnName the name of the column - * @param defaultValue the default value of the column - * @param display if true - the column will be displayed; if false - the column will be hidden - */ - public void addColumn(String columnName, Object defaultValue, boolean display) { - addColumn(columnName, defaultValue, display, ""); - } - - /** - * Add a column to the report, specify the default column value, and specify whether the column should be displayed - * in the final output (useful when intermediate columns are necessary for later calculations, but are not required - * to be in the output file. - * - * @param columnName the name of the column - * @param defaultValue the default value of the column - * @param format the format string used to display data - */ - public void addColumn(String columnName, Object defaultValue, String format) { - addColumn(columnName, defaultValue, true, format); - } - - /** - * Add a column to the report, specify whether the column should be displayed in the final output (useful when - * intermediate columns are necessary for later calculations, but are not required to be in the output file), and the - * format string used to display the data. - * - * @param columnName the name of the column - * @param display if true - the column will be displayed; if false - the column will be hidden - * @param format the format string used to display data - */ - public void addColumn(String columnName, boolean display, String format) { - addColumn(columnName, null, display, format); + public void addColumn(String columnName) { + addColumn(columnName, ""); } /** @@ -347,388 +289,200 @@ public class GATKReportTable { * output file), and the format string used to display the data. * * @param columnName the name of the column - * @param defaultValue if true - the column will be displayed; if false - the column will be hidden - * @param display display the column * @param format the format string used to display data */ - public void addColumn(String columnName, Object defaultValue, boolean display, String format) { + public void addColumn(String columnName, String format) { if (!isValidName(columnName)) { throw new ReviewedStingException("Attempted to set a GATKReportTable column name of '" + columnName + "'. GATKReportTable column names must be purely alphanumeric - no spaces or special characters are allowed."); } - columns.put(columnName, new GATKReportColumn(columnName, defaultValue, display, format)); + columnNameToIndex.put(columnName, columnInfo.size()); + columnInfo.add(new GATKReportColumn(columnName, format)); } /** - * Check if the requested element exists, and if not, create it. + * Check if the requested cell is valid and expand the table if necessary * - * @param primaryKey the primary key value - * @param columnName the name of the column + * @param rowIndex the row index + * @param colIndex the column index */ - private void verifyEntry(Object primaryKey, String columnName) { - if (!columns.containsKey(columnName)) { - throw new ReviewedStingException("Attempted to access column '" + columnName + "' that does not exist in table '" + tableName + "'."); - } - - primaryKeyColumn.add(primaryKey); - - if (!columns.get(columnName).containsKey(primaryKey)) { - columns.get(columnName).initialize(primaryKey); - } - } - - public boolean containsKey(Object primaryKey) { - return primaryKeyColumn.contains(primaryKey); - } - - public Collection getPrimaryKeys() { - return Collections.unmodifiableCollection(primaryKeyColumn); + private void verifyEntry(final int rowIndex, final int colIndex) { + if ( rowIndex < 0 || colIndex < 0 || colIndex >= getNumColumns() ) + throw new ReviewedStingException("attempted to access a cell that does not exist in table '" + tableName + "'"); } /** * Set the value for a given position in the table * - * @param primaryKey the primary key value - * @param columnName the name of the column - * @param value the value to set + * @param rowIndex the row index + * @param updateRowIdMap should we update the row ID map? */ - public void set(Object primaryKey, String columnName, Object value) { - verifyEntry(primaryKey, columnName); - GATKReportColumn column = columns.get(columnName); - //todo -- Check if value is of same type as column + private void expandTo(final int rowIndex, final boolean updateRowIdMap) { + int currentSize = underlyingData.size(); + if ( rowIndex >= currentSize ) { + final int numNewRows = rowIndex - currentSize + 1; + for ( int i = 0; i < numNewRows; i++ ) { + if ( updateRowIdMap ) + rowIdToIndex.put(currentSize, currentSize); + underlyingData.add(new Object[getNumColumns()]); + currentSize++; + } + } + } + + /** + * Set the value for a given position in the table + * + * @param rowID the row ID + * @param columnName the name of the column + * @param value the value to set + */ + public void set(final Object rowID, final String columnName, final Object value) { + if ( !rowIdToIndex.containsKey(rowID) ) { + rowIdToIndex.put(rowID, underlyingData.size()); + expandTo(underlyingData.size(), false); + } + set(rowIdToIndex.get(rowID), columnNameToIndex.get(columnName), value); + } + + public void set(final int rowIndex, final int colIndex, Object value) { + expandTo(rowIndex, true); + verifyEntry(rowIndex, colIndex); + GATKReportColumn column = columnInfo.get(colIndex); // We do not accept internal null values if (value == null) value = "null"; + else + value = fixType(value, column); - // This code below is bs. Why am do I have to conform to bad code + if ( column.getDataType().equals(GATKReportDataType.fromObject(value)) || column.getDataType().equals(GATKReportDataType.Unknown) ) { + underlyingData.get(rowIndex)[colIndex] = value; + column.updateFormatting(value); + } else { + throw new ReviewedStingException(String.format("Tried to add an object of type: %s to a column of type: %s", GATKReportDataType.fromObject(value).name(), column.getDataType().name())); + } + } + + /** + * Returns true if the table contains a row mapping with the given ID + * + * @param rowID the row ID + */ + public boolean containsRowID(final Object rowID) { + return rowIdToIndex.containsKey(rowID); + } + + /** + * Returns the row mapping IDs + * + */ + public Collection getRowIDs() { + return rowIdToIndex.keySet(); + } + + /** + * Set the value for a given position in the table + * + * @param rowID the row ID + * @param columnName the name of the column + */ + public void increment(final Object rowID, final String columnName) { + int prevValue; + if ( !rowIdToIndex.containsKey(rowID) ) { + rowIdToIndex.put(rowID, underlyingData.size()); + underlyingData.add(new Object[getNumColumns()]); + prevValue = 0; + } else { + Object obj = get(rowID, columnName); + if ( !(obj instanceof Integer) ) + throw new ReviewedStingException("Attempting to increment a value in a cell that is not an integer"); + prevValue = (Integer)obj; + } + + set(rowIdToIndex.get(rowID), columnNameToIndex.get(columnName), prevValue + 1); + } + + /** + * Returns the index of the first row matching the column values. + * Ex: "CountVariants", "dbsnp", "eval", "called", "all", "novel", "all" + * + * @param columnValues column values. + * @return The index of the first row matching the column values or -1 if no such row exists. + */ + public int findRowByData(final Object... columnValues) { + if ( columnValues == null || columnValues.length == 0 || columnValues.length > getNumColumns() ) + return -1; + + for ( int rowIndex = 0; rowIndex < underlyingData.size(); rowIndex++ ) { + + final Object[] row = underlyingData.get(rowIndex); + + boolean matches = true; + for ( int colIndex = 0; colIndex < columnValues.length; colIndex++ ) { + if ( !columnValues[colIndex].equals(row[colIndex]) ) { + matches = false; + break; + } + } + + if ( matches ) + return rowIndex; + } + + return -1; + } + + private Object fixType(final Object value, final GATKReportColumn column) { // Below is some code to convert a string into its appropriate type. - - // I second Roger's rant! - // If we got a string but the column is not a String type + // todo -- Types have to be more flexible. For example, %d should accept Integers, Shorts and Bytes. + Object newValue = null; - if (value instanceof String && !column.getDataType().equals(GATKReportDataType.String)) { + if ( value instanceof String && !column.getDataType().equals(GATKReportDataType.String) ) { // Integer case - if (column.getDataType().equals(GATKReportDataType.Integer)) { + if ( column.getDataType().equals(GATKReportDataType.Integer) ) { try { newValue = Long.parseLong((String) value); } catch (Exception e) { /** do nothing */ } } - if (column.getDataType().equals(GATKReportDataType.Decimal)) { + if ( column.getDataType().equals(GATKReportDataType.Decimal) ) { try { newValue = Double.parseDouble((String) value); } catch (Exception e) { /** do nothing */ } } - if (column.getDataType().equals(GATKReportDataType.Character) && ((String) value).length() == 1) { + if ( column.getDataType().equals(GATKReportDataType.Character) && ((String) value).length() == 1 ) { newValue = ((String) value).charAt(0); } } - if (newValue != null) - value = newValue; - - // todo -- Types have to be more flexible. For example, %d should accept Integers, Shorts and Bytes. - if (column.getDataType().equals(GATKReportDataType.fromObject(value)) || column.getDataType().equals(GATKReportDataType.Unknown) ) - columns.get(columnName).put(primaryKey, value); - else - throw new ReviewedStingException(String.format("Tried to add an object of type: %s to a column of type: %s", GATKReportDataType.fromObject(value).name(), column.getDataType().name())); + return (newValue != null) ? newValue : value; } /** * Get a value from the given position in the table * - * @param primaryKey the primary key value - * @param columnName the name of the column + * @param rowID the row ID + * @param columnName the name of the column * @return the value stored at the specified position in the table */ - public Object get(Object primaryKey, String columnName) { - verifyEntry(primaryKey, columnName); - - return columns.get(columnName).get(primaryKey); + public Object get(final Object rowID, final String columnName) { + return get(rowIdToIndex.get(rowID), columnNameToIndex.get(columnName)); } /** * Get a value from the given position in the table * - * @param primaryKey the primary key value + * @param rowIndex the index of the row * @param columnIndex the index of the column * @return the value stored at the specified position in the table */ - private Object get(Object primaryKey, int columnIndex) { - return columns.getByIndex(columnIndex).get(primaryKey); - } - - /** - * Increment an element in the table. This implementation is awful - a functor would probably be better. - * - * @param primaryKey the primary key value - * @param columnName the name of the column - */ - public void increment(Object primaryKey, String columnName) { - Object oldValue = get(primaryKey, columnName); - Object newValue; - - if (oldValue instanceof Byte) { - newValue = ((Byte) oldValue) + 1; - } else if (oldValue instanceof Short) { - newValue = ((Short) oldValue) + 1; - } else if (oldValue instanceof Integer) { - newValue = ((Integer) oldValue) + 1; - } else if (oldValue instanceof Long) { - newValue = ((Long) oldValue) + 1L; - } else if (oldValue instanceof Float) { - newValue = ((Float) oldValue) + 1.0f; - } else if (oldValue instanceof Double) { - newValue = ((Double) oldValue) + 1.0d; - } else { - throw new UnsupportedOperationException("Can't increment value: object " + oldValue + " is not an instance of one of the numerical Java primitive wrapper classes (Byte, Short, Integer, Long, Float, Double)"); - } - - set(primaryKey, columnName, newValue); - } - - /** - * Decrement an element in the table. This implementation is awful - a functor would probably be better. - * - * @param primaryKey the primary key value - * @param columnName the name of the column - */ - public void decrement(Object primaryKey, String columnName) { - Object oldValue = get(primaryKey, columnName); - Object newValue; - - if (oldValue instanceof Byte) { - newValue = ((Byte) oldValue) - 1; - } else if (oldValue instanceof Short) { - newValue = ((Short) oldValue) - 1; - } else if (oldValue instanceof Integer) { - newValue = ((Integer) oldValue) - 1; - } else if (oldValue instanceof Long) { - newValue = ((Long) oldValue) - 1L; - } else if (oldValue instanceof Float) { - newValue = ((Float) oldValue) - 1.0f; - } else if (oldValue instanceof Double) { - newValue = ((Double) oldValue) - 1.0d; - } else { - throw new UnsupportedOperationException("Can't decrement value: object " + oldValue + " is not an instance of one of the numerical Java primitive wrapper classes (Byte, Short, Integer, Long, Float, Double)"); - } - - set(primaryKey, columnName, newValue); - } - - /** - * Add the specified value to an element in the table - * - * @param primaryKey the primary key value - * @param columnName the name of the column - * @param valueToAdd the value to add - */ - public void add(Object primaryKey, String columnName, Object valueToAdd) { - Object oldValue = get(primaryKey, columnName); - Object newValue; - - if (oldValue instanceof Byte) { - newValue = ((Byte) oldValue) + ((Byte) valueToAdd); - } else if (oldValue instanceof Short) { - newValue = ((Short) oldValue) + ((Short) valueToAdd); - } else if (oldValue instanceof Integer) { - newValue = ((Integer) oldValue) + ((Integer) valueToAdd); - } else if (oldValue instanceof Long) { - newValue = ((Long) oldValue) + ((Long) valueToAdd); - } else if (oldValue instanceof Float) { - newValue = ((Float) oldValue) + ((Float) valueToAdd); - } else if (oldValue instanceof Double) { - newValue = ((Double) oldValue) + ((Double) valueToAdd); - } else { - throw new UnsupportedOperationException("Can't add values: object " + oldValue + " is not an instance of one of the numerical Java primitive wrapper classes (Byte, Short, Integer, Long, Float, Double)"); - } - - set(primaryKey, columnName, newValue); - } - - /** - * Subtract the specified value from an element in the table - * - * @param primaryKey the primary key value - * @param columnName the name of the column - * @param valueToSubtract the value to subtract - */ - public void subtract(Object primaryKey, String columnName, Object valueToSubtract) { - Object oldValue = get(primaryKey, columnName); - Object newValue; - - if (oldValue instanceof Byte) { - newValue = ((Byte) oldValue) - ((Byte) valueToSubtract); - } else if (oldValue instanceof Short) { - newValue = ((Short) oldValue) - ((Short) valueToSubtract); - } else if (oldValue instanceof Integer) { - newValue = ((Integer) oldValue) - ((Integer) valueToSubtract); - } else if (oldValue instanceof Long) { - newValue = ((Long) oldValue) - ((Long) valueToSubtract); - } else if (oldValue instanceof Float) { - newValue = ((Float) oldValue) - ((Float) valueToSubtract); - } else if (oldValue instanceof Double) { - newValue = ((Double) oldValue) - ((Double) valueToSubtract); - } else { - throw new UnsupportedOperationException("Can't subtract values: object " + oldValue + " is not an instance of one of the numerical Java primitive wrapper classes (Byte, Short, Integer, Long, Float, Double)"); - } - - set(primaryKey, columnName, newValue); - } - - /** - * Multiply the specified value to an element in the table - * - * @param primaryKey the primary key value - * @param columnName the name of the column - * @param valueToMultiply the value to multiply by - */ - public void multiply(Object primaryKey, String columnName, Object valueToMultiply) { - Object oldValue = get(primaryKey, columnName); - Object newValue; - - if (oldValue instanceof Byte) { - newValue = ((Byte) oldValue) * ((Byte) valueToMultiply); - } else if (oldValue instanceof Short) { - newValue = ((Short) oldValue) * ((Short) valueToMultiply); - } else if (oldValue instanceof Integer) { - newValue = ((Integer) oldValue) * ((Integer) valueToMultiply); - } else if (oldValue instanceof Long) { - newValue = ((Long) oldValue) * ((Long) valueToMultiply); - } else if (oldValue instanceof Float) { - newValue = ((Float) oldValue) * ((Float) valueToMultiply); - } else if (oldValue instanceof Double) { - newValue = ((Double) oldValue) * ((Double) valueToMultiply); - } else { - throw new UnsupportedOperationException("Can't multiply values: object " + oldValue + " is not an instance of one of the numerical Java primitive wrapper classes (Byte, Short, Integer, Long, Float, Double)"); - } - - set(primaryKey, columnName, newValue); - } - - /** - * Divide the specified value from an element in the table - * - * @param primaryKey the primary key value - * @param columnName the name of the column - * @param valueToDivide the value to divide by - */ - public void divide(Object primaryKey, String columnName, Object valueToDivide) { - Object oldValue = get(primaryKey, columnName); - Object newValue; - - if (oldValue instanceof Byte) { - newValue = ((Byte) oldValue) * ((Byte) valueToDivide); - } else if (oldValue instanceof Short) { - newValue = ((Short) oldValue) * ((Short) valueToDivide); - } else if (oldValue instanceof Integer) { - newValue = ((Integer) oldValue) * ((Integer) valueToDivide); - } else if (oldValue instanceof Long) { - newValue = ((Long) oldValue) * ((Long) valueToDivide); - } else if (oldValue instanceof Float) { - newValue = ((Float) oldValue) * ((Float) valueToDivide); - } else if (oldValue instanceof Double) { - newValue = ((Double) oldValue) * ((Double) valueToDivide); - } else { - throw new UnsupportedOperationException("Can't divide values: object " + oldValue + " is not an instance of one of the numerical Java primitive wrapper classes (Byte, Short, Integer, Long, Float, Double)"); - } - - set(primaryKey, columnName, newValue); - } - - /** - * Add two columns to each other and set the results to a third column - * - * @param columnToSet the column that should hold the results - * @param augend the column that shall be the augend - * @param addend the column that shall be the addend - */ - public void addColumns(String columnToSet, String augend, String addend) { - for (Object primaryKey : primaryKeyColumn) { - Number firstColumnValue = (Number) get(primaryKey, augend); - Number secondColumnValue = (Number) get(primaryKey, addend); - - Double value = firstColumnValue.doubleValue() + secondColumnValue.doubleValue(); - - set(primaryKey, columnToSet, value); - } - } - - /** - * Subtract one column from another and set the results to a third column - * - * @param columnToSet the column that should hold the results - * @param minuend the column that shall be the minuend (the a in a - b) - * @param subtrahend the column that shall be the subtrahend (the b in a - b) - */ - public void subtractColumns(String columnToSet, String minuend, String subtrahend) { - for (Object primaryKey : primaryKeyColumn) { - Number firstColumnValue = (Number) get(primaryKey, minuend); - Number secondColumnValue = (Number) get(primaryKey, subtrahend); - - Double value = firstColumnValue.doubleValue() - secondColumnValue.doubleValue(); - - set(primaryKey, columnToSet, value); - } - } - - /** - * Multiply two columns by each other and set the results to a third column - * - * @param columnToSet the column that should hold the results - * @param multiplier the column that shall be the multiplier - * @param multiplicand the column that shall be the multiplicand - */ - public void multiplyColumns(String columnToSet, String multiplier, String multiplicand) { - for (Object primaryKey : primaryKeyColumn) { - Number firstColumnValue = (Number) get(primaryKey, multiplier); - Number secondColumnValue = (Number) get(primaryKey, multiplicand); - - Double value = firstColumnValue.doubleValue() * secondColumnValue.doubleValue(); - - set(primaryKey, columnToSet, value); - } - } - - /** - * Divide two columns by each other and set the results to a third column - * - * @param columnToSet the column that should hold the results - * @param numeratorColumn the column that shall be the numerator - * @param denominatorColumn the column that shall be the denominator - */ - public void divideColumns(String columnToSet, String numeratorColumn, String denominatorColumn) { - for (Object primaryKey : primaryKeyColumn) { - Number firstColumnValue = (Number) get(primaryKey, numeratorColumn); - Number secondColumnValue = (Number) get(primaryKey, denominatorColumn); - - Double value = firstColumnValue.doubleValue() / secondColumnValue.doubleValue(); - - set(primaryKey, columnToSet, value); - } - } - - /** - * Return the print width of the primary key column - * - * @return the width of the primary key column - */ - int getPrimaryKeyColumnWidth() { - int maxWidth = getPrimaryKeyName().length(); - - for (Object primaryKey : primaryKeyColumn) { - int width = primaryKey.toString().length(); - - if (width > maxWidth) { - maxWidth = width; - } - } - - return maxWidth; + public Object get(int rowIndex, int columnIndex) { + verifyEntry(rowIndex, columnIndex); + return underlyingData.get(rowIndex)[columnIndex]; } /** @@ -736,82 +490,91 @@ public class GATKReportTable { * * @param out the PrintStream to which the table should be written */ - void write(PrintStream out) { + void write(final PrintStream out) { - /* - * Table header: - * #:GATKTable:nColumns:nRows:(DataType for each column):; - * #:GATKTable:TableName:Description :; - * key colA colB - * row1 xxxx xxxxx - */ + /* + * Table header: + * #:GATKTable:nColumns:nRows:(DataType for each column):; + * #:GATKTable:TableName:Description :; + * key colA colB + * row1 xxxx xxxxx + */ - // Get the column widths for everything - String primaryKeyFormat = "%-" + getPrimaryKeyColumnWidth() + "s"; + // write the table definition + out.printf(GATKTABLE_HEADER_PREFIX + ":%d:%d", getNumColumns(), getNumRows()); - // Emit the table definition - String formatHeader = String.format(GATKTABLE_HEADER_PREFIX + ":%b:%d:%d", primaryKeyDisplay, getColumns().size(), getNumRows()); - // Add all the formats for all the columns - for (GATKReportColumn column : getColumns()) { - if (column.isDisplayable()) - formatHeader += (SEPARATOR + column.getFormat()); + // write the formats for all the columns + for ( final GATKReportColumn column : columnInfo ) + out.print(SEPARATOR + column.getFormat()); + out.println(ENDLINE); + + // write the table name & description + out.printf(GATKTABLE_HEADER_PREFIX + ":%s:%s\n", tableName, tableDescription); + + // write the column names + boolean needsPadding = false; + for ( final GATKReportColumn column : columnInfo ) { + if ( needsPadding ) + out.printf(" "); + needsPadding = true; + + out.printf(column.getColumnFormat().getNameFormat(), column.getColumnName()); } - out.println(formatHeader + ENDLINE); - out.printf(GATKTABLE_HEADER_PREFIX + ":%s:%s\n", tableName, tableDescription); + out.println(); - //out.printf("#:GATKTable:%s:%s", Algorithm); + // write the table body + if ( sortByRowID ) { + final TreeMap sortedMap; + try { + sortedMap = new TreeMap(rowIdToIndex); + } catch (ClassCastException e) { + throw new ReviewedStingException("Unable to sort the rows based on the row IDs because the ID Objects are of different types"); + } + for ( final Map.Entry rowKey : sortedMap.entrySet() ) + writeRow(out, underlyingData.get(rowKey.getValue())); + } else { + for ( final Object[] row : underlyingData ) + writeRow(out, row); + } + out.println(); + } - // Emit the table header, taking into account the padding requirement if the primary key is a hidden column + private void writeRow(final PrintStream out, final Object[] row) { boolean needsPadding = false; - if (primaryKeyDisplay) { - out.printf(primaryKeyFormat, getPrimaryKeyName()); + for ( int i = 0; i < row.length; i++ ) { + if ( needsPadding ) + out.printf(" "); needsPadding = true; + + final Object obj = row[i]; + final String value; + + final GATKReportColumn info = columnInfo.get(i); + + if ( obj == null ) + value = "null"; + else if ( info.getDataType().equals(GATKReportDataType.Unknown) && (obj instanceof Double || obj instanceof Float) ) + value = String.format("%.8f", obj); + else + value = String.format(info.getFormat(), obj); + + out.printf(info.getColumnFormat().getValueFormat(), value); } - for (String columnName : columns.keySet()) { - if (columns.get(columnName).isDisplayable()) { - if (needsPadding) { - out.printf(" "); - } - out.printf(columns.get(columnName).getColumnFormat().getNameFormat(), columnName); - - needsPadding = true; - } - } - - out.printf("%n"); - - // Emit the table body - for (final Object primaryKey : primaryKeyColumn) { - needsPadding = false; - if (primaryKeyDisplay) { - out.printf(primaryKeyFormat, primaryKey); - needsPadding = true; - } - - for (final Map.Entry entry : columns.entrySet()) { - final GATKReportColumn column = entry.getValue(); - if (column.isDisplayable()) { - if (needsPadding) { - out.print(" "); - } - - final String value = column.getStringValue(primaryKey); - out.printf(column.getColumnFormat().getValueFormat(), value); - - needsPadding = true; - } - } - - out.println(); - } - - out.println(); + out.println(); } public int getNumRows() { - return primaryKeyColumn.size(); + return underlyingData.size(); + } + + public int getNumColumns() { + return columnInfo.size(); + } + + public List getColumnInfo() { + return columnInfo; } public String getTableName() { @@ -822,63 +585,22 @@ public class GATKReportTable { return tableDescription; } - public GATKReportColumns getColumns() { - return columns; - } - /** - * Combines two compatible GATK report tables. This is the general function which will call the different algorithms - * necessary to gather the tables. Every column's combine algorithm is read and treated accordingly. + * Concatenates the rows from the table to this one * - * @param input Another GATK table + * @param table another GATK table */ - void combineWith(GATKReportTable input) { - /* - * This function is different from addRowsFrom because we will add the ability to sum,average, etc rows - * TODO: Add other combining algorithms - */ + public void concat(final GATKReportTable table) { + if ( !isSameFormat(table) ) + throw new ReviewedStingException("Error trying to concatenate tables with different formats"); - // Make sure the columns match AND the Primary Key - if (input.getColumns().keySet().equals(this.getColumns().keySet()) && - input.getPrimaryKeyName().equals(this.getPrimaryKeyName())) { - this.addRowsFrom(input); - } else - throw new ReviewedStingException("Failed to combine GATKReportTable, columns don't match!"); - } + // add the data + underlyingData.addAll(table.underlyingData); - /** - * A gather algorithm that simply takes the rows from the argument, and adds them to the current table. This is the - * default gather algorithm. - * - * @param input Another GATK table to add rows from. - */ - private void addRowsFrom(GATKReportTable input) { - // add column by column - - // For every column - for (String columnKey : input.getColumns().keySet()) { - GATKReportColumn current = this.getColumns().get(columnKey); - GATKReportColumn toAdd = input.getColumns().get(columnKey); - // We want to take the current column and add all the values from input - - // The column is a map of values - for (Object rowKey : toAdd.keySet()) { - // We add every value from toAdd to the current - if (!current.containsKey(rowKey)) { - this.set(rowKey, columnKey, toAdd.get(rowKey)); - //System.out.printf("Putting row with PK: %s \n", rowKey); - } else { - this.set(rowKey, columnKey, toAdd.get(rowKey)); - - System.out.printf("OVERWRITING Row with PK: %s \n", rowKey); - } - } - } - - } - - public String getPrimaryKeyName() { - return primaryKeyName; + // update the row index map + final int currentNumRows = getNumRows(); + for ( Map.Entry entry : table.rowIdToIndex.entrySet() ) + rowIdToIndex.put(entry.getKey(), entry.getValue() + currentNumRows); } /** @@ -889,13 +611,19 @@ public class GATKReportTable { * @param table another GATK table * @return true if the the tables are gatherable */ - public boolean isSameFormat(GATKReportTable table) { - //Should we add the sortByPrimaryKey as a check? + public boolean isSameFormat(final GATKReportTable table) { + if ( !tableName.equals(table.tableName) || + !tableDescription.equals(table.tableDescription) || + columnInfo.size() != table.columnInfo.size() ) + return false; - return columns.isSameFormat(table.columns) && - (primaryKeyDisplay == table.primaryKeyDisplay && primaryKeyName.equals(table.primaryKeyName) && - tableName.equals(table.tableName) && - tableDescription.equals(table.tableDescription)); + for ( int i = 0; i < columnInfo.size(); i++ ) { + if ( !columnInfo.get(i).getFormat().equals(table.columnInfo.get(i).getFormat()) || + !columnInfo.get(i).getColumnName().equals(table.columnInfo.get(i).getColumnName()) ) + return false; + } + + return true; } /** @@ -904,11 +632,41 @@ public class GATKReportTable { * @param table another GATK report * @return true if all field in the reports, tables, and columns are equal. */ - public boolean equals(GATKReportTable table) { - return isSameFormat(table) && - (columns.equals(table.columns) && - primaryKeyColumn.equals(table.primaryKeyColumn) && - sortByPrimaryKey == table.sortByPrimaryKey); + public boolean equals(final GATKReportTable table) { + if ( !isSameFormat(table) || + underlyingData.size() != table.underlyingData.size() ) + return false; + final List myOrderedRows = getOrderedRows(); + final List otherOrderedRows = table.getOrderedRows(); + + for ( int i = 0; i < underlyingData.size(); i++ ) { + final Object[] myData = myOrderedRows.get(i); + final Object[] otherData = otherOrderedRows.get(i); + for ( int j = 0; j < myData.length; j++ ) { + if ( !myData[j].toString().equals(otherData[j].toString()) ) // need to deal with different typing (e.g. Long vs. Integer) + return false; + } + } + + return true; + } + + private List getOrderedRows() { + if ( !sortByRowID ) + return underlyingData; + + final TreeMap sortedMap; + try { + sortedMap = new TreeMap(rowIdToIndex); + } catch (ClassCastException e) { + return underlyingData; + } + + final List orderedData = new ArrayList(underlyingData.size()); + for ( final int rowKey : sortedMap.values() ) + orderedData.add(underlyingData.get(rowKey)); + + return orderedData; } } diff --git a/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportTableV2.java b/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportTableV2.java deleted file mode 100755 index d00a45765..000000000 --- a/public/java/src/org/broadinstitute/sting/gatk/report/GATKReportTableV2.java +++ /dev/null @@ -1,672 +0,0 @@ -/* - * 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.gatk.report; - -import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; -import org.broadinstitute.sting.utils.text.TextFormattingUtils; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.PrintStream; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class GATKReportTableV2 { - /** - * REGEX that matches any table with an invalid name - */ - public static final String INVALID_TABLE_NAME_REGEX = "[^a-zA-Z0-9_\\-\\.]"; - private static final String GATKTABLE_HEADER_PREFIX = "#:GATKTable"; - private static final String SEPARATOR = ":"; - private static final String ENDLINE = ":;"; - - private final String tableName; - private final String tableDescription; - - private final boolean sortByRowID; - - private List underlyingData; - private final List columnInfo; - private final Map columnNameToIndex; - private final HashMap rowIdToIndex; - - private static final String COULD_NOT_READ_HEADER = "Could not read the header of this file -- "; - private static final String COULD_NOT_READ_COLUMN_NAMES = "Could not read the column names of this file -- "; - private static final String COULD_NOT_READ_DATA_LINE = "Could not read a data line of this table -- "; - private static final String COULD_NOT_READ_EMPTY_LINE = "Could not read the last empty line of this table -- "; - private static final String OLD_GATK_TABLE_VERSION = "We no longer support older versions of the GATK Tables"; - - private static final int INITITAL_ARRAY_SIZE = 10000; - private static final String NUMBER_CONVERSION_EXCEPTION = "String is a number but is not a long or a double: "; - - protected enum TableDataHeaderFields { - COLS(2), - ROWS(3), - FORMAT_START(4); - - private final int index; - TableDataHeaderFields(int index) { this.index = index; } - public int index() { return index; } - } - - protected enum TableNameHeaderFields { - NAME(2), - DESCRIPTION(3); - - private final int index; - TableNameHeaderFields(int index) { this.index = index; } - public int index() { return index; } - } - - public GATKReportTableV2(BufferedReader reader, GATKReportVersion version) { - - switch ( version ) { - case V1_1: - // read in the header lines - final String[] tableData, tableNameData; - try { - tableData = reader.readLine().split(SEPARATOR); - tableNameData = reader.readLine().split(SEPARATOR); - } catch (IOException e) { - throw new ReviewedStingException(COULD_NOT_READ_HEADER + e.getMessage()); - } - - // parse the header fields - tableName = tableNameData[TableNameHeaderFields.NAME.index()]; - 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 - sortByRowID = false; - - // initialize the data - final int nColumns = Integer.parseInt(tableData[TableDataHeaderFields.COLS.index()]); - final int nRows = Integer.parseInt(tableData[TableDataHeaderFields.ROWS.index()]); - underlyingData = new ArrayList(nRows); - columnInfo = new ArrayList(nColumns); - columnNameToIndex = new HashMap(nColumns); - - // when reading from a file, the row ID mapping is just the index - rowIdToIndex = new HashMap(); - for ( int i = 0; i < nRows; i++ ) - rowIdToIndex.put(i, i); - - // read the column names - final String columnLine; - try { - columnLine = reader.readLine(); - } catch (IOException e) { - throw new ReviewedStingException(COULD_NOT_READ_COLUMN_NAMES); - } - - final List columnStarts = TextFormattingUtils.getWordStarts(columnLine); - final String[] columnNames = TextFormattingUtils.splitFixedWidth(columnLine, columnStarts); - - // Put in columns using the format string from the header - for ( int i = 0; i < nColumns; i++ ) { - final String format = tableData[TableDataHeaderFields.FORMAT_START.index() + i]; - addColumn(columnNames[i], format); - } - - // fill in the table - try { - for ( int i = 0; i < nRows; i++ ) { - // read a data line - final String dataLine = reader.readLine(); - final List lineSplits = Arrays.asList(TextFormattingUtils.splitFixedWidth(dataLine, columnStarts)); - - underlyingData.add(new Object[nColumns]); - for ( int columnIndex = 0; columnIndex < nColumns; columnIndex++ ) { - - final GATKReportDataType type = columnInfo.get(columnIndex).getDataType(); - final String columnName = columnNames[columnIndex]; - set(i, columnName, type.Parse(lineSplits.get(columnIndex))); - - } - } - } catch (IOException e) { - throw new ReviewedStingException(COULD_NOT_READ_DATA_LINE + e.getMessage()); - } - - try { - reader.readLine(); - } catch (IOException e) { - throw new ReviewedStingException(COULD_NOT_READ_EMPTY_LINE + e.getMessage()); - } - break; - - default: - throw new ReviewedStingException(OLD_GATK_TABLE_VERSION); - } - } - - /** - * Construct a new GATK report table with the specified name and description - * - * @param tableName the name of the table - * @param tableDescription the description of the table - * @param numColumns the number of columns in this table - */ - public GATKReportTableV2(final String tableName, final String tableDescription, final int numColumns) { - this(tableName, tableDescription, numColumns, true); - } - - /** - * Construct a new GATK report table with the specified name and description and whether to sort rows by the row ID. - * - * @param tableName the name of the table - * @param tableDescription the description of the 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) - */ - public GATKReportTableV2(final String tableName, final String tableDescription, final int numColumns, final boolean sortByRowID) { - 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."); - } - - if ( !isValidDescription(tableDescription) ) { - throw new ReviewedStingException("Attempted to set a GATKReportTable description of '" + tableDescription + "'. GATKReportTable descriptions must not contain newlines."); - } - - this.tableName = tableName; - this.tableDescription = tableDescription; - this.sortByRowID = sortByRowID; - - underlyingData = new ArrayList(INITITAL_ARRAY_SIZE); - columnInfo = new ArrayList(numColumns); - columnNameToIndex = new HashMap(numColumns); - rowIdToIndex = new HashMap(); - } - - /** - * Verifies that a table or column name has only alphanumeric characters - no spaces or special characters allowed - * - * @param name the name of the table or column - * @return true if the name is valid, false if otherwise - */ - private boolean isValidName(String name) { - Pattern p = Pattern.compile(INVALID_TABLE_NAME_REGEX); - Matcher m = p.matcher(name); - - return !m.find(); - } - - /** - * Verifies that a table or column name has only alphanumeric characters - no spaces or special characters allowed - * - * @param description the name of the table or column - * @return true if the name is valid, false if otherwise - */ - private boolean isValidDescription(String description) { - Pattern p = Pattern.compile("\\r|\\n"); - Matcher m = p.matcher(description); - - return !m.find(); - } - - /** - * Add a mapping from ID to the index of a new row added to the table. - * - * @param ID the unique ID - */ - public void addRowID(final String ID) { - addRowID(ID, false); - } - - /** - * Add a mapping from ID to the index of a new row added to the table. - * - * @param ID the unique ID - * @param populateFirstColumn should we automatically populate the first column with the row's ID? - */ - public void addRowID(final String ID, final boolean populateFirstColumn) { - addRowIDMapping(ID, underlyingData.size(), populateFirstColumn); - } - - /** - * Add a mapping from ID to row index. - * - * @param ID the unique ID - * @param index the index associated with the ID - */ - public void addRowIDMapping(final String ID, final int index) { - addRowIDMapping(ID, index, false); - } - - /** - * Add a mapping from ID to row index. - * - * @param ID the unique ID - * @param index the index associated with the ID - * @param populateFirstColumn should we automatically populate the first column with the row's ID? - */ - public void addRowIDMapping(final Object ID, final int index, final boolean populateFirstColumn) { - if ( populateFirstColumn && !isValidName(ID.toString()) ) - throw new ReviewedStingException("Attempted to set a GATKReportTable ID of '" + ID + "'; GATKReportTable IDs must be purely alphanumeric - no spaces or special characters are allowed."); - - expandTo(index, false); - rowIdToIndex.put(ID, index); - - if ( populateFirstColumn ) - set(index, 0, ID); - } - - /** - * Add a column to the report and specify the default value that should be supplied if a given position in the table - * is never explicitly set. - * - * @param columnName the name of the column - */ - public void addColumn(String columnName) { - addColumn(columnName, ""); - } - - /** - * Add a column to the report, specify the default column value, whether the column should be displayed in the final - * output (useful when intermediate columns are necessary for later calculations, but are not required to be in the - * output file), and the format string used to display the data. - * - * @param columnName the name of the column - * @param format the format string used to display data - */ - public void addColumn(String columnName, String format) { - if (!isValidName(columnName)) { - throw new ReviewedStingException("Attempted to set a GATKReportTable column name of '" + columnName + "'. GATKReportTable column names must be purely alphanumeric - no spaces or special characters are allowed."); - } - columnNameToIndex.put(columnName, columnInfo.size()); - columnInfo.add(new GATKReportColumnV2(columnName, format)); - } - - /** - * Check if the requested cell is valid and expand the table if necessary - * - * @param rowIndex the row index - * @param colIndex the column index - */ - private void verifyEntry(final int rowIndex, final int colIndex) { - if ( rowIndex < 0 || colIndex < 0 || colIndex >= getNumColumns() ) - throw new ReviewedStingException("attempted to access a cell that does not exist in table '" + tableName + "'"); - } - - /** - * Set the value for a given position in the table - * - * @param rowIndex the row index - * @param updateRowIdMap should we update the row ID map? - */ - private void expandTo(final int rowIndex, final boolean updateRowIdMap) { - int currentSize = underlyingData.size(); - if ( rowIndex >= currentSize ) { - final int numNewRows = rowIndex - currentSize + 1; - for ( int i = 0; i < numNewRows; i++ ) { - if ( updateRowIdMap ) - rowIdToIndex.put(currentSize, currentSize); - underlyingData.add(new Object[getNumColumns()]); - currentSize++; - } - } - } - - /** - * Set the value for a given position in the table - * - * @param rowID the row ID - * @param columnName the name of the column - * @param value the value to set - */ - public void set(final Object rowID, final String columnName, final Object value) { - if ( !rowIdToIndex.containsKey(rowID) ) { - rowIdToIndex.put(rowID, underlyingData.size()); - expandTo(underlyingData.size(), false); - } - set(rowIdToIndex.get(rowID), columnNameToIndex.get(columnName), value); - } - - public void set(final int rowIndex, final int colIndex, Object value) { - expandTo(rowIndex, true); - verifyEntry(rowIndex, colIndex); - GATKReportColumnV2 column = columnInfo.get(colIndex); - - // We do not accept internal null values - if (value == null) - value = "null"; - else - value = fixType(value, column); - - if ( column.getDataType().equals(GATKReportDataType.fromObject(value)) || column.getDataType().equals(GATKReportDataType.Unknown) ) { - underlyingData.get(rowIndex)[colIndex] = value; - column.updateFormatting(value); - } else { - throw new ReviewedStingException(String.format("Tried to add an object of type: %s to a column of type: %s", GATKReportDataType.fromObject(value).name(), column.getDataType().name())); - } - } - - /** - * Returns true if the table contains a row mapping with the given ID - * - * @param rowID the row ID - */ - public boolean containsRowID(final Object rowID) { - return rowIdToIndex.containsKey(rowID); - } - - /** - * Returns the row mapping IDs - * - */ - public Collection getRowIDs() { - return rowIdToIndex.keySet(); - } - - /** - * Set the value for a given position in the table - * - * @param rowID the row ID - * @param columnName the name of the column - */ - public void increment(final Object rowID, final String columnName) { - int prevValue; - if ( !rowIdToIndex.containsKey(rowID) ) { - rowIdToIndex.put(rowID, underlyingData.size()); - underlyingData.add(new Object[getNumColumns()]); - prevValue = 0; - } else { - Object obj = get(rowID, columnName); - if ( !(obj instanceof Integer) ) - throw new ReviewedStingException("Attempting to increment a value in a cell that is not an integer"); - prevValue = (Integer)obj; - } - - set(rowIdToIndex.get(rowID), columnNameToIndex.get(columnName), prevValue + 1); - } - - /** - * Returns the index of the first row matching the column values. - * Ex: "CountVariants", "dbsnp", "eval", "called", "all", "novel", "all" - * - * @param columnValues column values. - * @return The index of the first row matching the column values or -1 if no such row exists. - */ - public int findRowByData(final Object... columnValues) { - if ( columnValues == null || columnValues.length == 0 || columnValues.length > getNumColumns() ) - return -1; - - for ( int rowIndex = 0; rowIndex < underlyingData.size(); rowIndex++ ) { - - final Object[] row = underlyingData.get(rowIndex); - - boolean matches = true; - for ( int colIndex = 0; colIndex < columnValues.length; colIndex++ ) { - if ( !columnValues[colIndex].equals(row[colIndex]) ) { - matches = false; - break; - } - } - - if ( matches ) - return rowIndex; - } - - return -1; - } - - private Object fixType(final Object value, final GATKReportColumnV2 column) { - // Below is some code to convert a string into its appropriate type. - - // todo -- Types have to be more flexible. For example, %d should accept Integers, Shorts and Bytes. - - Object newValue = null; - if ( value instanceof String && !column.getDataType().equals(GATKReportDataType.String) ) { - // Integer case - if ( column.getDataType().equals(GATKReportDataType.Integer) ) { - try { - newValue = Long.parseLong((String) value); - } catch (Exception e) { - /** do nothing */ - } - } - if ( column.getDataType().equals(GATKReportDataType.Decimal) ) { - try { - newValue = Double.parseDouble((String) value); - } catch (Exception e) { - /** do nothing */ - } - } - if ( column.getDataType().equals(GATKReportDataType.Character) && ((String) value).length() == 1 ) { - newValue = ((String) value).charAt(0); - } - } - - return (newValue != null) ? newValue : value; - } - - /** - * Get a value from the given position in the table - * - * @param rowID the row ID - * @param columnName the name of the column - * @return the value stored at the specified position in the table - */ - public Object get(final Object rowID, final String columnName) { - return get(rowIdToIndex.get(rowID), columnNameToIndex.get(columnName)); - } - - /** - * Get a value from the given position in the table - * - * @param rowIndex the index of the row - * @param columnIndex the index of the column - * @return the value stored at the specified position in the table - */ - public Object get(int rowIndex, int columnIndex) { - verifyEntry(rowIndex, columnIndex); - return underlyingData.get(rowIndex)[columnIndex]; - } - - /** - * Write the table to the PrintStream, formatted nicely to be human-readable, AWK-able, and R-friendly. - * - * @param out the PrintStream to which the table should be written - */ - void write(final PrintStream out) { - - /* - * Table header: - * #:GATKTable:nColumns:nRows:(DataType for each column):; - * #:GATKTable:TableName:Description :; - * key colA colB - * row1 xxxx xxxxx - */ - - // write the table definition - out.printf(GATKTABLE_HEADER_PREFIX + ":%d:%d", getNumColumns(), getNumRows()); - - // write the formats for all the columns - for ( final GATKReportColumnV2 column : columnInfo ) - out.print(SEPARATOR + column.getFormat()); - out.println(ENDLINE); - - // write the table name & description - out.printf(GATKTABLE_HEADER_PREFIX + ":%s:%s\n", tableName, tableDescription); - - // write the column names - boolean needsPadding = false; - for ( final GATKReportColumnV2 column : columnInfo ) { - if ( needsPadding ) - out.printf(" "); - needsPadding = true; - - out.printf(column.getColumnFormat().getNameFormat(), column.getColumnName()); - } - out.println(); - - // write the table body - if ( sortByRowID ) { - final TreeMap sortedMap; - try { - sortedMap = new TreeMap(rowIdToIndex); - } catch (ClassCastException e) { - throw new ReviewedStingException("Unable to sort the rows based on the row IDs because the ID Objects are of different types"); - } - for ( final Map.Entry rowKey : sortedMap.entrySet() ) - writeRow(out, underlyingData.get(rowKey.getValue())); - } else { - for ( final Object[] row : underlyingData ) - writeRow(out, row); - } - - out.println(); - } - - private void writeRow(final PrintStream out, final Object[] row) { - boolean needsPadding = false; - for ( int i = 0; i < row.length; i++ ) { - if ( needsPadding ) - out.printf(" "); - needsPadding = true; - - final Object obj = row[i]; - final String value; - - final GATKReportColumnV2 info = columnInfo.get(i); - - if ( obj == null ) - value = "null"; - else if ( info.getDataType().equals(GATKReportDataType.Unknown) && (obj instanceof Double || obj instanceof Float) ) - value = String.format("%.8f", obj); - else - value = String.format(info.getFormat(), obj); - - out.printf(info.getColumnFormat().getValueFormat(), value); - } - - out.println(); - } - - public int getNumRows() { - return underlyingData.size(); - } - - public int getNumColumns() { - return columnInfo.size(); - } - - public List getColumnInfo() { - return columnInfo; - } - - public String getTableName() { - return tableName; - } - - public String getTableDescription() { - return tableDescription; - } - - /** - * Concatenates the rows from the table to this one - * - * @param table another GATK table - */ - public void concat(final GATKReportTableV2 table) { - if ( !isSameFormat(table) ) - throw new ReviewedStingException("Error trying to concatenate tables with different formats"); - - // add the data - underlyingData.addAll(table.underlyingData); - - // update the row index map - final int currentNumRows = getNumRows(); - for ( Map.Entry entry : table.rowIdToIndex.entrySet() ) - rowIdToIndex.put(entry.getKey(), entry.getValue() + currentNumRows); - } - - /** - * Returns whether or not the two tables have the same format including columns and everything in between. This does - * not check if the data inside is the same. This is the check to see if the two tables are gatherable or - * reduceable - * - * @param table another GATK table - * @return true if the the tables are gatherable - */ - public boolean isSameFormat(final GATKReportTableV2 table) { - if ( !tableName.equals(table.tableName) || - !tableDescription.equals(table.tableDescription) || - columnInfo.size() != table.columnInfo.size() ) - return false; - - for ( int i = 0; i < columnInfo.size(); i++ ) { - if ( !columnInfo.get(i).getFormat().equals(table.columnInfo.get(i).getFormat()) || - !columnInfo.get(i).getColumnName().equals(table.columnInfo.get(i).getColumnName()) ) - return false; - } - - return true; - } - - /** - * Checks that the tables are exactly the same. - * - * @param table another GATK report - * @return true if all field in the reports, tables, and columns are equal. - */ - public boolean equals(final GATKReportTableV2 table) { - if ( !isSameFormat(table) || - underlyingData.size() != table.underlyingData.size() ) - return false; - - final List myOrderedRows = getOrderedRows(); - final List otherOrderedRows = table.getOrderedRows(); - - for ( int i = 0; i < underlyingData.size(); i++ ) { - final Object[] myData = myOrderedRows.get(i); - final Object[] otherData = otherOrderedRows.get(i); - for ( int j = 0; j < myData.length; j++ ) { - if ( !myData[j].toString().equals(otherData[j].toString()) ) // need to deal with different typing (e.g. Long vs. Integer) - return false; - } - } - - return true; - } - - private List getOrderedRows() { - if ( !sortByRowID ) - return underlyingData; - - final TreeMap sortedMap; - try { - sortedMap = new TreeMap(rowIdToIndex); - } catch (ClassCastException e) { - return underlyingData; - } - - final List orderedData = new ArrayList(underlyingData.size()); - for ( final int rowKey : sortedMap.values() ) - orderedData.add(underlyingData.get(rowKey)); - - return orderedData; - } -} diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/QuantizationInfo.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/QuantizationInfo.java index 50a5a3a30..c631a63ce 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/QuantizationInfo.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/QuantizationInfo.java @@ -1,6 +1,6 @@ package org.broadinstitute.sting.gatk.walkers.bqsr; -import org.broadinstitute.sting.gatk.report.GATKReportTableV2; +import org.broadinstitute.sting.gatk.report.GATKReportTable; import org.broadinstitute.sting.utils.QualityUtils; import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; import org.broadinstitute.sting.utils.recalibration.QualQuantizer; @@ -77,8 +77,8 @@ public class QuantizationInfo { return quantizationLevels; } - public GATKReportTableV2 generateReportTable() { - GATKReportTableV2 quantizedTable = new GATKReportTableV2(RecalDataManager.QUANTIZED_REPORT_TABLE_TITLE, "Quality quantization map", 3); + public GATKReportTable generateReportTable() { + GATKReportTable quantizedTable = new GATKReportTable(RecalDataManager.QUANTIZED_REPORT_TABLE_TITLE, "Quality quantization map", 3); quantizedTable.addColumn(RecalDataManager.QUALITY_SCORE_COLUMN_NAME); quantizedTable.addColumn(RecalDataManager.QUANTIZED_COUNT_COLUMN_NAME); quantizedTable.addColumn(RecalDataManager.QUANTIZED_VALUE_COLUMN_NAME); diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/RecalDataManager.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/RecalDataManager.java index d0d4cb96f..d916abaae 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/RecalDataManager.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/RecalDataManager.java @@ -27,7 +27,7 @@ package org.broadinstitute.sting.gatk.walkers.bqsr; import org.apache.log4j.Logger; import org.broadinstitute.sting.gatk.report.GATKReport; -import org.broadinstitute.sting.gatk.report.GATKReportTableV2; +import org.broadinstitute.sting.gatk.report.GATKReportTable; import org.broadinstitute.sting.utils.BaseUtils; import org.broadinstitute.sting.utils.R.RScriptExecutor; import org.broadinstitute.sting.utils.Utils; @@ -223,8 +223,8 @@ public class RecalDataManager { logger.info(""); } - private static List generateReportTables(Map> keysAndTablesMap) { - List result = new LinkedList(); + private static List generateReportTables(Map> keysAndTablesMap) { + List result = new LinkedList(); int tableIndex = 0; final Pair covariateValue = new Pair(RecalDataManager.COVARIATE_VALUE_COLUMN_NAME, "%s"); @@ -263,7 +263,7 @@ public class RecalDataManager { columnNames.add(nObservations); columnNames.add(nErrors); - GATKReportTableV2 reportTable = new GATKReportTableV2("RecalTable" + tableIndex++, "", columnNames.size()); + GATKReportTable reportTable = new GATKReportTable("RecalTable" + tableIndex++, "", columnNames.size()); for (Pair columnName : columnNames) reportTable.addColumn(columnName.getFirst(), columnName.getSecond()); // every table must have the event type @@ -300,11 +300,11 @@ public class RecalDataManager { outputRecalibrationReport(RAC.generateReportTable(), quantizationInfo.generateReportTable(), generateReportTables(keysAndTablesMap), outputFile); } - public static void outputRecalibrationReport(GATKReportTableV2 argumentTable, QuantizationInfo quantizationInfo, LinkedHashMap> keysAndTablesMap, PrintStream outputFile) { + public static void outputRecalibrationReport(GATKReportTable argumentTable, QuantizationInfo quantizationInfo, LinkedHashMap> keysAndTablesMap, PrintStream outputFile) { outputRecalibrationReport(argumentTable, quantizationInfo.generateReportTable(), generateReportTables(keysAndTablesMap), outputFile); } - private static void outputRecalibrationReport(GATKReportTableV2 argumentTable, GATKReportTableV2 quantizationTable, List recalTables, PrintStream outputFile) { + private static void outputRecalibrationReport(GATKReportTable argumentTable, GATKReportTable quantizationTable, List recalTables, PrintStream outputFile) { GATKReport report = new GATKReport(); report.addTable(argumentTable); report.addTable(quantizationTable); diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/RecalibrationArgumentCollection.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/RecalibrationArgumentCollection.java index 863796a67..340620c2f 100755 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/RecalibrationArgumentCollection.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/RecalibrationArgumentCollection.java @@ -27,7 +27,7 @@ package org.broadinstitute.sting.gatk.walkers.bqsr; import org.broad.tribble.Feature; import org.broadinstitute.sting.commandline.*; -import org.broadinstitute.sting.gatk.report.GATKReportTableV2; +import org.broadinstitute.sting.gatk.report.GATKReportTable; import org.broadinstitute.sting.utils.Utils; import java.io.File; @@ -172,8 +172,8 @@ public class RecalibrationArgumentCollection { public File recalibrationReport = null; - public GATKReportTableV2 generateReportTable() { - GATKReportTableV2 argumentsTable = new GATKReportTableV2("Arguments", "Recalibration argument collection values used in this run", 2); + public GATKReportTable generateReportTable() { + GATKReportTable argumentsTable = new GATKReportTable("Arguments", "Recalibration argument collection values used in this run", 2); argumentsTable.addColumn("Argument"); argumentsTable.addColumn(RecalDataManager.ARGUMENT_VALUE_COLUMN_NAME); argumentsTable.addRowID("covariate", true); diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/RecalibrationReport.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/RecalibrationReport.java index a1945b5f6..43eb2ba34 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/RecalibrationReport.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/bqsr/RecalibrationReport.java @@ -1,7 +1,7 @@ package org.broadinstitute.sting.gatk.walkers.bqsr; import org.broadinstitute.sting.gatk.report.GATKReport; -import org.broadinstitute.sting.gatk.report.GATKReportTableV2; +import org.broadinstitute.sting.gatk.report.GATKReportTable; import org.broadinstitute.sting.utils.QualityUtils; import org.broadinstitute.sting.utils.collections.Pair; import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; @@ -21,7 +21,7 @@ public class RecalibrationReport { private final LinkedHashMap> keysAndTablesMap; // quick access reference to the read group table and its key manager private final ArrayList requestedCovariates = new ArrayList(); // list of all covariates to be used in this calculation - private final GATKReportTableV2 argumentTable; // keep the argument table untouched just for output purposes + private final GATKReportTable argumentTable; // keep the argument table untouched just for output purposes private final RecalibrationArgumentCollection RAC; // necessary for quantizing qualities with the same parameter public RecalibrationReport(final File RECAL_FILE) { @@ -30,7 +30,7 @@ public class RecalibrationReport { argumentTable = report.getTable(RecalDataManager.ARGUMENT_REPORT_TABLE_TITLE); RAC = initializeArgumentCollectionTable(argumentTable); - GATKReportTableV2 quantizedTable = report.getTable(RecalDataManager.QUANTIZED_REPORT_TABLE_TITLE); + GATKReportTable quantizedTable = report.getTable(RecalDataManager.QUANTIZED_REPORT_TABLE_TITLE); quantizationInfo = initializeQuantizationTable(quantizedTable); Pair, ArrayList> covariates = RecalDataManager.initializeCovariates(RAC); // initialize the required and optional covariates @@ -53,11 +53,11 @@ public class RecalibrationReport { int nRequiredCovariates = requiredCovariatesToAdd.size(); // the number of required covariates defines which table we are looking at (RG, QUAL or ALL_COVARIATES) final String UNRECOGNIZED_REPORT_TABLE_EXCEPTION = "Unrecognized table. Did you add an extra required covariate? This is a hard check."; if (nRequiredCovariates == 1) { // if there is only one required covariate, this is the read group table - final GATKReportTableV2 reportTable = report.getTable(RecalDataManager.READGROUP_REPORT_TABLE_TITLE); + final GATKReportTable reportTable = report.getTable(RecalDataManager.READGROUP_REPORT_TABLE_TITLE); table = parseReadGroupTable(keyManager, reportTable); } else if (nRequiredCovariates == 2 && optionalCovariatesToAdd.isEmpty()) { // when we have both required covariates and no optional covariates we're at the QUAL table - final GATKReportTableV2 reportTable = report.getTable(RecalDataManager.QUALITY_SCORE_REPORT_TABLE_TITLE); + final GATKReportTable reportTable = report.getTable(RecalDataManager.QUALITY_SCORE_REPORT_TABLE_TITLE); table = parseQualityScoreTable(keyManager, reportTable); } else @@ -68,12 +68,12 @@ public class RecalibrationReport { final BQSRKeyManager keyManager = new BQSRKeyManager(requiredCovariates, optionalCovariates); // initializing it's corresponding key manager - final GATKReportTableV2 reportTable = report.getTable(RecalDataManager.ALL_COVARIATES_REPORT_TABLE_TITLE); + final GATKReportTable reportTable = report.getTable(RecalDataManager.ALL_COVARIATES_REPORT_TABLE_TITLE); final Map table = parseAllCovariatesTable(keyManager, reportTable); keysAndTablesMap.put(keyManager, table); } - protected RecalibrationReport(QuantizationInfo quantizationInfo, LinkedHashMap> keysAndTablesMap, GATKReportTableV2 argumentTable, RecalibrationArgumentCollection RAC) { + protected RecalibrationReport(QuantizationInfo quantizationInfo, LinkedHashMap> keysAndTablesMap, GATKReportTable argumentTable, RecalibrationArgumentCollection RAC) { this.quantizationInfo = quantizationInfo; this.keysAndTablesMap = keysAndTablesMap; this.argumentTable = argumentTable; @@ -138,7 +138,7 @@ public class RecalibrationReport { * @param reportTable the GATKReport table containing data for this table * @return a lookup table indexed by bitsets containing the empirical quality and estimated quality reported for every key. */ - private Map parseAllCovariatesTable(BQSRKeyManager keyManager, GATKReportTableV2 reportTable) { + private Map parseAllCovariatesTable(BQSRKeyManager keyManager, GATKReportTable reportTable) { ArrayList columnNamesOrderedList = new ArrayList(5); columnNamesOrderedList.add(RecalDataManager.READGROUP_COLUMN_NAME); columnNamesOrderedList.add(RecalDataManager.QUALITY_SCORE_COLUMN_NAME); @@ -155,7 +155,7 @@ public class RecalibrationReport { * @param reportTable the GATKReport table containing data for this table * @return a lookup table indexed by bitsets containing the empirical quality and estimated quality reported for every key. */ - private Map parseQualityScoreTable(BQSRKeyManager keyManager, GATKReportTableV2 reportTable) { + private Map parseQualityScoreTable(BQSRKeyManager keyManager, GATKReportTable reportTable) { ArrayList columnNamesOrderedList = new ArrayList(3); columnNamesOrderedList.add(RecalDataManager.READGROUP_COLUMN_NAME); columnNamesOrderedList.add(RecalDataManager.QUALITY_SCORE_COLUMN_NAME); @@ -170,7 +170,7 @@ public class RecalibrationReport { * @param reportTable the GATKReport table containing data for this table * @return a lookup table indexed by bitsets containing the empirical quality and estimated quality reported for every key. */ - private Map parseReadGroupTable(BQSRKeyManager keyManager, GATKReportTableV2 reportTable) { + private Map parseReadGroupTable(BQSRKeyManager keyManager, GATKReportTable reportTable) { ArrayList columnNamesOrderedList = new ArrayList(2); columnNamesOrderedList.add(RecalDataManager.READGROUP_COLUMN_NAME); columnNamesOrderedList.add(RecalDataManager.EVENT_TYPE_COLUMN_NAME); @@ -185,7 +185,7 @@ public class RecalibrationReport { * @param columnNamesOrderedList a list of columns to read from the report table and build as key for this particular table * @return a lookup table indexed by bitsets containing the empirical quality and estimated quality reported for every key. */ - private Map genericRecalTableParsing(BQSRKeyManager keyManager, GATKReportTableV2 reportTable, ArrayList columnNamesOrderedList, boolean hasEstimatedQReportedColumn) { + private Map genericRecalTableParsing(BQSRKeyManager keyManager, GATKReportTable reportTable, ArrayList columnNamesOrderedList, boolean hasEstimatedQReportedColumn) { Map result = new HashMap(reportTable.getNumRows()*2); for ( int i = 0; i < reportTable.getNumRows(); i++ ) { @@ -216,7 +216,7 @@ public class RecalibrationReport { * @param table the GATKReportTable containing the quantization mappings * @return an ArrayList with the quantization mappings from 0 to MAX_QUAL_SCORE */ - private QuantizationInfo initializeQuantizationTable(GATKReportTableV2 table) { + private QuantizationInfo initializeQuantizationTable(GATKReportTable table) { Byte[] quals = new Byte[QualityUtils.MAX_QUAL_SCORE + 1]; Long[] counts = new Long[QualityUtils.MAX_QUAL_SCORE + 1]; for ( int i = 0; i < table.getNumRows(); i++ ) { @@ -237,7 +237,7 @@ public class RecalibrationReport { * @param table the GATKReportTable containing the arguments and its corresponding values * @return a RAC object properly initialized with all the objects in the table */ - private RecalibrationArgumentCollection initializeArgumentCollectionTable(GATKReportTableV2 table) { + private RecalibrationArgumentCollection initializeArgumentCollectionTable(GATKReportTable table) { RecalibrationArgumentCollection RAC = new RecalibrationArgumentCollection(); for ( int i = 0; i < table.getNumRows(); i++ ) { diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/diagnostics/ErrorRatePerCycle.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/diagnostics/ErrorRatePerCycle.java index 709b26808..a48570fc6 100755 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/diagnostics/ErrorRatePerCycle.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/diagnostics/ErrorRatePerCycle.java @@ -1,13 +1,12 @@ package org.broadinstitute.sting.gatk.walkers.diagnostics; -import net.sf.samtools.SAMReadGroupRecord; import org.broadinstitute.sting.commandline.Argument; import org.broadinstitute.sting.commandline.Output; import org.broadinstitute.sting.gatk.contexts.AlignmentContext; import org.broadinstitute.sting.gatk.contexts.ReferenceContext; import org.broadinstitute.sting.gatk.refdata.RefMetaDataTracker; import org.broadinstitute.sting.gatk.report.GATKReport; -import org.broadinstitute.sting.gatk.report.GATKReportTableV2; +import org.broadinstitute.sting.gatk.report.GATKReportTable; import org.broadinstitute.sting.gatk.walkers.LocusWalker; import org.broadinstitute.sting.utils.BaseUtils; import org.broadinstitute.sting.utils.QualityUtils; @@ -75,7 +74,7 @@ public class ErrorRatePerCycle extends LocusWalker { public Integer MIN_MAPPING_QUAL = 20; private GATKReport report; - private GATKReportTableV2 table; + private GATKReportTable table; private final static String reportName = "ErrorRatePerCycle"; private final static String reportDescription = "The error rate per sequenced position in the reads"; diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/diagnostics/ReadGroupProperties.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/diagnostics/ReadGroupProperties.java index bc3706f16..e4e3c271e 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/diagnostics/ReadGroupProperties.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/diagnostics/ReadGroupProperties.java @@ -30,7 +30,7 @@ import org.broadinstitute.sting.commandline.Output; import org.broadinstitute.sting.gatk.contexts.ReferenceContext; import org.broadinstitute.sting.gatk.refdata.ReadMetaDataTracker; import org.broadinstitute.sting.gatk.report.GATKReport; -import org.broadinstitute.sting.gatk.report.GATKReportTableV2; +import org.broadinstitute.sting.gatk.report.GATKReportTable; import org.broadinstitute.sting.gatk.walkers.ReadWalker; import org.broadinstitute.sting.utils.Median; import org.broadinstitute.sting.utils.sam.GATKSAMRecord; @@ -169,7 +169,7 @@ public class ReadGroupProperties extends ReadWalker { public void onTraversalDone(Integer sum) { final GATKReport report = new GATKReport(); report.addTable(TABLE_NAME, "Table of read group properties", 12); - GATKReportTableV2 table = report.getTable(TABLE_NAME); + GATKReportTable table = report.getTable(TABLE_NAME); DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.SHORT); table.addColumn("readgroup"); @@ -218,7 +218,7 @@ public class ReadGroupProperties extends ReadWalker { report.print(out); } - private final void setTableValue(GATKReportTableV2 table, final String rgID, final String key, final Object value) { + private final void setTableValue(GATKReportTable table, final String rgID, final String key, final Object value) { table.set(rgID, key, value == null ? "NA" : value); } } diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/diagnostics/ReadLengthDistribution.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/diagnostics/ReadLengthDistribution.java index 50e5e05e1..0f5432b80 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/diagnostics/ReadLengthDistribution.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/diagnostics/ReadLengthDistribution.java @@ -5,7 +5,7 @@ import org.broadinstitute.sting.commandline.Output; import org.broadinstitute.sting.gatk.contexts.ReferenceContext; import org.broadinstitute.sting.gatk.refdata.ReadMetaDataTracker; import org.broadinstitute.sting.gatk.report.GATKReport; -import org.broadinstitute.sting.gatk.report.GATKReportTableV2; +import org.broadinstitute.sting.gatk.report.GATKReportTable; import org.broadinstitute.sting.gatk.walkers.ReadWalker; import org.broadinstitute.sting.utils.sam.GATKSAMRecord; @@ -57,7 +57,7 @@ public class ReadLengthDistribution extends ReadWalker { report = new GATKReport(); report.addTable("ReadLengthDistribution", "Table of read length distributions", 1 + (readGroups.isEmpty() ? 1 : readGroups.size())); - GATKReportTableV2 table = report.getTable("ReadLengthDistribution"); + GATKReportTable table = report.getTable("ReadLengthDistribution"); table.addColumn("readLength"); @@ -74,7 +74,7 @@ public class ReadLengthDistribution extends ReadWalker { @Override public Integer map(ReferenceContext referenceContext, GATKSAMRecord samRecord, ReadMetaDataTracker readMetaDataTracker) { - GATKReportTableV2 table = report.getTable("ReadLengthDistribution"); + GATKReportTable table = report.getTable("ReadLengthDistribution"); int length = Math.abs(samRecord.getReadLength()); String sample = samRecord.getReadGroup().getSample(); diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/DiffEngine.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/DiffEngine.java index ef5abe4e4..28f78e880 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/DiffEngine.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/DiffEngine.java @@ -26,7 +26,7 @@ package org.broadinstitute.sting.gatk.walkers.diffengine; import org.apache.log4j.Logger; import org.broadinstitute.sting.gatk.report.GATKReport; -import org.broadinstitute.sting.gatk.report.GATKReportTableV2; +import org.broadinstitute.sting.gatk.report.GATKReportTable; import org.broadinstitute.sting.utils.Utils; import org.broadinstitute.sting.utils.classloader.PluginManager; import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; @@ -236,7 +236,7 @@ public class DiffEngine { GATKReport report = new GATKReport(); final String tableName = "differences"; report.addTable(tableName, "Summarized differences between the master and test files. See http://www.broadinstitute.org/gsa/wiki/index.php/DiffEngine for more information", 3); - final GATKReportTableV2 table = report.getTable(tableName); + final GATKReportTable table = report.getTable(tableName); table.addColumn("Difference"); table.addColumn("NumberOfOccurrences"); table.addColumn("ExampleDifference"); diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/GATKReportDiffableReader.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/GATKReportDiffableReader.java index f0af325f0..480a1fc29 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/GATKReportDiffableReader.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/GATKReportDiffableReader.java @@ -26,8 +26,7 @@ package org.broadinstitute.sting.gatk.walkers.diffengine; import org.broadinstitute.sting.gatk.report.GATKReport; import org.broadinstitute.sting.gatk.report.GATKReportColumn; -import org.broadinstitute.sting.gatk.report.GATKReportColumnV2; -import org.broadinstitute.sting.gatk.report.GATKReportTableV2; +import org.broadinstitute.sting.gatk.report.GATKReportTable; import java.io.File; import java.io.FileReader; @@ -53,7 +52,7 @@ public class GATKReportDiffableReader implements DiffableReader { // one line reads the whole thing into memory GATKReport report = new GATKReport(file); - for (GATKReportTableV2 table : report.getTables()) { + for (GATKReportTable table : report.getTables()) { root.add(tableToNode(table, root)); } @@ -63,13 +62,13 @@ public class GATKReportDiffableReader implements DiffableReader { } } - private DiffNode tableToNode(GATKReportTableV2 table, DiffNode root) { + private DiffNode tableToNode(GATKReportTable table, DiffNode root) { DiffNode tableRoot = DiffNode.empty(table.getTableName(), root); tableRoot.add("Description", table.getTableDescription()); tableRoot.add("NumberOfRows", table.getNumRows()); - for ( GATKReportColumnV2 column : table.getColumnInfo() ) { + for ( GATKReportColumn column : table.getColumnInfo() ) { DiffNode columnRoot = DiffNode.empty(column.getColumnName(), tableRoot); columnRoot.add("Width", column.getColumnFormat().getWidth()); diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/VariantEvalReportWriter.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/VariantEvalReportWriter.java index 7107d1a01..2a759f2f5 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/VariantEvalReportWriter.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/varianteval/VariantEvalReportWriter.java @@ -25,7 +25,7 @@ package org.broadinstitute.sting.gatk.walkers.varianteval; import org.broadinstitute.sting.gatk.report.GATKReport; -import org.broadinstitute.sting.gatk.report.GATKReportTableV2; +import org.broadinstitute.sting.gatk.report.GATKReportTable; import org.broadinstitute.sting.gatk.walkers.varianteval.evaluators.VariantEvaluator; import org.broadinstitute.sting.gatk.walkers.varianteval.stratifications.VariantStratifier; import org.broadinstitute.sting.gatk.walkers.varianteval.stratifications.manager.StratificationManager; @@ -75,7 +75,7 @@ public class VariantEvalReportWriter { final EvaluationContext nec = stratManager.get(key); for ( final VariantEvaluator ve : nec.getVariantEvaluators() ) { - final GATKReportTableV2 table = report.getTable(ve.getSimpleName()); + final GATKReportTable table = report.getTable(ve.getSimpleName()); final AnalysisModuleScanner scanner = new AnalysisModuleScanner(ve); final Map datamap = scanner.getData(); @@ -122,7 +122,7 @@ public class VariantEvalReportWriter { * @param primaryKey * @param stratsAndStates */ - private static void setStratificationColumns(final GATKReportTableV2 table, + private static void setStratificationColumns(final GATKReportTable table, final String primaryKey, final List> stratsAndStates) { table.set(primaryKey, table.getTableName(), table.getTableName()); @@ -165,7 +165,7 @@ public class VariantEvalReportWriter { report.addTable(tableName, tableDesc, 1 + stratifiers.size() + (scanner.hasMoltenField() ? 2 : datamap.size()), true); // grab the table, and add the columns we need to it - final GATKReportTableV2 table = report.getTable(tableName); + final GATKReportTable table = report.getTable(tableName); table.addColumn(tableName, tableName); // first create a column to hold each stratifier state diff --git a/public/java/src/org/broadinstitute/sting/utils/recalibration/QualQuantizer.java b/public/java/src/org/broadinstitute/sting/utils/recalibration/QualQuantizer.java index 0cb10679d..62edd5fac 100644 --- a/public/java/src/org/broadinstitute/sting/utils/recalibration/QualQuantizer.java +++ b/public/java/src/org/broadinstitute/sting/utils/recalibration/QualQuantizer.java @@ -29,7 +29,7 @@ import com.google.java.contract.Invariant; import com.google.java.contract.Requires; import org.apache.log4j.Logger; import org.broadinstitute.sting.gatk.report.GATKReport; -import org.broadinstitute.sting.gatk.report.GATKReportTableV2; +import org.broadinstitute.sting.gatk.report.GATKReportTable; import org.broadinstitute.sting.utils.QualityUtils; import org.broadinstitute.sting.utils.Utils; import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; @@ -423,7 +423,7 @@ public class QualQuantizer { private final void addQualHistogramToReport(final GATKReport report) { report.addTable("QualHistogram", "Quality score histogram provided to report", 2); - GATKReportTableV2 table = report.getTable("QualHistogram"); + GATKReportTable table = report.getTable("QualHistogram"); table.addColumn("qual"); table.addColumn("count"); @@ -437,7 +437,7 @@ public class QualQuantizer { private final void addIntervalsToReport(final GATKReport report) { report.addTable("QualQuantizerIntervals", "Table of QualQuantizer quantization intervals", 10); - GATKReportTableV2 table = report.getTable("QualQuantizerIntervals"); + GATKReportTable table = report.getTable("QualQuantizerIntervals"); table.addColumn("name"); table.addColumn("qStart"); @@ -455,7 +455,7 @@ public class QualQuantizer { addIntervalToReport(table, interval, true); } - private final void addIntervalToReport(final GATKReportTableV2 table, final QualInterval interval, final boolean atRootP) { + private final void addIntervalToReport(final GATKReportTable table, final QualInterval interval, final boolean atRootP) { final String name = interval.getName(); table.set(name, "name", name); table.set(name, "qStart", interval.qStart); diff --git a/public/java/test/org/broadinstitute/sting/gatk/report/GATKReportUnitTest.java b/public/java/test/org/broadinstitute/sting/gatk/report/GATKReportUnitTest.java index d538a027f..a82c22b31 100644 --- a/public/java/test/org/broadinstitute/sting/gatk/report/GATKReportUnitTest.java +++ b/public/java/test/org/broadinstitute/sting/gatk/report/GATKReportUnitTest.java @@ -41,12 +41,12 @@ public class GATKReportUnitTest extends BaseTest { Assert.assertEquals(report.getVersion(), GATKReportVersion.V1_1); Assert.assertEquals(report.getTables().size(), 5); - GATKReportTableV2 countVariants = report.getTable("CountVariants"); + GATKReportTable countVariants = report.getTable("CountVariants"); Assert.assertEquals(countVariants.get(0, "nProcessedLoci"), "63025520"); Assert.assertEquals(countVariants.get(0, "nNoCalls"), "0"); Assert.assertEquals(countVariants.get(0, "heterozygosity"), 4.73e-06); - GATKReportTableV2 validationReport = report.getTable("ValidationReport"); + GATKReportTable validationReport = report.getTable("ValidationReport"); Assert.assertEquals(validationReport.get(2, "PPV"), Double.NaN); } @@ -77,9 +77,9 @@ public class GATKReportUnitTest extends BaseTest { Assert.assertEquals(GATKReportColumn.isRightAlign(value), expected, "right align of '" + value + "'"); } - private GATKReportTableV2 makeBasicTable() { + private GATKReportTable makeBasicTable() { GATKReport report = GATKReport.newSimpleReport("TableName", "sample", "value"); - GATKReportTableV2 table = report.getTable("TableName"); + GATKReportTable table = report.getTable("TableName"); report.addRow("foo.1", "hello"); report.addRow("foo.2", "world"); return table; @@ -87,7 +87,7 @@ public class GATKReportUnitTest extends BaseTest { @Test public void testDottedSampleName() { - GATKReportTableV2 table = makeBasicTable(); + GATKReportTable table = makeBasicTable(); Assert.assertEquals(table.get(0, "value"), "hello"); Assert.assertEquals(table.get(1, "value"), "world"); } @@ -151,7 +151,7 @@ public class GATKReportUnitTest extends BaseTest { report1.concat(report3); report1.addTable("Table2", "To contain some more data types", 3); - GATKReportTableV2 table = report1.getTable("Table2"); + GATKReportTable table = report1.getTable("Table2"); table.addColumn("SomeInt", "%d"); table.addColumn("SomeFloat", "%.16E"); table.addColumn("TrueFalse", "%B"); diff --git a/public/java/test/org/broadinstitute/sting/gatk/walkers/bqsr/BQSRGathererUnitTest.java b/public/java/test/org/broadinstitute/sting/gatk/walkers/bqsr/BQSRGathererUnitTest.java index d789eecde..8e9f2533f 100644 --- a/public/java/test/org/broadinstitute/sting/gatk/walkers/bqsr/BQSRGathererUnitTest.java +++ b/public/java/test/org/broadinstitute/sting/gatk/walkers/bqsr/BQSRGathererUnitTest.java @@ -1,7 +1,7 @@ package org.broadinstitute.sting.gatk.walkers.bqsr; import org.broadinstitute.sting.gatk.report.GATKReport; -import org.broadinstitute.sting.gatk.report.GATKReportTableV2; +import org.broadinstitute.sting.gatk.report.GATKReportTable; import org.testng.Assert; import org.testng.annotations.Test; @@ -30,8 +30,8 @@ public class BQSRGathererUnitTest { GATKReport originalReport = new GATKReport(recal); GATKReport calculatedReport = new GATKReport(output); - for (GATKReportTableV2 originalTable : originalReport.getTables()) { - GATKReportTableV2 calculatedTable = calculatedReport.getTable(originalTable.getTableName()); + for (GATKReportTable originalTable : originalReport.getTables()) { + GATKReportTable calculatedTable = calculatedReport.getTable(originalTable.getTableName()); List columnsToTest = new LinkedList(); columnsToTest.add(RecalDataManager.NUMBER_OBSERVATIONS_COLUMN_NAME); columnsToTest.add(RecalDataManager.NUMBER_ERRORS_COLUMN_NAME); @@ -59,7 +59,7 @@ public class BQSRGathererUnitTest { * @param columnsToTest list of columns to test. All columns will be tested with the same criteria (equality given factor) * @param factor 1 to test for equality, any other value to multiply the original value and match with the calculated */ - private void testTablesWithColumnsAndFactor(GATKReportTableV2 original, GATKReportTableV2 calculated, List columnsToTest, int factor) { + private void testTablesWithColumnsAndFactor(GATKReportTable original, GATKReportTable calculated, List columnsToTest, int factor) { for (int row = 0; row < original.getNumRows(); row++ ) { for (String column : columnsToTest) { Object actual = calculated.get(new Integer(row), column); diff --git a/public/scala/src/org/broadinstitute/sting/queue/util/QJobReport.scala b/public/scala/src/org/broadinstitute/sting/queue/util/QJobReport.scala index d49e4526d..093741b5d 100644 --- a/public/scala/src/org/broadinstitute/sting/queue/util/QJobReport.scala +++ b/public/scala/src/org/broadinstitute/sting/queue/util/QJobReport.scala @@ -25,7 +25,7 @@ package org.broadinstitute.sting.queue.util import org.broadinstitute.sting.queue.function.QFunction -import org.broadinstitute.sting.gatk.report.{GATKReportTableV2, GATKReport} +import org.broadinstitute.sting.gatk.report.{GATKReportTable, GATKReport} import org.broadinstitute.sting.utils.exceptions.UserException import org.broadinstitute.sting.queue.engine.JobRunInfo import java.io.{PrintStream, File} @@ -65,7 +65,7 @@ trait QJobReport extends Logging { } /** The report Group is the analysis name transform to only contain valid GATKReportTable characters */ - def getReportGroup = self.analysisName.replaceAll(GATKReportTableV2.INVALID_TABLE_NAME_REGEX, "_") + def getReportGroup = self.analysisName.replaceAll(GATKReportTable.INVALID_TABLE_NAME_REGEX, "_") def getReportFeatures = reportFeatures def getReportFeatureNames: Seq[String] = getReportFeatures.keys.toSeq @@ -141,7 +141,7 @@ object QJobReport { for ( (group, groupLogs) <- groupLogs(logs) ) { val keys = logKeys(groupLogs) report.addTable(group, "Job logs for " + group, keys.size) - val table: GATKReportTableV2 = report.getTable(group) + val table: GATKReportTable = report.getTable(group) // add the columns keys.foreach(table.addColumn(_))