Allow users to directly specify filters from the command-line, applicable to

any walker.


git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@2012 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
hanna 2009-11-10 18:40:16 +00:00
parent 6a37090529
commit 2cf9670d1e
6 changed files with 183 additions and 82 deletions

View File

@ -123,7 +123,7 @@ public abstract class CommandLineExecutable extends CommandLineProgram {
@Override
protected String getArgumentSourceName( Class argumentSource ) {
return WalkerManager.getWalkerName((Class<Walker>) argumentSource);
return GATKEngine.getWalkerName((Class<Walker>)argumentSource);
}
/**

View File

@ -56,6 +56,10 @@ public class GATKArgumentCollection {
@Argument(fullName = "input_file", shortName = "I", doc = "SAM or BAM file(s)", required = false)
public List<File> samFiles = new ArrayList<File>();
@ElementList(required = false)
@Argument(fullName = "read_filters", shortName = "rf", doc = "Specify filtration criteria on the each read.", required=false)
public List<String> readFilters = new ArrayList<String>();
@ElementList(required = false)
@Argument(fullName = "intervals", shortName = "L", doc = "A list of genomic intervals over which to operate. Can be explicitly specified on the command line or in a file.", required = false)
public List<String> intervals = null;

View File

@ -40,6 +40,7 @@ import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedData;
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedDatum;
import org.broadinstitute.sting.gatk.walkers.*;
import org.broadinstitute.sting.gatk.filters.ZeroMappingQualityReadFilter;
import org.broadinstitute.sting.gatk.filters.FilterManager;
import org.broadinstitute.sting.gatk.io.OutputTracker;
import org.broadinstitute.sting.utils.*;
import org.broadinstitute.sting.utils.bed.BedParser;
@ -97,6 +98,11 @@ public class GenomeAnalysisEngine {
*/
private final WalkerManager walkerManager;
/**
* Manage lists of filters.
*/
private final FilterManager filterManager;
/**
* our constructor, where all the work is done
* <p/>
@ -107,6 +113,7 @@ public class GenomeAnalysisEngine {
// make sure our instance variable points to this analysis engine
instance = this;
walkerManager = new WalkerManager();
filterManager = new FilterManager();
}
/**
@ -184,7 +191,16 @@ public class GenomeAnalysisEngine {
* @return An instance of the walker.
*/
public Walker<?, ?> getWalkerByName(String walkerName) {
return walkerManager.createWalkerByName(walkerName);
return walkerManager.createByName(walkerName);
}
/**
* Gets the name of a given walker type.
* @param walkerType Type of walker.
* @return Name of the walker.
*/
public String getWalkerName(Class<Walker> walkerType) {
return walkerManager.getName(walkerType);
}
private void initializeDataSources(Walker my_walker, GATKArgumentCollection argCollection) {
@ -240,7 +256,7 @@ public class GenomeAnalysisEngine {
Utils.scareUser(String.format("Read-based traversals require a reference file but none was given"));
microScheduler = MicroScheduler.create(my_walker, readsDataSource, referenceDataSource, rodDataSources, argCollection.numberOfThreads);
} else {
Utils.scareUser(String.format("Unable to create the appropriate TraversalEngine for analysis type %s", WalkerManager.getWalkerName(my_walker.getClass())));
Utils.scareUser(String.format("Unable to create the appropriate TraversalEngine for analysis type %s", walkerManager.getName(my_walker.getClass())));
}
return microScheduler;
@ -377,9 +393,11 @@ public class GenomeAnalysisEngine {
private Reads extractSourceInfo(Walker walker, GATKArgumentCollection argCollection) {
List<SamRecordFilter> filters = new ArrayList<SamRecordFilter>();
filters.addAll(WalkerManager.getReadFilters(walker));
filters.addAll(WalkerManager.getReadFilters(walker,filterManager));
if (argCollection.filterZeroMappingQualityReads != null && argCollection.filterZeroMappingQualityReads)
filters.add(new ZeroMappingQualityReadFilter());
for(String filterName: argCollection.readFilters)
filters.add(filterManager.createByName(filterName));
return new Reads(argCollection.samFiles,
argCollection.strictnessLevel,

View File

@ -30,8 +30,9 @@ import java.util.*;
import org.broadinstitute.sting.gatk.walkers.*;
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedDatum;
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedData;
import org.broadinstitute.sting.gatk.filters.FilterManager;
import org.broadinstitute.sting.utils.StingException;
import org.broadinstitute.sting.utils.PackageUtils;
import org.broadinstitute.sting.utils.PluginManager;
import org.apache.log4j.Logger;
import net.sf.picard.filter.SamRecordFilter;
@ -42,49 +43,15 @@ import net.sf.picard.filter.SamRecordFilter;
* Time: 3:14:28 PM
* To change this template use File | Settings | File Templates.
*/
public class WalkerManager {
public class WalkerManager extends PluginManager<Walker> {
/**
* our log, which we want to capture anything from this class
*/
private static Logger logger = Logger.getLogger(WalkerManager.class);
private Map<String, Class<? extends Walker>> walkersByName;
public WalkerManager() {
List<Class<? extends Walker>> walkers = PackageUtils.getClassesImplementingInterface(Walker.class);
walkersByName = createWalkerDatabase(walkers);
}
/**
* Does a walker with the given name exist?
*
* @param walkerName Name of the walker for which to search.
* @return True if the walker exists, false otherwise.
*/
public boolean doesWalkerExist(String walkerName) {
return walkersByName.containsKey(walkerName);
}
/**
* Gets a walker with the given name, or null if no walker exists.
*
* @param walkerName Name of the walker to retrieve.
* @return The walker object if found; null otherwise.
*/
public Walker createWalkerByName(String walkerName) {
try {
Class<? extends Walker> walker = walkersByName.get(walkerName);
if( walker == null )
throw new StingException(String.format("Could not find walker with name: %s", walkerName));
return walker.newInstance();
}
catch( InstantiationException ex ) {
throw new StingException("Unable to instantiate walker " + walkerName, ex);
}
catch( IllegalAccessException ex ) {
throw new StingException("Unable to access walker " + walkerName, ex);
}
super(Walker.class,"walker","Walker");
}
/**
@ -92,7 +59,7 @@ public class WalkerManager {
* @return Names of currently available walkers.
*/
public Set<String> getWalkerNames() {
return Collections.unmodifiableSet( walkersByName.keySet() );
return Collections.unmodifiableSet( pluginsByName.keySet() );
}
/**
@ -101,7 +68,7 @@ public class WalkerManager {
* @return Class representing the walker.
*/
public Class getWalkerClassByName(String walkerName) {
return walkersByName.get(walkerName);
return pluginsByName.get(walkerName);
}
/**
@ -185,61 +152,30 @@ public class WalkerManager {
/**
* Extracts filters that the walker has requested be run on the dataset.
* @param walker Walker to inspect for filtering requests.
* @param filterManager Manages the creation of filters.
* @return A non-empty list of filters to apply to the reads.
*/
public static List<SamRecordFilter> getReadFilters(Walker walker) {
Class<? extends SamRecordFilter>[] filterTypes = getReadFilterTypes(walker);
public static List<SamRecordFilter> getReadFilters(Walker walker, FilterManager filterManager) {
List<SamRecordFilter> filters = new ArrayList<SamRecordFilter>();
for( Class<? extends SamRecordFilter> filterType: filterTypes ) {
try {
filters.add(filterType.newInstance());
}
catch( InstantiationException ex ) {
throw new StingException("Unable to instantiate filter: " + filterType, ex);
}
catch( IllegalAccessException ex ) {
throw new StingException("Unable to access filter: " + filterType, ex);
}
}
for(Class<? extends SamRecordFilter> filterType: getReadFilterTypes(walker))
filters.add(filterManager.createFilterByType(filterType));
return filters;
}
/**
* Instantiate the list of walker classes. Add them to the walker hashmap.
*
* @param walkerClasses Classes to instantiate.
* @return map of walker name to walker.
*/
private Map<String, Class<? extends Walker>> createWalkerDatabase(List<Class<? extends Walker>> walkerClasses) {
Map<String, Class<? extends Walker>> walkers = new HashMap<String, Class<? extends Walker>>();
for (Class<? extends Walker> walkerClass : walkerClasses) {
String walkerName = getWalkerName(walkerClass);
walkers.put(walkerName, walkerClass);
}
return walkers;
}
/**
* Create a name for this type of walker.
*
* @param walkerType The type of walker.
* @return A name for this type of walker.
*/
public static String getWalkerName(Class<? extends Walker> walkerType) {
@Override
public String getName(Class<? extends Walker> walkerType) {
String walkerName = "";
if (walkerType.getAnnotation(WalkerName.class) != null)
walkerName = walkerType.getAnnotation(WalkerName.class).value().trim();
if (walkerName.length() == 0) {
walkerName = walkerType.getSimpleName();
if (walkerName.endsWith("Walker"))
walkerName = walkerName.substring(0, walkerName.lastIndexOf("Walker"));
}
else
walkerName = super.getName(walkerType);
return walkerName;
}

View File

@ -0,0 +1,34 @@
package org.broadinstitute.sting.gatk.filters;
import org.apache.log4j.Logger;
import org.broadinstitute.sting.utils.PluginManager;
import net.sf.picard.filter.SamRecordFilter;
/**
* Manage filters and filter options. Any requests for basic filtering classes
* should ultimately be made through this class.
*
* @author mhanna
* @version 0.1
*/
public class FilterManager extends PluginManager<SamRecordFilter> {
/**
* our log, which we want to capture anything from this class
*/
private static Logger logger = Logger.getLogger(FilterManager.class);
public FilterManager() {
super(SamRecordFilter.class,"filter","Filter");
}
/**
* Instantiate a filter of the given type. Along the way, scream bloody murder if
* the filter is not available.
* @param filterType
* @return
*/
public SamRecordFilter createFilterByType(Class<? extends SamRecordFilter> filterType) {
return this.createByName(getName(filterType));
}
}

View File

@ -0,0 +1,109 @@
package org.broadinstitute.sting.utils;
import java.util.Map;
import java.util.List;
import java.util.HashMap;
/**
* Manage plugins and plugin configuration.
* @author mhanna
* @version 0.1
*/
public abstract class PluginManager<PluginType> {
/**
* Defines the category of plugin defined by the subclass.
*/
protected final String pluginCategory;
/**
* Define common strings to trim off the end of the name.
*/
protected final String pluginSuffix;
/**
* Plugins stored based on their name.
*/
protected final Map<String, Class<? extends PluginType>> pluginsByName;
/**
* Create a new plugin manager.
* @param pluginType Core type for a plugin.
* @param pluginCategory Provides a category name to the plugin. Must not be null.
* @param pluginSuffix Provides a suffix that will be trimmed off when converting to a plugin name. Can be null.
*/
protected PluginManager(Class<PluginType> pluginType, String pluginCategory, String pluginSuffix) {
this.pluginCategory = pluginCategory;
this.pluginSuffix = pluginSuffix;
List<Class<? extends PluginType>> plugins = PackageUtils.getClassesImplementingInterface(pluginType);
pluginsByName = createPluginDatabase(plugins);
}
/**
* Does a plugin with the given name exist?
*
* @param pluginName Name of the plugin for which to search.
* @return True if the plugin exists, false otherwise.
*/
public boolean exists(String pluginName) {
return pluginsByName.containsKey(pluginName);
}
/**
* Gets a plugin with the given name, or null if no plugin exists.
*
* @param pluginName Name of the plugin to retrieve.
* @return The plugin object if found; null otherwise.
*/
public PluginType createByName(String pluginName) {
try {
Class<? extends PluginType> plugin = pluginsByName.get(pluginName);
if( plugin == null )
throw new StingException(String.format("Could not find %s with name: %s", pluginCategory,pluginName));
return plugin.newInstance();
}
catch( InstantiationException ex ) {
throw new StingException(String.format("Unable to instantiate %s %s",pluginCategory,pluginName), ex);
}
catch( IllegalAccessException ex ) {
throw new StingException(String.format("Unable to access %s %s",pluginCategory,pluginName), ex);
}
}
/**
* Create the list of available plugins and add them to the database.
*
* @param pluginClasses Classes to record.
* @return map of plugin name -> plugin.
*/
private Map<String, Class<? extends PluginType>> createPluginDatabase(List<Class<? extends PluginType>> pluginClasses) {
Map<String, Class<? extends PluginType>> plugins = new HashMap<String, Class<? extends PluginType>>();
for (Class<? extends PluginType> pluginClass : pluginClasses) {
String pluginName = getName(pluginClass);
plugins.put(pluginName, pluginClass);
}
return plugins;
}
/**
* Create a name for this type of plugin.
*
* @param pluginType The type of plugin.
* @return A name for this type of plugin.
*/
public String getName(Class<? extends PluginType> pluginType) {
String pluginName = "";
if (pluginName.length() == 0) {
pluginName = pluginType.getSimpleName();
if (pluginSuffix != null && pluginName.endsWith(pluginSuffix))
pluginName = pluginName.substring(0, pluginName.lastIndexOf(pluginSuffix));
}
return pluginName;
}
}