First pass at a reorganized walker info display. Groups walkers by package

and displays walker data extracted from the JavaDoc.  Needs a bit of help,
both in content and flexibility of package naming.


git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@2267 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
hanna 2009-12-04 23:24:29 +00:00
parent 07b88621c5
commit b04de77952
6 changed files with 179 additions and 70 deletions

View File

@ -1,7 +1,9 @@
package org.broadinstitute.sting.gatk;
import org.broadinstitute.sting.utils.GATKErrorReport;
import org.broadinstitute.sting.utils.TextFormattingUtils;
import org.broadinstitute.sting.utils.cmdLine.*;
import org.broadinstitute.sting.gatk.walkers.Walker;
import java.io.PrintStream;
import java.util.*;
@ -112,38 +114,73 @@ public class CommandLineGATK extends CommandLineExecutable {
* @return A string summarizing the walkers available in this distribution.
*/
private String getAdditionalHelp() {
// Get the list of walker names from the walker manager.
Set<String> walkerNames = GATKEngine.getWalkerNames();
// Sort the list of walker names.
walkerNames = new TreeSet<String>(walkerNames);
//HelpFormatter.LINE_WIDTH;
// Construct a help string to output available walkers.
final int PACKAGE_INDENT = 1;
final int WALKER_INDENT = 3;
final String FIELD_SEPARATOR = " | ";
// Construct a help string to output available walkers.
StringBuilder additionalHelp = new StringBuilder();
Formatter formatter = new Formatter(additionalHelp);
formatter.format("Available analyses:%n");
formatter.format("Available analyses:%n%n");
// Compute the max size of any walker name
int maxNameLength = 0;
for (String walkerName : walkerNames) {
if (maxNameLength < walkerName.length())
maxNameLength = walkerName.length();
// Get the list of walker names from the walker manager.
WalkerManager walkerManager = GATKEngine.getWalkerManager();
Map<String,Collection<Class<? extends Walker>>> walkers = walkerManager.getWalkerNamesByPackage();
int longestPackageName = 0;
int longestWalkerName = 0;
for(Map.Entry<String,Collection<Class<? extends Walker>>> walkersByPackage: walkers.entrySet()) {
longestPackageName = Math.max(longestPackageName,walkerManager.getPackageDisplayName(walkersByPackage.getKey()).length());
for(Class<? extends Walker> walkerType: walkersByPackage.getValue())
longestWalkerName = Math.max(longestWalkerName,walkerManager.getName(walkerType).length());
}
final int fieldWidth = maxNameLength + HelpFormatter.FIELD_SEPARATION_WIDTH;
final int walkersPerLine = Math.min(HelpFormatter.LINE_WIDTH / fieldWidth, 4);
final int columnSpacing = Math.max((HelpFormatter.LINE_WIDTH - (fieldWidth * walkersPerLine)) / walkersPerLine, 1);
final int headerWidth = Math.max(longestPackageName+PACKAGE_INDENT,longestWalkerName+WALKER_INDENT);
int currentWalkerName = 0;
for (String walkerName : walkerNames) {
formatter.format("%-" + HelpFormatter.FIELD_SEPARATION_WIDTH + "s" +
"%-" + fieldWidth + "s" +
"%-" + columnSpacing + "s", "", walkerName, "");
if (++currentWalkerName % walkersPerLine == 0)
formatter.format("%n");
// Sort the list of walker names.
walkers = new TreeMap<String,Collection<Class<? extends Walker>>>(walkers);
for(String packageName: walkers.keySet()) {
String packageDisplayName = walkerManager.getPackageDisplayName(packageName);
String packageHelpText = walkerManager.getPackageHelpText(packageName);
printDescriptorLine(formatter,PACKAGE_INDENT,packageDisplayName,headerWidth,FIELD_SEPARATOR,packageHelpText, TextFormattingUtils.DEFAULT_LINE_WIDTH);
for(Class<? extends Walker> walkerType: walkers.get(packageName)) {
String walkerName = walkerManager.getName(walkerType);
String walkerHelpText = walkerManager.getWalkerHelpText(walkerType);
printDescriptorLine(formatter,WALKER_INDENT,walkerName,headerWidth,FIELD_SEPARATOR,walkerHelpText, TextFormattingUtils.DEFAULT_LINE_WIDTH);
}
// Print a blank line between sets of walkers.
printDescriptorLine(formatter,0,"",headerWidth,FIELD_SEPARATOR,"", TextFormattingUtils.DEFAULT_LINE_WIDTH);
}
return additionalHelp.toString();
}
private void printDescriptorLine(Formatter formatter,
int headerIndentWidth,
String header,
int headerWidth,
String fieldSeparator,
String description,
int lineWidth) {
final int headerPaddingWidth = headerWidth - header.length() - headerIndentWidth;
final int descriptionWidth = lineWidth - fieldSeparator.length() - headerWidth;
List<String> wordWrappedText = TextFormattingUtils.wordWrap(description,descriptionWidth);
String headerIndentFormatString = headerIndentWidth > 0 ? "%" + headerIndentWidth + "s" : "%s";
String headerPaddingFormatString = headerPaddingWidth > 0 ? "%" + headerPaddingWidth + "s" : "%s";
String headerWidthFormatString = headerWidth > 0 ? "%" + headerWidth + "s" : "%s";
// Output description line.
formatter.format(headerIndentFormatString + "%s" + headerPaddingFormatString + "%s%s%n",
"", header, "", fieldSeparator, wordWrappedText.size()>0?wordWrappedText.get(0):"");
for(int i = 1; i < wordWrappedText.size(); i++)
formatter.format(headerWidthFormatString + "%s%s%n", "", fieldSeparator, wordWrappedText.get(i));
}
}

View File

@ -175,15 +175,6 @@ public class GenomeAnalysisEngine {
outputs.add(stub);
}
/**
* Gets a set of the names of all walkers that the GATK has discovered.
*
* @return A set of the names of all discovered walkers.
*/
public Set<String> getWalkerNames() {
return walkerManager.getWalkerNames();
}
/**
* Retrieves an instance of the walker based on the walker name.
*
@ -219,6 +210,14 @@ public class GenomeAnalysisEngine {
return Collections.unmodifiableSet(filters);
}
/**
* Allow subclasses and others within this package direct access to the walker manager.
* @return The walker manager used by this package.
*/
protected WalkerManager getWalkerManager() {
return walkerManager;
}
private void initializeDataSources(Walker my_walker, Collection<SamRecordFilter> filters, GATKArgumentCollection argCollection) {
validateSuppliedReadsAgainstWalker(my_walker, argCollection);
logger.info("Strictness is " + argCollection.strictnessLevel);

View File

@ -26,6 +26,8 @@
package org.broadinstitute.sting.gatk;
import java.util.*;
import java.io.InputStream;
import java.io.IOException;
import org.broadinstitute.sting.gatk.walkers.*;
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedDatum;
@ -50,16 +52,70 @@ public class WalkerManager extends PluginManager<Walker> {
*/
private static Logger logger = Logger.getLogger(WalkerManager.class);
/**
* A collection of help text for walkers and their enclosing packages.
*/
private Properties helpText = new Properties();
public WalkerManager() {
super(Walker.class,"walker","Walker");
InputStream helpSourceFile = getClass().getClassLoader().getResourceAsStream("help.properties");
if(helpSourceFile != null) {
try {
helpText.load(helpSourceFile);
}
catch(IOException ex) {
throw new StingException("Unable to process help data");
}
}
}
/**
* Get the list of walkers currently available to the GATK.
* Get the list of walkers currently available to the GATK, organized
* by package.
* @return Names of currently available walkers.
*/
public Set<String> getWalkerNames() {
return Collections.unmodifiableSet( pluginsByName.keySet() );
public Map<String,Collection<Class<? extends Walker>>> getWalkerNamesByPackage() {
Map<String,Collection<Class<? extends Walker>>> walkersByPackage = new HashMap<String,Collection<Class<? extends Walker>>>();
for(Class<? extends Walker> walker: pluginsByName.values()) {
String walkerPackage = walker.getPackage().getName();
if(!walkersByPackage.containsKey(walkerPackage))
walkersByPackage.put(walkerPackage,new ArrayList<Class<? extends Walker>>());
walkersByPackage.get(walkerPackage).add(walker);
}
return Collections.unmodifiableMap(walkersByPackage);
}
/**
* Gets the display name for a given package.
* @param packageName Fully qualified package name.
* @return A suitable display name for the package.
*/
public String getPackageDisplayName(String packageName) {
return packageName.substring(packageName.lastIndexOf('.')+1);
}
/**
* Gets the help text associated with a given package name.
* @param packageName Package for which to search for help text.
* @return Package help text, or "" if none exists.
*/
public String getPackageHelpText(String packageName) {
if(!helpText.containsKey(packageName))
return "";
return helpText.getProperty(packageName);
}
/**
* Gets the help text associated with a given walker type.
* @param walkerType Type of walker for which to search for help text.
* @return Package help text, or "" if none exists.
*/
public String getWalkerHelpText(Class<? extends Walker> walkerType) {
String walkerName = walkerType.getName();
if(!helpText.containsKey(walkerName))
return "";
return helpText.getProperty(walkerName);
}
/**

View File

@ -0,0 +1,43 @@
package org.broadinstitute.sting.utils;
import java.util.List;
import java.util.ArrayList;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* Common utilities for dealing with strings.
*
* @author mhanna
* @version 0.1
*/
public class TextFormattingUtils {
/**
* The default line width, for GATK output written to the screen.
*/
public static final int DEFAULT_LINE_WIDTH = 100;
/**
* Simple implementation of word-wrap for a line of text. Idea and
* regexp shamelessly stolen from http://joust.kano.net/weblog/archives/000060.html.
* Regexp can probably be simplified for our application.
* @param text Text to wrap.
* @param width Maximum line width.
* @return A list of word-wrapped lines.
*/
public static List<String> wordWrap( String text, int width ) {
Pattern wrapper = Pattern.compile( String.format(".{0,%d}(?:\\S(?: |$)|$)", width-1) );
Matcher matcher = wrapper.matcher( text );
List<String> wrapped = new ArrayList<String>();
while( matcher.find() ) {
// Regular expression is supersensitive to whitespace.
// Assert that content is present before adding the line.
String line = matcher.group().trim();
if( line.length() > 0 )
wrapped.add( matcher.group() );
}
return wrapped;
}
}

View File

@ -1,5 +1,7 @@
package org.broadinstitute.sting.utils.cmdLine;
import org.broadinstitute.sting.utils.TextFormattingUtils;
import java.util.Formatter;
import java.util.List;
import java.util.ArrayList;
@ -7,8 +9,6 @@ import java.util.Iterator;
import java.util.Comparator;
import java.util.Collection;
import java.util.Collections;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* User: hanna
* Date: May 6, 2009
@ -27,10 +27,6 @@ import java.util.regex.Matcher;
*/
public class HelpFormatter {
/**
* Target this line width.
*/
public static final int LINE_WIDTH = 100;
public static final int FIELD_SEPARATION_WIDTH = 3;
/**
@ -76,7 +72,7 @@ public class HelpFormatter {
}
// Word wrap the synopsis.
List<String> wrappedSynopsis = wordWrap( lineBuilder.toString(), LINE_WIDTH );
List<String> wrappedSynopsis = TextFormattingUtils.wordWrap( lineBuilder.toString(), TextFormattingUtils.DEFAULT_LINE_WIDTH );
String header = "usage: ";
int headerLength = header.length();
@ -119,12 +115,12 @@ public class HelpFormatter {
// Try to fit the entire argument definition across the screen, but impose an arbitrary cap of 3/4 *
// LINE_WIDTH in case the length of the arguments gets out of control.
int argWidth = Math.min( findLongestArgumentCallingInfo(argumentDefinitions), (LINE_WIDTH*3)/4 - FIELD_SEPARATION_WIDTH );
int docWidth = LINE_WIDTH - argWidth - FIELD_SEPARATION_WIDTH;
int argWidth = Math.min( findLongestArgumentCallingInfo(argumentDefinitions), (TextFormattingUtils.DEFAULT_LINE_WIDTH*3)/4 - FIELD_SEPARATION_WIDTH );
int docWidth = TextFormattingUtils.DEFAULT_LINE_WIDTH - argWidth - FIELD_SEPARATION_WIDTH;
for( ArgumentDefinition argumentDefinition: argumentDefinitions ) {
Iterator<String> wordWrappedArgs = wordWrap( getArgumentCallingInfo(argumentDefinition), argWidth ).iterator();
Iterator<String> wordWrappedDoc = wordWrap( argumentDefinition.doc, docWidth ).iterator();
Iterator<String> wordWrappedArgs = TextFormattingUtils.wordWrap( getArgumentCallingInfo(argumentDefinition), argWidth ).iterator();
Iterator<String> wordWrappedDoc = TextFormattingUtils.wordWrap( argumentDefinition.doc, docWidth ).iterator();
while( wordWrappedArgs.hasNext() || wordWrappedDoc.hasNext() ) {
String arg = wordWrappedArgs.hasNext() ? wordWrappedArgs.next() : "";
@ -173,29 +169,6 @@ public class HelpFormatter {
return longest;
}
/**
* Simple implementation of word-wrap for a line of text. Idea and
* regexp shamelessly stolen from http://joust.kano.net/weblog/archives/000060.html.
* Regexp can probably be simplified for our application.
* @param text Text to wrap.
* @param width Maximum line width.
* @return A list of word-wrapped lines.
*/
private List<String> wordWrap( String text, int width ) {
Pattern wrapper = Pattern.compile( String.format(".{0,%d}(?:\\S(?: |$)|$)", width-1) );
Matcher matcher = wrapper.matcher( text );
List<String> wrapped = new ArrayList<String>();
while( matcher.find() ) {
// Regular expression is supersensitive to whitespace.
// Assert that content is present before adding the line.
String line = matcher.group().trim();
if( line.length() > 0 )
wrapped.add( matcher.group() );
}
return wrapped;
}
/**
* Extract the argument definition groups from the argument definitions and arrange them appropriately.
* For help, we want the arguments sorted as they are declared in the class. However, required arguments

View File

@ -22,6 +22,7 @@ public class HelpExtractorDoclet {
* Extracts the contents of certain types of javadoc and adds them to an XML file.
* @param rootDoc The documentation root.
* @return Whether the JavaDoc run succeeded.
* @throws FileNotFoundException if output can't be written.
*/
public static boolean start(RootDoc rootDoc) throws FileNotFoundException {
PrintStream out = System.out;
@ -56,9 +57,9 @@ public class HelpExtractorDoclet {
}
/**
* Validate the given options against
* @param option
* @return
* Validate the given options against options supported by this doclet.
* @param option Option to validate.
* @return Number of potential parameters; 0 if not supported.
*/
public static int optionLength(String option) {
if(option.equals("-out")) {