From 8fd59c88232618bae576a9713a117d6a7aac9d5b Mon Sep 17 00:00:00 2001 From: aaron Date: Wed, 7 Apr 2010 20:39:55 +0000 Subject: [PATCH] Modified the report system based on Ryan's feedback: tables are now created independently to avoid the permutation problem when they were all compressed in rows, and removed our dependency on FreeMarker. The Grep format stays the same. git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@3130 348d0f76-0448-11de-a6fe-93d51630548a --- ivy.xml | 1 - .../utils/report/ReportMarshaller.java | 29 +-- .../utils/report/VE2ReportFactory.java | 68 +++--- .../utils/report/templates/CSVFormat.java | 29 +++ .../utils/report/templates/GrepFormat.java | 58 +++++ .../utils/report/templates/ReportFormat.java | 17 ++ .../report/templates/TableBasedFormat.java | 212 ++++++++++++++++++ .../utils/report/templates/TableFormat.java | 42 ++++ .../utils/report/templates/human_readable.ftl | 69 +++--- .../utils/report/utils/ComplexDataUtils.java | 17 +- .../playground/utils/report/utils/Node.java | 7 +- .../utils/report/utils/NodeUtils.java | 12 +- .../VariantEval2IntegrationTest.java | 10 +- .../utils/report/ReportMarshallerTest.java | 2 +- 14 files changed, 452 insertions(+), 121 deletions(-) create mode 100644 java/src/org/broadinstitute/sting/playground/utils/report/templates/CSVFormat.java create mode 100644 java/src/org/broadinstitute/sting/playground/utils/report/templates/GrepFormat.java create mode 100644 java/src/org/broadinstitute/sting/playground/utils/report/templates/ReportFormat.java create mode 100644 java/src/org/broadinstitute/sting/playground/utils/report/templates/TableBasedFormat.java create mode 100644 java/src/org/broadinstitute/sting/playground/utils/report/templates/TableFormat.java diff --git a/ivy.xml b/ivy.xml index 48cdb7b27..4f5e0cb3b 100644 --- a/ivy.xml +++ b/ivy.xml @@ -16,7 +16,6 @@ - diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/ReportMarshaller.java b/java/src/org/broadinstitute/sting/playground/utils/report/ReportMarshaller.java index 4459fce57..c52dc4421 100644 --- a/java/src/org/broadinstitute/sting/playground/utils/report/ReportMarshaller.java +++ b/java/src/org/broadinstitute/sting/playground/utils/report/ReportMarshaller.java @@ -23,11 +23,8 @@ package org.broadinstitute.sting.playground.utils.report; -import freemarker.template.Configuration; -import freemarker.template.DefaultObjectWrapper; -import freemarker.template.Template; -import freemarker.template.TemplateException; -import org.broadinstitute.sting.oneoffprojects.walkers.varianteval2.CountVariants; + +import org.broadinstitute.sting.playground.utils.report.templates.ReportFormat; import org.broadinstitute.sting.playground.utils.report.utils.ComplexDataUtils; import org.broadinstitute.sting.playground.utils.report.utils.Node; import org.broadinstitute.sting.utils.StingException; @@ -46,7 +43,7 @@ import java.util.*; * marshall report data out of the GATK. */ public class ReportMarshaller { - private Template temp; + private ReportFormat temp; // the aggregation of all our analyses private Node root; @@ -58,7 +55,7 @@ public class ReportMarshaller { * @param reportName the report name * @param template the template to use */ - public ReportMarshaller(String reportName, File filename, Template template) { + public ReportMarshaller(String reportName, File filename, ReportFormat template) { try { init(reportName, new OutputStreamWriter(new FileOutputStream(filename))); } catch (FileNotFoundException e) { @@ -72,7 +69,7 @@ public class ReportMarshaller { * * @param reportName the report name */ - public ReportMarshaller(String reportName, Writer writer, Template template, List reportTags) { + public ReportMarshaller(String reportName, Writer writer, ReportFormat template, List reportTags) { init(reportName, writer); temp = template; for (Node n : reportTags) { @@ -86,7 +83,7 @@ public class ReportMarshaller { * * @param reportName the report name */ - public ReportMarshaller(String reportName, OutputStream writer, Template template, List reportTags) { + public ReportMarshaller(String reportName, OutputStream writer, ReportFormat template, List reportTags) { init(reportName, new PrintWriter(writer)); temp = template; for (Node n : reportTags) { @@ -152,7 +149,7 @@ public class ReportMarshaller { } /** - * output the Params objects we find + * collect the Params objects annotated on the target object * * @param toMarshall the object to output * @param moduleScanner our scanner, which stores the annotated field information @@ -171,7 +168,7 @@ public class ReportMarshaller { } /** - * output the DataPoint objects we find + * collect the DataPoint objects annotated on the target object * * @param toMarshall the object to output * @param moduleScanner our scanner, which stores the annotated field information @@ -194,15 +191,11 @@ public class ReportMarshaller { */ public void close() { try { - // add the data to a map - Map map = new HashMap(); - map.put("root", root); - temp.process(map, writeLocation); + temp.write(writeLocation, root); writeLocation.flush(); - } catch (TemplateException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + writeLocation.close(); } catch (IOException e) { - e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + throw new StingException("IO exception", e); } } diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/VE2ReportFactory.java b/java/src/org/broadinstitute/sting/playground/utils/report/VE2ReportFactory.java index 770c23998..e277b7e0b 100644 --- a/java/src/org/broadinstitute/sting/playground/utils/report/VE2ReportFactory.java +++ b/java/src/org/broadinstitute/sting/playground/utils/report/VE2ReportFactory.java @@ -1,8 +1,9 @@ package org.broadinstitute.sting.playground.utils.report; -import freemarker.template.Configuration; -import freemarker.template.DefaultObjectWrapper; -import freemarker.template.Template; +import org.broadinstitute.sting.playground.utils.report.templates.CSVFormat; +import org.broadinstitute.sting.playground.utils.report.templates.GrepFormat; +import org.broadinstitute.sting.playground.utils.report.templates.ReportFormat; +import org.broadinstitute.sting.playground.utils.report.templates.TableFormat; import org.broadinstitute.sting.playground.utils.report.utils.Node; import org.broadinstitute.sting.utils.StingException; @@ -29,30 +30,17 @@ public class VE2ReportFactory { /** the types of templates we're aware of for VariantEval2 */ public enum VE2TemplateType { - Table("human_readable.ftl"), - Grep("grep_readable.ftl"), - CSV("csv_readable.ftl"); + Table(TableFormat.class), + Grep(GrepFormat.class), + CSV(CSVFormat.class); - public String filename; + public Class underlyingReportType; - VE2TemplateType(String file) { - filename = file; + VE2TemplateType(Class type) { + underlyingReportType = type; } } - /** - * create a list of RM from an mapping of writer to template type - * @param fileset the mapping of files to types - * @param reportTags the tags to append to each report root node - * @return a list of ReportMarshallers to write data to - */ - public static List getTemplate(Map fileset, List reportTags) { - List list = new ArrayList(); - for (Writer writer : fileset.keySet()) - list.add(new ReportMarshaller("Variant Eval 2 Report",writer,createTemplate(fileset.get(writer)),reportTags)); - return list; - } - /** * create a report ReportMarshaller from a writer, type, and any report tags * @param writer the output object @@ -60,27 +48,27 @@ public class VE2ReportFactory { * @param reportTags the tags to append to each report root node * @return a list of ReportMarshallers to write data to */ - public static ReportMarshaller getTemplate(OutputStream writer,VE2TemplateType type, List reportTags) { - return new ReportMarshaller("Variant Eval 2 Report",writer,createTemplate(type),reportTags); + public static ReportMarshaller createMarhsaller(OutputStream writer,VE2TemplateType type, List reportTags) { + return new ReportMarshaller("Variant Eval 2 Report",writer,createByType(type.underlyingReportType),reportTags); } /** - * create a template from the TemplateType - * @param template the template type - * @return a Template object + * create a report formatter with the given type + * + * @param formatType type of the reporter to create. + * + * @return The reporter object if created; null otherwise. */ - private static Template createTemplate(VE2TemplateType template) { - Configuration cfg = new Configuration(); - cfg.setClassForTemplateLoading(VE2ReportFactory.class,ve2templateDir); - - cfg.setObjectWrapper(new DefaultObjectWrapper()); - Template temp = null; - try { - temp = cfg.getTemplate(template.filename); - } catch (IOException e) { - throw new StingException("Unable to create template file " + template.filename + " of type " + template,e); - } - return temp; - } + public static ReportFormat createByType(Class formatType) { + try { + return ((Class) formatType).newInstance(); + } + catch (InstantiationException ex) { + throw new StingException(String.format("Unable to instantiate %s", formatType), ex); + } + catch (IllegalAccessException ex) { + throw new StingException(String.format("Unable to access %s", formatType), ex); + } + } } diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/templates/CSVFormat.java b/java/src/org/broadinstitute/sting/playground/utils/report/templates/CSVFormat.java new file mode 100644 index 000000000..9689b623a --- /dev/null +++ b/java/src/org/broadinstitute/sting/playground/utils/report/templates/CSVFormat.java @@ -0,0 +1,29 @@ +package org.broadinstitute.sting.playground.utils.report.templates; + +/** + * the basic comma seperated value format + */ +public class CSVFormat extends TableBasedFormat { + private final String DIVIDER = ","; + + /** + * format the string according to our internal rules + * + * @param str the string to format + * @return a string, properly formatted + */ + @Override + public String formatColumn(String str) { + return str+DIVIDER; + } + + /** + * does the output format want to display line breaks (dotted lines)? + * + * @return true if the format uses them + */ + @Override + public boolean displayDashedLineBreaks() { + return false; + } +} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/templates/GrepFormat.java b/java/src/org/broadinstitute/sting/playground/utils/report/templates/GrepFormat.java new file mode 100644 index 000000000..48ff70612 --- /dev/null +++ b/java/src/org/broadinstitute/sting/playground/utils/report/templates/GrepFormat.java @@ -0,0 +1,58 @@ +package org.broadinstitute.sting.playground.utils.report.templates; + +import org.broadinstitute.sting.playground.utils.report.utils.Node; + +import java.io.PrintWriter; +import java.io.Writer; + + +/** + * + * @author aaron + * + * Class GrepFormat + * + * implements the grep output format + */ +public class GrepFormat implements ReportFormat { + private PrintWriter stream; + + /** + * write out to the writer, given the root node + * @param baseFile the writer to write to + * @param baseNode the root node + */ + @Override + public void write(Writer baseFile, Node baseNode) { + stream = new PrintWriter(baseFile); + for (Node analysis : baseNode.getChildren()) { + StringBuilder builder = new StringBuilder(); + boolean first = true; + for (Node tag : analysis.getChildren()) { + if (first) first = false; + else if (tag.tag) { + builder.append("."); + } + if ( tag.tag ) builder.append("["+tag.getName() + "=" + tag.getValue()+"]"); + } + recursiveTraverse(analysis,builder.toString()); + } + } + + /** + * recursively get the data. If we hit a final node, output the node plus the trailing text + * @param n the node we're looking at + * @param value the previous text we've seen + */ + public void recursiveTraverse(Node n, String value) { + if (n.tag) return; + if (n.getChildren().size() < 1) { + stream.println(value + " " + n.getValue()); + } + else { + String nString = n.getName() + "=" +n.getValue(); + for (Node child : n.getChildren()) + recursiveTraverse(child,value + ".[" + nString + "]"); + } + } +} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/templates/ReportFormat.java b/java/src/org/broadinstitute/sting/playground/utils/report/templates/ReportFormat.java new file mode 100644 index 000000000..113d22a52 --- /dev/null +++ b/java/src/org/broadinstitute/sting/playground/utils/report/templates/ReportFormat.java @@ -0,0 +1,17 @@ +package org.broadinstitute.sting.playground.utils.report.templates; + +import org.broadinstitute.sting.playground.utils.report.utils.Node; + +import java.io.File; +import java.io.Writer; + +/** + * @author aaron + *

+ * Interface ReportFormat + *

+ * The basics of a report formatter + */ +public interface ReportFormat { + public void write(Writer baseFile, Node baseNode); +} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/templates/TableBasedFormat.java b/java/src/org/broadinstitute/sting/playground/utils/report/templates/TableBasedFormat.java new file mode 100644 index 000000000..17ae422e5 --- /dev/null +++ b/java/src/org/broadinstitute/sting/playground/utils/report/templates/TableBasedFormat.java @@ -0,0 +1,212 @@ +package org.broadinstitute.sting.playground.utils.report.templates; + +import org.broadinstitute.sting.playground.utils.report.utils.Node; + +import java.io.PrintWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * an abstract class to share the basics of a table based format; many methods + * overlap in different output types. + */ +public abstract class TableBasedFormat implements ReportFormat { + private Map> analyses = new HashMap>(); + private PrintWriter stream; + + @Override + public void write(Writer writeTo, Node baseNode) { + getAnalyses(baseNode); + stream = new PrintWriter(writeTo); + for (String s : analyses.keySet()) { + writeAnalysis(analyses.get(s)); + outputTables(analyses.get(s)); + } + } + + /** + * break out the analyses by type, given the base node + * @param baseNode the root node + */ + private void getAnalyses(Node baseNode) { + for (Node n : baseNode.getChildren()) + if (!n.tag && n.getComplex()) { + if (!analyses.containsKey(n.getValue())) + analyses.put(n.getValue(),new ArrayList()); + analyses.get(n.getValue()).add(n); + } + } + + /** + * write the analysis nodes out, only outputting the simple data points (non-table data) + * @param nodes a list of nodes, of the same analysis type + */ + private void writeAnalysis(List nodes) { + if (nodes.size() < 1 || !nodes.get(0).getName().equals("analysis")) return; + Node forTitle = nodes.get(0); + stream.println(niceDivider(80)); + stream.println("Analysis Name: \t" + forTitle.getValue()); + stream.println("Analysis Description: \t" + forTitle.getDescription()); + stream.println(); + + String header = extractHeaderString(forTitle); + if (header == null) return; // a null here indicates we don't have any unique columns to display + stream.println(header); + stream.println(niceDivider(header.length())); + + for (Node analysis : nodes) { + String dataString = dataPointNodesToValues(analysis); + if (dataString.length() > 0 && !dataString.equals("")) { + stream.print(getTagValues(analysis)); + stream.println(dataString); + } + } + stream.println(); + stream.println(); + + } + + /** + * output the tables: look at list of analysis nodes (all from the same analysis) and output the table + * @param nodes the list of analysis nodes (of the same underlying type) + */ + public void outputTables(List nodes) { + Map> tableRows = new HashMap>(); + Map tableHeaders = new HashMap(); + for (Node analysis : nodes) + for (Node n : analysis.getChildren()) { + if (n.table) { + StringBuilder columnBuilder = new StringBuilder(); + getTagNames(analysis,columnBuilder); + for (Node row : n.getChildren()) { + StringBuilder rowBuilder = new StringBuilder(); + rowBuilder.append(getTagValues(analysis)); + rowBuilder.append(formatColumn(row.getValue())); + columnBuilder.append(formatColumn(row.getName())); + for (Node column : row.getChildren()) { + columnBuilder.append(formatColumn(column.getValue())); + if (column.getChildren().size() == 1) { + String value = formatColumn(column.getChildren().iterator().next().getValue()); + rowBuilder.append(value); + } + } + if (!tableRows.containsKey(n.getValue())) + tableRows.put(n.getValue(),new ArrayList()); + tableRows.get(n.getValue()).add(rowBuilder.toString()); + if (!tableHeaders.containsKey(n.getValue())) + tableHeaders.put(n.getValue(),columnBuilder.toString()); + } + } + } + + // output the tables + for (String tableName : tableHeaders.keySet()) { + stream.println("Table Name : " + tableName); + stream.println(); + stream.println(tableHeaders.get(tableName)); + stream.println(niceDivider(tableHeaders.get(tableName).length())); + List rows = tableRows.get(tableName); + for (String row : rows) + stream.println(row); + stream.println(); + } + } + + /** + * get the header (tag) names + * @param analysis the analysis node + * @return a string representing the tag names + */ + private String getTagValues(Node analysis) { + StringBuilder buffer = new StringBuilder(); + for (Node s : analysis.getChildren()) + if (s.tag) buffer.append(formatColumn(s.getValue())); + return buffer.toString(); + } + + /** + * simple data points describe themselves, and have one child that stores their value and it's description. Extract the value and + * convert the list of nodes to a string + * @param analysis the analysis + * @return a String representing the values + */ + private String dataPointNodesToValues(Node analysis) { + StringBuilder builder = new StringBuilder(); + for (Node n : analysis.getChildren()) { + if (!n.tag && !n.table) { + if (n.getChildren().size() > 1) throw new IllegalStateException("Simple data points shouldn't have more than one value"); + if (n.getChildren().size() == 1) + builder.append(formatColumn(n.getChildren().iterator().next().getValue())); + } + } + return builder.toString(); + } + + /** + * extract the header string from the base analysis node + */ + private String extractHeaderString(Node analysisNode) { + StringBuilder buffer = new StringBuilder(); + // first get the tags + getTagNames(analysisNode, buffer); + if (!getColumnNames(analysisNode, buffer)) + return null; + + return buffer.toString(); + } + + /** + * get the column names from the analysis node + * @param analysisNode the node + * @param buffer the buffer to append to + * @return true if there was data fields to output, false if we dont add data to the column header list + */ + private boolean getColumnNames(Node analysisNode, StringBuilder buffer) { + // now get the simple data points + boolean addedValue = false; + for (Node n : analysisNode.getChildren()) + if (!n.tag && !n.table) { + addedValue = true; + buffer.append(formatColumn(n.getValue())); + } + return addedValue; + } + + /** + * get the tags names from an analysis node + * @param analysisNode the node + * @param buffer the StringBuilder to append to + */ + private void getTagNames(Node analysisNode, StringBuilder buffer) { + for (Node n : analysisNode.getChildren()) + if (n.tag) buffer.append(formatColumn(n.getName())); + } + + /** + * create a correct-length divider string + * @param length the length for the divider + * @return a string with the divider text of length "length" + */ + private String niceDivider(int length) { + if (!displayDashedLineBreaks()) return ""; + StringBuilder builder = new StringBuilder(); + for (int x = 0; x < length; x++) builder.append("-"); + return builder.toString(); + } + + /** + * format the string according to our internal rules + * @param str the string to format + * @return a string, properly formatted + */ + public abstract String formatColumn(String str); + + /** + * does the output format want to display line breaks (dotted lines)? + * @return true if the format uses them + */ + public abstract boolean displayDashedLineBreaks(); +} diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/templates/TableFormat.java b/java/src/org/broadinstitute/sting/playground/utils/report/templates/TableFormat.java new file mode 100644 index 000000000..195608310 --- /dev/null +++ b/java/src/org/broadinstitute/sting/playground/utils/report/templates/TableFormat.java @@ -0,0 +1,42 @@ +package org.broadinstitute.sting.playground.utils.report.templates; + +import org.broadinstitute.sting.playground.utils.report.utils.Node; +import org.broadinstitute.sting.utils.Pair; + +import java.io.*; +import java.util.*; + + +/** + * + * @author aaron + * + * Class TableFormat + * + * implements the table (human readable) format. + */ +public class TableFormat extends TableBasedFormat { + private static final int COLUMN_WIDTH = 25; + + /** + * format the string according to our internal rules + * + * @param str the string to format + * @return a string, properly formatted + */ + @Override + public String formatColumn(String str) { + return String.format("%-"+COLUMN_WIDTH+"s",str); + } + + /** + * does the output format want to display line breaks (dotted lines)? + * + * @return true if the format uses them + */ + @Override + public boolean displayDashedLineBreaks() { + return true; + } +} + diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/templates/human_readable.ftl b/java/src/org/broadinstitute/sting/playground/utils/report/templates/human_readable.ftl index ef715f6b4..21d76f021 100644 --- a/java/src/org/broadinstitute/sting/playground/utils/report/templates/human_readable.ftl +++ b/java/src/org/broadinstitute/sting/playground/utils/report/templates/human_readable.ftl @@ -6,23 +6,26 @@ Report: ${root.value} Description: ${root.description} -<#-- get any tags on the root node --> +<#-- get any tags on the root node (any information we've tagged the report with) --> <#list root.children as tagNode> <#if tagNode.tag> Tag: ${tagNode.name} = ${tagNode.value} -<#list root.children as analysis> +<#list root.childresn as analysis> <#if analysis.complex> - <#if analysis.value!=currentAnalysis> + <#if analysis.value!=currentAnalysi> <#assign currentAnalysis=analysis.value> Analysis: ${analysis.value} Column names specific to the analysis: <@emit_column_names_with_descriptions analysis=analysis/> - + + + <@emit_tables analysis=analysis/> + <@emit_tags analysis=analysis/> <@emit_column_names analysis=analysis/> @@ -32,16 +35,32 @@ Column names specific to the analysis: <#-- -------------------- --> +<#-- emit only tables --> +<#macro emit_tables analysis> + <#if analysis.complex && !analysis.tag> + <#list analysis.children as child> + <#if child.table> + <@emit_tags analysis=analysis/> + <#list child.tableRows as rows> + <@emit_tag_values analysis=analysis/> + +---------------------------------------------------------------------------------------------------------------------------------------- + <#list rows as node> + <@emit_name value=node.value/> + + + + + + + +<#-- -------------------- --> <#-- get the data tag values --> <#macro emit_row_values analysis> - <#list analysis.tableRows as rows> + <#list analysis.tableRowsNoTables as rows> <@emit_tag_values analysis=analysis/> <#list rows as node> - <#if (node.value?length > colTextWidth)> - <#lt>${(node.value?substring(0, colTextWidth)+"..")?right_pad(colWidth)}<#rt> - <#else> - <#lt>${node.value?right_pad(colWidth)}<#rt> - + <@emit_name value=node.value/> @@ -49,38 +68,22 @@ Column names specific to the analysis: <#-- -------------------- --> <#-- get the column names --> <#macro emit_column_names analysis> - <#if analysis.complex && analysis.display> + <#if analysis.complex && !analysis.tag> <#list analysis.children as child> <#if child.complex && !child.table> - <@emit_name value=child.value/> - <#elseif child.table> - <#list child.children as rows> - <@emit_name value=rows.name/> - <#list rows.children as cols> - <@emit_name value=cols.value/> - - <#break> - + <@emit_name value=child.value/> <#-- -------------------- --> -<#-- get the column names --> +<#-- get the column names to display at the top of the analysis --> <#macro emit_column_names_with_descriptions analysis> - <#if analysis.complex && analysis.display> + <#if analysis.complex && !analysis.tag> <#list analysis.children as child> <#if child.complex && !child.table> - ${child.value?right_pad(40)}${child.description} - <#elseif child.table> - <#list child.children as rows> - ${rows.name?right_pad(40)}${rows.description} - <#list rows.children as cols> - ${cols.value?right_pad(40)}${cols.description} - - <#break> - - + ${child.value?right_pad(40)}${child.description} + @@ -104,7 +107,7 @@ Column names specific to the analysis: <#-- -------------------- --> -<#-- a macro for cleaning up emitted names --> +<#-- a macro for formatting emitted names --> <#macro emit_name value> <#if (value?length > colTextWidth)> <#lt>${(value?substring(0, colTextWidth)+"..")?right_pad(colWidth)}<#rt> diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/utils/ComplexDataUtils.java b/java/src/org/broadinstitute/sting/playground/utils/report/utils/ComplexDataUtils.java index b4eb2fa45..05d3cd817 100644 --- a/java/src/org/broadinstitute/sting/playground/utils/report/utils/ComplexDataUtils.java +++ b/java/src/org/broadinstitute/sting/playground/utils/report/utils/ComplexDataUtils.java @@ -31,7 +31,7 @@ public class ComplexDataUtils { // try to handle maps else if (obj instanceof Map) { - extractMap(obj, nodes); + throw new UnsupportedOperationException("The report generation system is currently unable to output Maps, due to their ambiguity"); // handle collections } else if (obj instanceof Collection) @@ -49,21 +49,6 @@ public class ComplexDataUtils { return nodes; } - /** - * extract a map object - * @param obj the object (instance of Map) - * @param nodes the node list to add our key->values to - */ - private static void extractMap(Object obj, Collection nodes) { - for (Object key : ((Map) obj).keySet()) { - Node keyNode = new Node("key", key.toString(), "map key"); - nodes.add(keyNode); - keyNode.addAllChildren(resolveObjects(((Map) obj).get(key))); - } - // special case: if the map is empty, add a null node - if (nodes.isEmpty()) nodes.add(new Node("", "", "")); - } - /** * extract a (hopefully) primitive value * @param obj the object diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/utils/Node.java b/java/src/org/broadinstitute/sting/playground/utils/report/utils/Node.java index db0d0f2cf..7ebf09eaf 100644 --- a/java/src/org/broadinstitute/sting/playground/utils/report/utils/Node.java +++ b/java/src/org/broadinstitute/sting/playground/utils/report/utils/Node.java @@ -103,7 +103,12 @@ public class Node { } public List> getTableRows() { - List> ret = NodeUtils.flattenToRow(this); + List> ret = NodeUtils.flattenToRow(this,false); + return ret; + } + + public List> getTableRowsNoTables() { + List> ret = NodeUtils.flattenToRow(this,true); return ret; } diff --git a/java/src/org/broadinstitute/sting/playground/utils/report/utils/NodeUtils.java b/java/src/org/broadinstitute/sting/playground/utils/report/utils/NodeUtils.java index 228b8a239..d7f4df109 100644 --- a/java/src/org/broadinstitute/sting/playground/utils/report/utils/NodeUtils.java +++ b/java/src/org/broadinstitute/sting/playground/utils/report/utils/NodeUtils.java @@ -42,7 +42,7 @@ public class NodeUtils { return list; } - public List> toRow(List> oldList) { + public List> toRow(List> oldList, boolean excludeTables) { // if we're a leaf node that isn't a tag, add it to each list if (validLeafNode()) addToEachList(oldList); @@ -50,10 +50,10 @@ public class NodeUtils { // special case: if we've just got a single node, traverse into it else if (node.getChildren().size() > 0 && !node.table) for (Node n : node.children) { - oldList = new NodeMarker(n).toRow(oldList); + oldList = new NodeMarker(n).toRow(oldList, excludeTables); } // when we encounter a table we want to branch into multiple rows - else if (node.table) { + else if (node.table && !excludeTables) { List> newList = new ArrayList>(); for (Node child : node.children) { if (child.display && !child.tag) { @@ -61,7 +61,7 @@ public class NodeUtils { tempList.add(new ArrayList()); tempList.get(0).add(child); NodeMarker marker = new NodeMarker(child); - List> carry = marker.toRow(tempList); + List> carry = marker.toRow(tempList, excludeTables); newList.addAll(carry); } } @@ -90,10 +90,10 @@ public class NodeUtils { } // given a node, generate rows (flattening tables) - public static List> flattenToRow(Node n) { + public static List> flattenToRow(Node n, boolean excludeTables) { NodeMarker fn = new NodeMarker(n); List> nodesList = new ArrayList>(); nodesList.add(new ArrayList()); - return fn.toRow(nodesList); + return fn.toRow(nodesList, excludeTables); } } diff --git a/java/test/org/broadinstitute/sting/oneoffprojects/walkers/varianteval2/VariantEval2IntegrationTest.java b/java/test/org/broadinstitute/sting/oneoffprojects/walkers/varianteval2/VariantEval2IntegrationTest.java index 93a3949b2..299cbad85 100755 --- a/java/test/org/broadinstitute/sting/oneoffprojects/walkers/varianteval2/VariantEval2IntegrationTest.java +++ b/java/test/org/broadinstitute/sting/oneoffprojects/walkers/varianteval2/VariantEval2IntegrationTest.java @@ -18,8 +18,8 @@ public class VariantEval2IntegrationTest extends WalkerTest { @Test public void testVE2Simple() { HashMap expectations = new HashMap(); - expectations.put("-L 1:1-10,000,000", "d5a8c6550236e971ffe29f7f254ad076"); - expectations.put("-L 1:1-10,000,000 -family NA19238+NA19239=NA19240 -MVQ 0", "529b56760da952741e9d843453a8eb73"); + expectations.put("-L 1:1-10,000,000", "32d771b62dadc1c164f19bf3a1efc018"); + expectations.put("-L 1:1-10,000,000 -family NA19238+NA19239=NA19240 -MVQ 0", "de42a239847e3466f4526e4781710ce7"); for ( Map.Entry entry : expectations.entrySet() ) { String extraArgs = entry.getKey(); @@ -39,10 +39,10 @@ public class VariantEval2IntegrationTest extends WalkerTest { " -B dbsnp_130,dbSNP," + GATKDataLocation + "dbsnp_130_b36.rod" + " -B comp_hapmap,VCF," + validationDataLocation + "CEU_hapmap_nogt_23.vcf"; - String eqMD5s = "13d2de47f9fe56a4ddfeca10d9c1d5a9"; // next two examples should be the same! + String eqMD5s = "0e961437bec3d4ad28b1511c0c45d13a"; // next two examples should be the same! expectations.put("", eqMD5s); expectations.put(" -known comp_hapmap -known dbsnp", eqMD5s); - expectations.put(" -known comp_hapmap", "edd1f32a7f2f0390fdd0cc4c5ff14bf1"); + expectations.put(" -known comp_hapmap", "139b10dc0ea968dc035798492ef4ef97"); for ( Map.Entry entry : expectations.entrySet() ) { String extraArgs2 = entry.getKey(); @@ -60,7 +60,7 @@ public class VariantEval2IntegrationTest extends WalkerTest { String extraArgs = "-L 1:1-10,000,000 -family NA19238+NA19239=NA19240 -MVQ 30"; WalkerTestSpec spec = new WalkerTestSpec( root + " " + extraArgs + " -o %s -outputVCF %s", 2, - Arrays.asList("31f8cf5010d4b73b1520acef88207214", "a3ce1d70d8ae3874807e9d61994d42af")); + Arrays.asList("3d4de331f90ef49792d3da3ee9509edc", "a3ce1d70d8ae3874807e9d61994d42af")); executeTest("testVE2WriteVCF", spec); } } diff --git a/java/test/org/broadinstitute/sting/playground/utils/report/ReportMarshallerTest.java b/java/test/org/broadinstitute/sting/playground/utils/report/ReportMarshallerTest.java index 0e83c65ca..4bc9bef17 100644 --- a/java/test/org/broadinstitute/sting/playground/utils/report/ReportMarshallerTest.java +++ b/java/test/org/broadinstitute/sting/playground/utils/report/ReportMarshallerTest.java @@ -46,7 +46,7 @@ public class ReportMarshallerTest extends BaseTest { cfg.setObjectWrapper(new DefaultObjectWrapper()); Template temp = null; try { - temp = cfg.getTemplate("myTestTemp.ftl"); + temp = cfg.createMarhsaller("myTestTemp.ftl"); } catch (IOException e) { e.printStackTrace(); }