Switched our code over to the new command line style (gnu style args), added the initial logger code, and added apache commons CLI to the IVY script.
There will be a slow conversion of all the System.out and System.err in other files to the logger style output. git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@145 348d0f76-0448-11de-a6fe-93d51630548a
This commit is contained in:
parent
38f18c8679
commit
046cecb067
|
|
@ -1,133 +1,151 @@
|
||||||
package org.broadinstitute.sting.gatk;
|
package org.broadinstitute.sting.gatk;
|
||||||
|
|
||||||
|
import edu.mit.broad.picard.reference.ReferenceSequence;
|
||||||
|
import edu.mit.broad.picard.reference.ReferenceSequenceFile;
|
||||||
|
import edu.mit.broad.picard.reference.ReferenceSequenceFileFactory;
|
||||||
import net.sf.samtools.SAMFileReader.ValidationStringency;
|
import net.sf.samtools.SAMFileReader.ValidationStringency;
|
||||||
import net.sf.samtools.SAMSequenceRecord;
|
import net.sf.samtools.SAMSequenceRecord;
|
||||||
import net.sf.samtools.util.RuntimeIOException;
|
import net.sf.samtools.util.RuntimeIOException;
|
||||||
import edu.mit.broad.picard.cmdline.CommandLineProgram;
|
import org.apache.log4j.Logger;
|
||||||
import edu.mit.broad.picard.cmdline.Usage;
|
|
||||||
import edu.mit.broad.picard.cmdline.Option;
|
|
||||||
import edu.mit.broad.picard.reference.ReferenceSequenceFileFactory;
|
|
||||||
import edu.mit.broad.picard.reference.ReferenceSequenceFile;
|
|
||||||
import edu.mit.broad.picard.reference.ReferenceSequence;
|
|
||||||
|
|
||||||
import org.broadinstitute.sting.utils.*;
|
|
||||||
import org.broadinstitute.sting.gatk.walkers.*;
|
|
||||||
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedData;
|
import org.broadinstitute.sting.gatk.refdata.ReferenceOrderedData;
|
||||||
import org.broadinstitute.sting.gatk.refdata.rodDbSNP;
|
import org.broadinstitute.sting.gatk.refdata.rodDbSNP;
|
||||||
import org.broadinstitute.sting.gatk.refdata.rodGFF;
|
import org.broadinstitute.sting.gatk.refdata.rodGFF;
|
||||||
import org.broadinstitute.sting.gatk.iterators.ReferenceIterator;
|
import org.broadinstitute.sting.gatk.walkers.LocusWalker;
|
||||||
import org.broadinstitute.sting.utils.Utils;
|
import org.broadinstitute.sting.gatk.walkers.ReadWalker;
|
||||||
import org.broadinstitute.sting.utils.FastaSequenceFile2;
|
import org.broadinstitute.sting.utils.FastaSequenceFile2;
|
||||||
|
import org.broadinstitute.sting.utils.GenomeLoc;
|
||||||
|
import org.broadinstitute.sting.utils.Utils;
|
||||||
|
import org.broadinstitute.sting.utils.cmdLine.CommandLineProgram;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.File;
|
||||||
import java.util.*;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Random;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class GenomeAnalysisTK extends CommandLineProgram {
|
public class GenomeAnalysisTK extends CommandLineProgram {
|
||||||
// Usage and parameters
|
|
||||||
@Usage(programVersion="0.1") public String USAGE = "Genome Analysis Toolkit\n";
|
|
||||||
@Option(shortName="I", doc="SAM or BAM file for validation") public File INPUT_FILE;
|
|
||||||
@Option(shortName="M", doc="Maximum number of reads to process before exiting", optional=true) public String MAX_READS_ARG = "-1";
|
|
||||||
@Option(shortName="S", doc="How strict should we be with validation", optional=true) public String STRICTNESS_ARG = "strict";
|
|
||||||
@Option(shortName="R", doc="Reference sequence file", optional=true) public File REF_FILE_ARG = null;
|
|
||||||
@Option(shortName="B", doc="Debugging output", optional=true) public String DEBUGGING_STR = null;
|
|
||||||
@Option(shortName="L", doc="Genome region to operation on: from chr:start-end", optional=true) public String REGION_STR = null;
|
|
||||||
|
|
||||||
@Option(shortName="INT", doc="File containing list of genomic intervals to operate on. line := <contig> <start> <end>\n", optional=true) public String INTERVALS_FILE = null;
|
|
||||||
|
|
||||||
@Option(shortName="T", doc="Type of analysis to run") public String Analysis_Name = null;
|
// parameters and their defaults
|
||||||
@Option(shortName="DBSNP", doc="DBSNP file", optional=true) public String DBSNP_FILE = null;
|
public File INPUT_FILE;
|
||||||
@Option(shortName="THREADED_IO", doc="If true, enables threaded I/O operations", optional=true) public String ENABLED_THREADED_IO = "false";
|
public String MAX_READS_ARG = "-1";
|
||||||
@Option(shortName="U", doc="If true, enables unsafe operations, nothing will be checked at runtime. You better know what you are doing if you set this flag.", optional=false) public String UNSAFE = "false";
|
public String STRICTNESS_ARG = "strict";
|
||||||
@Option(shortName="SORT_ON_FLY", doc="If true, enables on fly sorting of reads file.", optional=false) public String ENABLED_SORT_ON_FLY = "false";
|
public File REF_FILE_ARG = null;
|
||||||
|
public String DEBUGGING_STR = null;
|
||||||
@Option(shortName="PLUGINS", doc="Directory where plugin class files live.", optional=true)
|
public String REGION_STR = null;
|
||||||
public String pluginPathName = null;
|
public String Analysis_Name = null;
|
||||||
|
public String DBSNP_FILE = null;
|
||||||
|
public Boolean ENABLED_THREADED_IO = false;
|
||||||
|
public Boolean UNSAFE = false;
|
||||||
|
public Boolean ENABLED_SORT_ON_FLY = false;
|
||||||
|
public String INTERVALS_FILE = null;
|
||||||
|
|
||||||
|
// our walker manager
|
||||||
private WalkerManager walkerManager = null;
|
private WalkerManager walkerManager = null;
|
||||||
|
|
||||||
|
public String pluginPathName = null;
|
||||||
private TraversalEngine engine = null;
|
private TraversalEngine engine = null;
|
||||||
public boolean DEBUGGING = false;
|
public boolean DEBUGGING = false;
|
||||||
|
|
||||||
/** Required main method implementation. */
|
|
||||||
public static void main(String[] argv) {
|
/**
|
||||||
System.exit(new GenomeAnalysisTK().instanceMain(argv));
|
* our log, which we want to capture anything from this class
|
||||||
|
*/
|
||||||
|
private static Logger logger = Logger.getLogger(GenomeAnalysisTK.class);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setup our arguments, both required and optional
|
||||||
|
* <p/>
|
||||||
|
* Flags don't take an argument, the associated Boolean gets set to true if the flag appears on the command line.
|
||||||
|
*/
|
||||||
|
protected void setupArgs() {
|
||||||
|
m_parser.addRequiredlArg("input_file", "I", "SAM or BAM file for validation", "INPUT_FILE");
|
||||||
|
m_parser.addOptionalArg("maximum_reads", "M", "Maximum number of reads to process before exiting", "MAX_READS_ARG");
|
||||||
|
m_parser.addOptionalArg("validation_strictness", "S", "How strict should we be with validation", "STRICTNESS_ARG");
|
||||||
|
m_parser.addOptionalArg("reference_sequence", "R", "Reference sequence file", "REF_FILE_ARG");
|
||||||
|
m_parser.addOptionalArg("genome_region", "L", "Genome region to operation on: from chr:start-end", "REGION_STR");
|
||||||
|
m_parser.addRequiredlArg("analysis_type", "T", "Type of analysis to run", "Analysis_Name");
|
||||||
|
m_parser.addOptionalArg("DBSNP", "D", "DBSNP file", "DBSNP_FILE");
|
||||||
|
m_parser.addOptionalFlag("Threaded_IO", "P", "If set, enables threaded I/O operations", "ENABLED_THREADED_IO");
|
||||||
|
m_parser.addOptionalFlag("Unsafe", "U", "If set, enables unsafe operations, nothing will be checked at runtime.", "UNSAFE");
|
||||||
|
m_parser.addOptionalFlag("Sort_on_the_fly", "F", "If set, enables on fly sorting of reads file.", "ENABLED_SORT_ON_FLY");
|
||||||
|
m_parser.addOptionalArg("intervals_file", "V", "File containing list of genomic intervals to operate on. line := <contig> <start> <end>", "INTERVALS_FILE");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int doWork() {
|
/**
|
||||||
walkerManager = new WalkerManager(pluginPathName);
|
* Required main method implementation.
|
||||||
|
*/
|
||||||
|
public static void main(String[] argv) {
|
||||||
|
start(new GenomeAnalysisTK(), argv);
|
||||||
|
}
|
||||||
|
|
||||||
//testNewReferenceFeatures(REF_FILE_ARG);
|
protected int execute() {
|
||||||
|
|
||||||
|
|
||||||
|
walkerManager = new WalkerManager(pluginPathName);
|
||||||
|
|
||||||
final boolean TEST_ROD = false;
|
final boolean TEST_ROD = false;
|
||||||
ReferenceOrderedData[] rods = null;
|
ReferenceOrderedData[] rods = null;
|
||||||
|
|
||||||
if ( TEST_ROD ) {
|
if (TEST_ROD) {
|
||||||
ReferenceOrderedData gff = new ReferenceOrderedData(new File("trunk/data/gFFTest.gff"), rodGFF.class );
|
ReferenceOrderedData gff = new ReferenceOrderedData(new File("trunk/data/gFFTest.gff"), rodGFF.class);
|
||||||
gff.testMe();
|
gff.testMe();
|
||||||
|
|
||||||
//ReferenceOrderedData dbsnp = new ReferenceOrderedData(new File("trunk/data/dbSNP_head.txt"), rodDbSNP.class );
|
//ReferenceOrderedData dbsnp = new ReferenceOrderedData(new File("trunk/data/dbSNP_head.txt"), rodDbSNP.class );
|
||||||
ReferenceOrderedData dbsnp = new ReferenceOrderedData(new File("/Volumes/Users/mdepristo/broad/ATK/exampleSAMs/dbSNP_chr20.txt"), rodDbSNP.class );
|
ReferenceOrderedData dbsnp = new ReferenceOrderedData(new File("/Volumes/Users/mdepristo/broad/ATK/exampleSAMs/dbSNP_chr20.txt"), rodDbSNP.class);
|
||||||
//dbsnp.testMe();
|
//dbsnp.testMe();
|
||||||
rods = new ReferenceOrderedData[] { dbsnp }; // { gff, dbsnp };
|
rods = new ReferenceOrderedData[]{dbsnp}; // { gff, dbsnp };
|
||||||
}
|
} else if (DBSNP_FILE != null) {
|
||||||
else if ( DBSNP_FILE != null ) {
|
ReferenceOrderedData dbsnp = new ReferenceOrderedData(new File(DBSNP_FILE), rodDbSNP.class);
|
||||||
ReferenceOrderedData dbsnp = new ReferenceOrderedData(new File(DBSNP_FILE), rodDbSNP.class );
|
|
||||||
//dbsnp.testMe();
|
//dbsnp.testMe();
|
||||||
rods = new ReferenceOrderedData[] { dbsnp }; // { gff, dbsnp };
|
rods = new ReferenceOrderedData[]{dbsnp}; // { gff, dbsnp };
|
||||||
}
|
} else {
|
||||||
else {
|
rods = new ReferenceOrderedData[]{}; // { gff, dbsnp };
|
||||||
rods = new ReferenceOrderedData[] {}; // { gff, dbsnp };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.engine = new TraversalEngine(INPUT_FILE, REF_FILE_ARG, rods);
|
this.engine = new TraversalEngine(INPUT_FILE, REF_FILE_ARG, rods);
|
||||||
|
|
||||||
// Prepare the sort ordering w.r.t. the sequence dictionary
|
// Prepare the sort ordering w.r.t. the sequence dictionary
|
||||||
|
if (REF_FILE_ARG != null) {
|
||||||
final ReferenceSequenceFile refFile = ReferenceSequenceFileFactory.getReferenceSequenceFile(REF_FILE_ARG);
|
final ReferenceSequenceFile refFile = ReferenceSequenceFileFactory.getReferenceSequenceFile(REF_FILE_ARG);
|
||||||
List<SAMSequenceRecord> refContigs = refFile.getSequenceDictionary().getSequences();
|
List<SAMSequenceRecord> refContigs = refFile.getSequenceDictionary().getSequences();
|
||||||
|
|
||||||
HashMap<String, Integer> refContigOrdering = new HashMap<String, Integer>();
|
HashMap<String, Integer> refContigOrdering = new HashMap<String, Integer>();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for ( SAMSequenceRecord contig : refContigs ) {
|
for (SAMSequenceRecord contig : refContigs) {
|
||||||
refContigOrdering.put(contig.getSequenceName(), i);
|
refContigOrdering.put(contig.getSequenceName(), i);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
GenomeLoc.setContigOrdering(refContigOrdering);
|
|
||||||
|
|
||||||
|
GenomeLoc.setContigOrdering(refContigOrdering);
|
||||||
|
}
|
||||||
ValidationStringency strictness;
|
ValidationStringency strictness;
|
||||||
if ( STRICTNESS_ARG == null ) {
|
if (STRICTNESS_ARG == null) {
|
||||||
strictness = ValidationStringency.STRICT;
|
strictness = ValidationStringency.STRICT;
|
||||||
}
|
} else if (STRICTNESS_ARG.toLowerCase().equals("lenient")) {
|
||||||
else if ( STRICTNESS_ARG.toLowerCase().equals("lenient") ) {
|
|
||||||
strictness = ValidationStringency.LENIENT;
|
strictness = ValidationStringency.LENIENT;
|
||||||
}
|
} else if (STRICTNESS_ARG.toLowerCase().equals("silent")) {
|
||||||
else if ( STRICTNESS_ARG.toLowerCase().equals("silent") ) {
|
|
||||||
strictness = ValidationStringency.SILENT;
|
strictness = ValidationStringency.SILENT;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
strictness = ValidationStringency.STRICT;
|
strictness = ValidationStringency.STRICT;
|
||||||
}
|
}
|
||||||
System.err.println("Strictness is " + strictness);
|
logger.info("Strictness is " + strictness);
|
||||||
engine.setStrictness(strictness);
|
engine.setStrictness(strictness);
|
||||||
|
|
||||||
engine.setDebugging(! ( DEBUGGING_STR == null || DEBUGGING_STR.toLowerCase().equals("true")));
|
engine.setDebugging(!(DEBUGGING_STR == null || DEBUGGING_STR.toLowerCase().equals("true")));
|
||||||
engine.setMaxReads(Integer.parseInt(MAX_READS_ARG));
|
engine.setMaxReads(Integer.parseInt(MAX_READS_ARG));
|
||||||
|
|
||||||
if ( REGION_STR != null ) {
|
if (REGION_STR != null) {
|
||||||
engine.setLocation(REGION_STR);
|
engine.setLocation(REGION_STR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (INTERVALS_FILE != null)
|
if (INTERVALS_FILE != null) {
|
||||||
{
|
|
||||||
engine.setLocationFromFile(INTERVALS_FILE);
|
engine.setLocationFromFile(INTERVALS_FILE);
|
||||||
}
|
}
|
||||||
|
engine.setSafetyChecking(!UNSAFE);
|
||||||
|
engine.setSortOnFly(ENABLED_SORT_ON_FLY);
|
||||||
|
|
||||||
engine.setSafetyChecking(! UNSAFE.toLowerCase().equals("true"));
|
engine.initialize(ENABLED_THREADED_IO);
|
||||||
engine.setSortOnFly(ENABLED_SORT_ON_FLY.toLowerCase().equals("true"));
|
|
||||||
|
|
||||||
engine.initialize(ENABLED_THREADED_IO.toLowerCase().equals("true"));
|
|
||||||
|
|
||||||
//engine.testReference();
|
//engine.testReference();
|
||||||
|
|
||||||
//LocusWalker<Integer,Integer> walker = new PileupWalker();
|
//LocusWalker<Integer,Integer> walker = new PileupWalker();
|
||||||
|
|
@ -137,17 +155,17 @@ public class GenomeAnalysisTK extends CommandLineProgram {
|
||||||
if (walkerManager.doesWalkerExist(Analysis_Name)) {
|
if (walkerManager.doesWalkerExist(Analysis_Name)) {
|
||||||
my_walker = walkerManager.getWalkerByName(Analysis_Name);
|
my_walker = walkerManager.getWalkerByName(Analysis_Name);
|
||||||
} else {
|
} else {
|
||||||
System.out.println("Could not find walker "+Analysis_Name);
|
logger.fatal("Could not find walker " + Analysis_Name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LocusWalker<?, ?> walker = (LocusWalker<?, ?>)my_walker;
|
LocusWalker<?, ?> walker = (LocusWalker<?, ?>) my_walker;
|
||||||
engine.traverseByLoci(walker);
|
engine.traverseByLoci(walker);
|
||||||
}
|
}
|
||||||
catch ( java.lang.ClassCastException e ) {
|
catch (java.lang.ClassCastException e) {
|
||||||
// I guess we're a read walker LOL
|
// I guess we're a read walker LOL
|
||||||
ReadWalker<?, ?> walker = (ReadWalker<?, ?>)my_walker;
|
ReadWalker<?, ?> walker = (ReadWalker<?, ?>) my_walker;
|
||||||
engine.traverseByRead(walker);
|
engine.traverseByRead(walker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,343 @@
|
||||||
|
package org.broadinstitute.sting.utils.cmdLine;
|
||||||
|
|
||||||
|
import org.apache.commons.cli.*;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: aaron
|
||||||
|
* Date: Mar 19, 2009
|
||||||
|
* Time: 6:54:15 PM
|
||||||
|
* <p/>
|
||||||
|
* The Broad Institute
|
||||||
|
* SOFTWARE COPYRIGHT NOTICE AGREEMENT
|
||||||
|
* This software and its documentation are copyright 2009 by the
|
||||||
|
* Broad Institute/Massachusetts Institute of Technology. All rights are reserved.
|
||||||
|
* <p/>
|
||||||
|
* This software is supplied without any warranty or guaranteed support whatsoever. Neither
|
||||||
|
* the Broad Institute nor MIT can be responsible for its use, misuse, or functionality.
|
||||||
|
*/
|
||||||
|
public class ArgumentParser {
|
||||||
|
|
||||||
|
// what program are we parsing for
|
||||||
|
private String programName;
|
||||||
|
|
||||||
|
// our m_options
|
||||||
|
private ArrayList<String> m_option_names = new ArrayList<String>();
|
||||||
|
|
||||||
|
// where we eventually want the values to land
|
||||||
|
private HashMap<String, Field> m_storageLocations = new HashMap<String, Field>();
|
||||||
|
|
||||||
|
// create Options object
|
||||||
|
protected Options m_options = new Options();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* our log, which we want to capture anything from org.broadinstitute.sting
|
||||||
|
*/
|
||||||
|
protected static Logger logger = Logger.getLogger(ArgumentParser.class);
|
||||||
|
|
||||||
|
// the reference to the command line program to fill in
|
||||||
|
CommandLineProgram prog;
|
||||||
|
|
||||||
|
public ArgumentParser(String programName, CommandLineProgram prog) {
|
||||||
|
this.programName = programName;
|
||||||
|
this.prog = prog;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* print out the help information
|
||||||
|
*/
|
||||||
|
public void printHelp() {
|
||||||
|
// automatically generate the help statement
|
||||||
|
HelpFormatter formatter = new HelpFormatter();
|
||||||
|
formatter.printHelp(100,
|
||||||
|
"java -Xmx4096m -jar dist/GenomeAnalysisTK.jar",
|
||||||
|
"",
|
||||||
|
m_options,
|
||||||
|
"",
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addOptionalArg
|
||||||
|
* <p/>
|
||||||
|
* Adds an optional argument to check on the command line
|
||||||
|
*
|
||||||
|
* @param name the name of the argument, the long name
|
||||||
|
* @param letterform the short form
|
||||||
|
* @param description the description of the argument
|
||||||
|
* @param fieldname the field to set when we've parsed this option
|
||||||
|
*/
|
||||||
|
public void addOptionalArg(String name, String letterform, String description, String fieldname) {
|
||||||
|
// we always want the help option to be available
|
||||||
|
Option opt = OptionBuilder.withLongOpt(name).withArgName(name)
|
||||||
|
.hasArg()
|
||||||
|
.withDescription(description)
|
||||||
|
.create(letterform);
|
||||||
|
|
||||||
|
// add it to the option
|
||||||
|
AddToOptionStorage(name, letterform, fieldname, opt);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used locally to add to the options storage we have, for latter processing
|
||||||
|
*
|
||||||
|
* @param name the name of the option
|
||||||
|
* @param letterform it's short form
|
||||||
|
* @param fieldname what field it should be stuck into on the calling class
|
||||||
|
* @param opt the option
|
||||||
|
*/
|
||||||
|
private void AddToOptionStorage(String name, String letterform, String fieldname, Option opt) {
|
||||||
|
// add to the option list
|
||||||
|
m_options.addOption(opt);
|
||||||
|
|
||||||
|
// add the object with it's name to the storage location
|
||||||
|
try {
|
||||||
|
m_storageLocations.put(name, prog.getClass().getField(fieldname));
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
logger.fatal("Failed to find the field specified by the fieldname parameter.");
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to the list of m_options
|
||||||
|
m_option_names.add(letterform);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addRequiredlArg
|
||||||
|
* <p/>
|
||||||
|
* Adds a required argument to check on the command line
|
||||||
|
*
|
||||||
|
* @param name the name of the argument, the long name
|
||||||
|
* @param letterform the short form
|
||||||
|
* @param description the description of the argument
|
||||||
|
* @param fieldname what field it should be stuck into on the calling class
|
||||||
|
*/
|
||||||
|
public void addRequiredlArg(String name, String letterform, String description, String fieldname) {
|
||||||
|
// we always want the help option to be available
|
||||||
|
Option opt = OptionBuilder.isRequired()
|
||||||
|
.withLongOpt(name)
|
||||||
|
.withArgName(name)
|
||||||
|
.hasArg()
|
||||||
|
.withDescription("(Required Option) " + description)
|
||||||
|
.create(letterform);
|
||||||
|
|
||||||
|
// add it to the option
|
||||||
|
AddToOptionStorage(name, letterform, fieldname, opt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addOptionalArg
|
||||||
|
* <p/>
|
||||||
|
* Adds an optional argument to check on the command line
|
||||||
|
*
|
||||||
|
* @param name the name of the argument, the long name
|
||||||
|
* @param letterform the short form
|
||||||
|
* @param description the description of the argument
|
||||||
|
* @param fieldname what field it should be stuck into on the calling class
|
||||||
|
*/
|
||||||
|
public void addOptionalArgList(String name, String letterform, String description, String fieldname) {
|
||||||
|
// we always want the help option to be available
|
||||||
|
Option opt = OptionBuilder.withLongOpt(name).withArgName(name)
|
||||||
|
.hasArgs()
|
||||||
|
.withDescription(description)
|
||||||
|
.create(letterform);
|
||||||
|
// add it to the option
|
||||||
|
AddToOptionStorage(name, letterform, fieldname, opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addRequiredlArg
|
||||||
|
* <p/>
|
||||||
|
* Adds a required argument to check on the command line
|
||||||
|
*
|
||||||
|
* @param name the name of the argument, the long name
|
||||||
|
* @param letterform the short form
|
||||||
|
* @param description the description of the argument
|
||||||
|
* @param fieldname what field it should be stuck into on the calling class
|
||||||
|
*/
|
||||||
|
public void addRequiredlArgList(String name, String letterform, String description, String fieldname) {
|
||||||
|
// we always want the help option to be available
|
||||||
|
Option opt = OptionBuilder.isRequired()
|
||||||
|
.withLongOpt(name)
|
||||||
|
.withArgName(name)
|
||||||
|
.hasArgs()
|
||||||
|
.withDescription("(Required Option) " + description)
|
||||||
|
.create(letterform);
|
||||||
|
// add it to the option
|
||||||
|
AddToOptionStorage(name, letterform, fieldname, opt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addOptionalFlag
|
||||||
|
* <p/>
|
||||||
|
* Adds an optional argument to check on the command line
|
||||||
|
*
|
||||||
|
* @param name the name of the argument, the long name
|
||||||
|
* @param letterform the short form
|
||||||
|
* @param description the description of the argument
|
||||||
|
* @param fieldname what field it should be stuck into on the calling class
|
||||||
|
*/
|
||||||
|
public void addOptionalFlag(String name, String letterform, String description, String fieldname) {
|
||||||
|
// we always want the help option to be available
|
||||||
|
Option opt = OptionBuilder.withLongOpt(name)
|
||||||
|
.withDescription(description)
|
||||||
|
.create(letterform);
|
||||||
|
|
||||||
|
// add it to the option
|
||||||
|
AddToOptionStorage(name, letterform, fieldname, opt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* addRequiredlFlag
|
||||||
|
* <p/>
|
||||||
|
* Adds a required argument to check on the command line
|
||||||
|
*
|
||||||
|
* @param name the name of the argument, the long name
|
||||||
|
* @param letterform the short form
|
||||||
|
* @param description the description of the argument
|
||||||
|
* @param fieldname what field it should be stuck into on the calling class
|
||||||
|
*/
|
||||||
|
public void addRequiredlFlag(String name, String letterform, String description, String fieldname) {
|
||||||
|
// we always want the help option to be available
|
||||||
|
Option opt = OptionBuilder.isRequired()
|
||||||
|
.withLongOpt(name)
|
||||||
|
.withDescription("(Required Flag) " + description)
|
||||||
|
.create(letterform);
|
||||||
|
|
||||||
|
// add it to the option
|
||||||
|
AddToOptionStorage(name, letterform, fieldname, opt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called to validate all the arguments to the program.
|
||||||
|
* If a required Arg isn't found, we generate the help message, and
|
||||||
|
* exit the program
|
||||||
|
*
|
||||||
|
* @param args the command line arguments we recieved
|
||||||
|
*/
|
||||||
|
protected void processArgs(String[] args) {
|
||||||
|
CommandLineParser parser = new PosixParser();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Collection<Option> opts = m_options.getOptions();
|
||||||
|
|
||||||
|
CommandLine cmd = parser.parse(m_options, args);
|
||||||
|
|
||||||
|
// logger.info("We have " + opts.size() + " options");
|
||||||
|
for (Option opt : opts) {
|
||||||
|
if (cmd.hasOption(opt.getOpt())) {
|
||||||
|
if (opt.hasArg()) {
|
||||||
|
//logger.info("looking at " + m_storageLocations.get(opt.getLongOpt()));
|
||||||
|
Field f = m_storageLocations.get(opt.getLongOpt());
|
||||||
|
try {
|
||||||
|
f.set(prog, constructFromString(f, cmd.getOptionValue(opt.getOpt())));
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
logger.fatal("processArgs: cannot convert field " + f.toString());
|
||||||
|
throw new RuntimeException("processArgs: Failed conversion " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
Field f = m_storageLocations.get(opt.getLongOpt());
|
||||||
|
try {
|
||||||
|
//logger.fatal("about to parse field " + f.getName());
|
||||||
|
f.set(prog, new Boolean(true));
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
logger.fatal("processArgs: cannot convert field " + f.toString());
|
||||||
|
throw new RuntimeException("processArgs: Failed conversion " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ParseException e) {
|
||||||
|
// we didn't get all the required arguments,
|
||||||
|
// print out the help
|
||||||
|
this.printHelp();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Object constructFromString(Field f, String str) {
|
||||||
|
Type type = f.getType();
|
||||||
|
// lets go through the types we support
|
||||||
|
if (type == Boolean.TYPE) {
|
||||||
|
boolean b = false;
|
||||||
|
if (str.toLowerCase().equals("true")) {
|
||||||
|
b = true;
|
||||||
|
}
|
||||||
|
Boolean bool = new Boolean(b);
|
||||||
|
return bool;
|
||||||
|
} else if (type == Integer.TYPE) {
|
||||||
|
Integer in = Integer.valueOf(str);
|
||||||
|
return in;
|
||||||
|
} else if (type == Float.TYPE) {
|
||||||
|
Float fl = Float.valueOf(str);
|
||||||
|
return fl;
|
||||||
|
} else {
|
||||||
|
Constructor ctor = null;
|
||||||
|
try {
|
||||||
|
ctor = f.getType().getConstructor(String.class);
|
||||||
|
return ctor.newInstance(str);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
logger.fatal("constructFromString: cannot convert field " + f.toString());
|
||||||
|
throw new RuntimeException("constructFromString: Failed conversion " + e.getMessage());
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
logger.fatal("constructFromString: cannot convert field " + f.toString());
|
||||||
|
throw new RuntimeException("constructFromString: Failed conversion " + e.getMessage());
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
logger.fatal("constructFromString: cannot convert field " + f.toString());
|
||||||
|
throw new RuntimeException("constructFromString: Failed conversion " + e.getMessage());
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
logger.fatal("constructFromString: cannot convert field " + f.toString());
|
||||||
|
throw new RuntimeException("constructFromString: Failed conversion " + e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
ArgumentParser p = new ArgumentParser("CrapApp");
|
||||||
|
p.setupDefaultArgs();
|
||||||
|
p.addRequiredlArg("Flag","F","a required arg");
|
||||||
|
p.addRequiredlFlag("Sub","S","a required flag");
|
||||||
|
p.addOptionalArg("Boat","T","Maybe you want a boat?");
|
||||||
|
String[] str = {"--Flag","rrr","-T","ppp", "--Flag","ttt"};
|
||||||
|
p.processArgs(str);
|
||||||
|
Iterator<String> r = map.keySet().iterator();
|
||||||
|
while (r.hasNext()) {
|
||||||
|
String key = r.next();
|
||||||
|
String[] q = map.get(key);
|
||||||
|
if (q != null) {
|
||||||
|
for (String mystr : q) {
|
||||||
|
System.err.println("key: " + key + " val: " + mystr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
@ -0,0 +1,246 @@
|
||||||
|
package org.broadinstitute.sting.utils.cmdLine;
|
||||||
|
|
||||||
|
import org.apache.log4j.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User: aaron
|
||||||
|
* Date: Mar 19, 2009
|
||||||
|
* Time: 3:54:56 PM
|
||||||
|
* <p/>
|
||||||
|
* The Broad Institute
|
||||||
|
* SOFTWARE COPYRIGHT NOTICE AGREEMENT
|
||||||
|
* This software and its documentation are copyright 2009 by the
|
||||||
|
* Broad Institute/Massachusetts Institute of Technology. All rights are reserved.
|
||||||
|
* <p/>
|
||||||
|
* This software is supplied without any warranty or guaranteed support whatsoever. Neither
|
||||||
|
* the Broad Institute nor MIT can be responsible for its use, misuse, or functionality.
|
||||||
|
* <p/>
|
||||||
|
* <p/>
|
||||||
|
* This class is our implementation of the command line parser, similar to Pickard's. We instead
|
||||||
|
* support GNU style command line arguements, and use this class to setup the global parser.
|
||||||
|
*/
|
||||||
|
public abstract class CommandLineProgram {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our Argument parser, which handles parsing the command line in GNU format
|
||||||
|
*/
|
||||||
|
protected ArgumentParser m_parser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* our log, which we want to capture anything from org.broadinstitute.sting
|
||||||
|
*/
|
||||||
|
private static Logger logger = Logger.getRootLogger();// .getLogger(CommandLineProgram.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the default log level
|
||||||
|
*/
|
||||||
|
public String logging_level = "ERROR";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* where to send the output of our logger
|
||||||
|
*/
|
||||||
|
public String toFile = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* do we want to silence the command line output
|
||||||
|
*/
|
||||||
|
public Boolean quietMode = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* do we want to generate debugging information with the logs
|
||||||
|
*/
|
||||||
|
public Boolean debugMode = false;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* our logging output patterns
|
||||||
|
*/
|
||||||
|
private static String patternString = "%p %m %n";
|
||||||
|
private static String debugPatternString = "%n[level] %p%n[date]\t\t %d{dd MMM yyyy HH:mm:ss,SSS} %n[class]\t\t %C %n[location]\t %l %n[line number]\t %L %n[message]\t %m %n";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the contract for the inheriting class is that they have a setupArgs()
|
||||||
|
* function which sets up the args to the specific program.
|
||||||
|
*/
|
||||||
|
protected abstract void setupArgs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this is the function that the inheriting class can expect to have called
|
||||||
|
* when all the argument processing is done
|
||||||
|
*
|
||||||
|
* @return the return code to exit the program with
|
||||||
|
*/
|
||||||
|
protected abstract int execute();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this is used to indicate if they've asked for help
|
||||||
|
*/
|
||||||
|
public Boolean help = false;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is called to start processing the command line, and kick
|
||||||
|
* off the execute message of the program.
|
||||||
|
*
|
||||||
|
* @param clp the command line program to execute
|
||||||
|
* @param args the command line arguments passed in
|
||||||
|
*/
|
||||||
|
public static void start(CommandLineProgram clp, String[] args) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
// setup a basic log configuration
|
||||||
|
BasicConfigurator.configure();
|
||||||
|
|
||||||
|
// setup our log layout
|
||||||
|
PatternLayout layout = new PatternLayout();
|
||||||
|
|
||||||
|
|
||||||
|
// setup the parser
|
||||||
|
clp.m_parser = new ArgumentParser(clp.getClass().getName(), clp);
|
||||||
|
|
||||||
|
// setup the default help and logging args controlled by the base class
|
||||||
|
clp.setupDefaultArgs();
|
||||||
|
|
||||||
|
// setup the args
|
||||||
|
clp.setupArgs();
|
||||||
|
|
||||||
|
// process the args
|
||||||
|
clp.m_parser.processArgs(args);
|
||||||
|
|
||||||
|
|
||||||
|
// if we're in debug mode, set the mode up
|
||||||
|
if (clp.debugMode) {
|
||||||
|
//logger.info("Setting debug");
|
||||||
|
layout.setConversionPattern(debugPatternString);
|
||||||
|
} else {
|
||||||
|
//logger.info("not Setting debug");
|
||||||
|
layout.setConversionPattern(patternString);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if they set the mode to quiet
|
||||||
|
if (clp.quietMode) {
|
||||||
|
|
||||||
|
// the only appender we should have is stdout, the following meathod is
|
||||||
|
// deprecated, but the standard remove all appenders doesn't seem to work
|
||||||
|
// TODO: find the right function
|
||||||
|
//Category root = Category.getRoot();
|
||||||
|
//root.removeAllAppenders();
|
||||||
|
//logger.removeAllAppenders();
|
||||||
|
}
|
||||||
|
|
||||||
|
// they asked for help, give it to them
|
||||||
|
if (clp.help) {
|
||||||
|
clp.m_parser.printHelp();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if they specify a log location, output our data there
|
||||||
|
if (clp.toFile != null) {
|
||||||
|
FileAppender appender = null;
|
||||||
|
try {
|
||||||
|
appender = new FileAppender(layout, clp.toFile, false);
|
||||||
|
logger.addAppender(appender);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Unable to re-route log output to " + clp.toFile + " make sure the destination exists");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// regardless of what happens next, generate the header information
|
||||||
|
generateHeaderInformation(clp, args);
|
||||||
|
|
||||||
|
// set the default logger level
|
||||||
|
clp.setupLoggerLevel();
|
||||||
|
|
||||||
|
// call the execute
|
||||||
|
int result = clp.execute();
|
||||||
|
|
||||||
|
// return the result
|
||||||
|
System.exit(result);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
// we catch all exceptions here. if it makes it to this level, we're in trouble. Let's bail!
|
||||||
|
// TODO: what if the logger is the exception? hmm...
|
||||||
|
logger.fatal("Exception caught by base Command Line Program, with message: " + e.getMessage());
|
||||||
|
logger.fatal("with cause: " + e.getCause());
|
||||||
|
e.printStackTrace();
|
||||||
|
throw new RuntimeException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* generateHeaderInformation
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* Generate a standard header for the logger
|
||||||
|
* @param clp the command line program to execute
|
||||||
|
* @param args the command line arguments passed in
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
protected static void generateHeaderInformation(CommandLineProgram clp, String[] args) {
|
||||||
|
|
||||||
|
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
||||||
|
java.util.Date date = new java.util.Date();
|
||||||
|
|
||||||
|
logger.info("-------------------------------------------------------");
|
||||||
|
logger.info("Program Name: " + clp.getClass().getName());
|
||||||
|
|
||||||
|
String output = "";
|
||||||
|
for (String str : args) {
|
||||||
|
output = output + str + " ";
|
||||||
|
}
|
||||||
|
logger.info("Program Args: " + output);
|
||||||
|
logger.info("Time/Date: " + dateFormat.format(date));
|
||||||
|
logger.info("-------------------------------------------------------");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this function checks the logger level passed in on the command line, taking the lowest
|
||||||
|
* level that was provided.
|
||||||
|
*/
|
||||||
|
private void setupLoggerLevel() {
|
||||||
|
|
||||||
|
Level par = Level.ERROR;
|
||||||
|
if (logging_level.equals("DEBUG")) {
|
||||||
|
par = Level.DEBUG;
|
||||||
|
}
|
||||||
|
if (logging_level.equals("ERROR")) {
|
||||||
|
par = Level.ERROR;
|
||||||
|
}
|
||||||
|
if (logging_level.equals("FATAL")) {
|
||||||
|
par = Level.FATAL;
|
||||||
|
}
|
||||||
|
if (logging_level.equals("INFO")) {
|
||||||
|
par = Level.INFO;
|
||||||
|
}
|
||||||
|
if (logging_level.equals("WARN")) {
|
||||||
|
par = Level.WARN;
|
||||||
|
}
|
||||||
|
if (logging_level.equals("OFF")) {
|
||||||
|
par = Level.OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.setLevel(par);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* we have some default options that should always get checked for in the
|
||||||
|
* arguments provided to the program
|
||||||
|
*/
|
||||||
|
private void setupDefaultArgs() {
|
||||||
|
m_parser.addOptionalFlag("help", "h", "Generate this help message", "help");
|
||||||
|
m_parser.addOptionalArg("logging_level", "l", "Set the logging level", "logging_level");
|
||||||
|
m_parser.addOptionalArg("log_to_file", "log", "Set the logging location", "toFile");
|
||||||
|
m_parser.addOptionalFlag("quiet_output_mode", "quiet", "Set the logging to quiet mode, no output to stdout", "quietMode");
|
||||||
|
m_parser.addOptionalFlag("debug_mode", "debug", "Set the logging file string to include a lot of debugging information (SLOW!)", "debugMode");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
1
ivy.xml
1
ivy.xml
|
|
@ -7,5 +7,6 @@
|
||||||
<dependency org="junit" name="junit" rev="4.4" />
|
<dependency org="junit" name="junit" rev="4.4" />
|
||||||
<dependency org="log4j" name="log4j" rev="1.2.15" />
|
<dependency org="log4j" name="log4j" rev="1.2.15" />
|
||||||
<dependency org="colt" name="colt" rev="1.2.0" />
|
<dependency org="colt" name="colt" rev="1.2.0" />
|
||||||
|
<dependency org="commons-cli" name="commons-cli" rev="1.1" />
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</ivy-module>
|
</ivy-module>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue