Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 138 additions & 28 deletions qannotate/src/au/edu/qimr/qannotate/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
*/
package au.edu.qimr.qannotate;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.qcmg.common.log.QLogger;
import org.qcmg.common.log.QLoggerFactory;

Expand Down Expand Up @@ -32,36 +36,19 @@ public static void main(final String[] args) {
logger = QLoggerFactory.getLogger(Main.class, options.getLogFileName(), options.getLogLevel());
logger.logInitialExecutionStats(options.getPGName(), options.getVersion(), args);

checkOptions(options);

if (options.getMode() == Options.MODE.dbsnp) {
new DbsnpMode(options);
} else if (options.getMode() == Options.MODE.germline) {
new GermlineMode(options);
} else if (options.getMode() == Options.MODE.snpeff) {
new SnpEffMode(options);
} else if (options.getMode() == Options.MODE.confidence) {
new ConfidenceMode(options);
} else if (options.getMode() == Options.MODE.ccm) {
new CCMMode(options);
} else if (options.getMode() == Options.MODE.vcf2maf) {
new Vcf2maf(options);
} else if (options.getMode() == Options.MODE.cadd) {
new CaddMode(options);
} else if (options.getMode() == Options.MODE.indelconfidence) {
new IndelConfidenceMode(options);
} else if (options.getMode() == Options.MODE.hom) {
new HomopolymersMode(options);
} else if (options.getMode() == Options.MODE.trf) {
new TandemRepeatMode(options);
} else if (options.getMode() == Options.MODE.make_valid) {
new MakeValidMode(options);
} else if (options.getMode() == Options.MODE.overlap) {
new OverlapMode(options);
} else if (options.getMode() == null) {
List<Options.MODE> modes = options.getModes();
if (modes.isEmpty()) {
throw new IllegalArgumentException("No mode was specified on the commandline - please add the \"-mode\" option");
}
if (modes.size() > 1 && (modes.contains(Options.MODE.vcf2maf) || modes.contains(Options.MODE.vcf2maftmp))) {
throw new IllegalArgumentException("Multiple mode runs do not support vcf2maf/vcf2maftmp");
}

if (modes.size() == 1) {
checkOptions(options);
runMode(options);
} else {
throw new IllegalArgumentException("No valid mode are specified on commandline - please run \"qannotate -help\" to see the list of available modes");
runMultipleModes(args, modes, options.getInputFileName(), options.getOutputFileName());
}

logger.logFinalExecutionStats(0);
Expand All @@ -79,6 +66,129 @@ public static void main(final String[] args) {
}
}

static void runMultipleModes(String[] args, List<Options.MODE> modes, String inputFile, String outputFile) throws Exception {
String currentInput = inputFile;
List<File> tempFiles = new ArrayList<>();
List<String> databaseArgs = extractDatabaseArgs(args);
int databaseIndex = 0;
for (int i = 0 ; i < modes.size() ; i++) {
boolean finalMode = i == modes.size() - 1;
String currentOutput;
if (finalMode) {
currentOutput = outputFile;
} else {
File tmp = File.createTempFile("qannotate-mode-" + i + "-", ".vcf");
tmp.deleteOnExit();
tempFiles.add(tmp);
currentOutput = tmp.getAbsolutePath();
}
List<String> modeDatabaseArgs = new ArrayList<>();
if (modeUsesDatabase(modes.get(i)) && databaseIndex < databaseArgs.size()) {
modeDatabaseArgs.add(databaseArgs.get(databaseIndex++));
}
Options modeOptions = new Options(rewriteArgsForMode(args, modes.get(i), currentInput, currentOutput, modeDatabaseArgs));
checkOptions(modeOptions);
runMode(modeOptions);
currentInput = currentOutput;
}
for (File temp : tempFiles) {
if (temp.exists() && ! temp.delete()) {
temp.deleteOnExit();
}
}
}

static String[] rewriteArgsForMode(String[] args, Options.MODE mode, String inputFile, String outputFile, List<String> databaseArgs) {
List<String> newArgs = new ArrayList<>();
for (int i = 0 ; i < args.length ; i++) {
String arg = args[i];
if (isOptionWithValue(arg, "mode", "input", "i", "o", "output", "d", "database")) {
i++;
continue;
}
if (arg.startsWith("--mode=") || arg.startsWith("--input=") || arg.startsWith("-i=")
|| arg.startsWith("--output=") || arg.startsWith("-o=") || arg.startsWith("-output=")
|| arg.startsWith("--database=") || arg.startsWith("-d=")) {
continue;
}
newArgs.add(arg);
}
newArgs.add("--mode");
newArgs.add(mode.name());
newArgs.add("-i");
newArgs.add(inputFile);
newArgs.add("-o");
newArgs.add(outputFile);
for (String databaseArg : databaseArgs) {
newArgs.add("-d");
newArgs.add(databaseArg);
}
return newArgs.toArray(new String[0]);
}

static List<String> extractDatabaseArgs(String[] args) {
List<String> databaseArgs = new ArrayList<>();
for (int i = 0 ; i < args.length ; i++) {
String arg = args[i];
if (arg.equals("-d") || arg.equals("--database")) {
if (i + 1 < args.length) {
databaseArgs.add(args[++i]);
}
} else if (arg.startsWith("-d=")) {
databaseArgs.add(arg.substring(3));
} else if (arg.startsWith("--database=")) {
databaseArgs.add(arg.substring(11));
}
}
return databaseArgs;
}

private static boolean modeUsesDatabase(Options.MODE mode) {
return switch (mode) {
case dbsnp, germline, snpeff, cadd, trf, hom, overlap, make_valid, indelconfidence -> true;
default -> false;
};
}

private static boolean isOptionWithValue(String arg, String... options) {
for (String option : options) {
if (arg.equals("-" + option) || arg.equals("--" + option)) {
return true;
}
}
return false;
}

private static void runMode(Options options) throws Exception {
if (options.getMode() == Options.MODE.dbsnp) {
new DbsnpMode(options);
} else if (options.getMode() == Options.MODE.germline) {
new GermlineMode(options);
} else if (options.getMode() == Options.MODE.snpeff) {
new SnpEffMode(options);
} else if (options.getMode() == Options.MODE.confidence) {
new ConfidenceMode(options);
} else if (options.getMode() == Options.MODE.ccm) {
new CCMMode(options);
} else if (options.getMode() == Options.MODE.vcf2maf) {
new Vcf2maf(options);
} else if (options.getMode() == Options.MODE.cadd) {
new CaddMode(options);
} else if (options.getMode() == Options.MODE.indelconfidence) {
new IndelConfidenceMode(options);
} else if (options.getMode() == Options.MODE.hom) {
new HomopolymersMode(options);
} else if (options.getMode() == Options.MODE.trf) {
new TandemRepeatMode(options);
} else if (options.getMode() == Options.MODE.make_valid) {
new MakeValidMode(options);
} else if (options.getMode() == Options.MODE.overlap) {
new OverlapMode(options);
} else {
throw new IllegalArgumentException("No valid mode are specified on commandline - please run \"qannotate -help\" to see the list of available modes");
}
}

/**
* Checks the Options object to see if the minimal options (input, output, database) have been supplied.
* Using the switch statements fall through process here.
Expand Down
49 changes: 28 additions & 21 deletions qannotate/src/au/edu/qimr/qannotate/Options.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

Expand All @@ -35,6 +36,7 @@ public enum MODE {dbsnp, germline, snpeff, confidence, vcf2maf, cadd, indelconfi
private final String commandLine;

private final Options.MODE mode;
private final List<Options.MODE> modes;
private final OptionParser parser;
private final String outputFileName;
private final String inputFileName;
Expand Down Expand Up @@ -83,12 +85,13 @@ public Options(final String[] args) throws IOException {
parser = new OptionParser();
OptionSet options = parseArgs(args);

if (options.has("mode")) {
String m = ((String) options.valueOf("mode")).toLowerCase();
this.mode = MODE.valueOf(m); //already checked the validation of mode
} else {
this.mode = null;
List<String> modeStrings = (List<String>) options.valuesOf("mode");
List<MODE> modeList = new ArrayList<>();
for (String m : modeStrings) {
modeList.add(MODE.valueOf(m.toLowerCase()));
}
this.modes = Collections.unmodifiableList(modeList);
this.mode = modeList.isEmpty() ? null : modeList.get(0);

if (options.has("h") || options.has("help")) {
displayHelp(mode);
Expand All @@ -113,7 +116,7 @@ public Options(final String[] args) throws IOException {
List<String> dbList = (List<String>) options.valuesOf("d");
databaseFiles = dbList.toArray(new String[dbList.size()]);

if (MODE.dbsnp == mode && dbList.isEmpty()) {
if (modes.contains(MODE.dbsnp) && dbList.isEmpty()) {
displayHelp(mode);
System.exit(0);
}
Expand Down Expand Up @@ -193,43 +196,43 @@ public OptionSet parseArgs(final String[] args) {
System.exit(0);
}

Options.MODE mm = null;
List<Options.MODE> selectedModes = new ArrayList<>();
if (options.has("mode")) {
final String m = ((String) options.valueOf("mode")).toLowerCase();
try {
mm = MODE.valueOf(m);
} catch (IllegalArgumentException | NullPointerException e) {
System.err.println("invalid mode specified: " + m);
System.exit(1);
for (String m : (List<String>) options.valuesOf("mode")) {
try {
selectedModes.add(MODE.valueOf(m.toLowerCase()));
} catch (IllegalArgumentException | NullPointerException e) {
System.err.println("invalid mode specified: " + m);
System.exit(1);
}
}
}

if (mm == null) {
if (selectedModes.isEmpty()) {
/*
* used by nanno.Annotate
*/
parser.accepts("config", Messages.getMessage("NANNO_CONF_FILE_DESCRIPTION")).withRequiredArg().ofType(String.class).describedAs("config file");
} else {

if (mm.equals(MODE.confidence) || mm.equals(MODE.vcf2maf)) {
if (selectedModes.contains(MODE.confidence) || selectedModes.contains(MODE.vcf2maf)) {
parser.accepts(test, Messages.getMessage("TUMOUR_SAMPLEID_DESCRIPTION")).withRequiredArg().ofType(String.class).describedAs("testSample");
parser.accepts(control, Messages.getMessage("NORMAL_SAMPLEID_DESCRIPTION")).withRequiredArg().ofType(String.class).describedAs("controlSample");
} else {
parser.acceptsAll(asList("d", "database"), Messages.getMessage("DATABASE_DESCRIPTION")).withRequiredArg().ofType(String.class).describedAs("database file");
}
parser.acceptsAll(asList("d", "database"), Messages.getMessage("DATABASE_DESCRIPTION")).withRequiredArg().ofType(String.class).describedAs("database file");

if (mm.equals(MODE.snpeff)) {
if (selectedModes.contains(MODE.snpeff)) {
parser.accepts("config", Messages.getMessage("CONF_FILE_DESCRIPTION")).withRequiredArg().ofType(String.class).describedAs("config file");
parser.accepts("summaryFile", Messages.getMessage("SUMMARY_FILE_DESCRIPTION")).withRequiredArg().ofType(String.class).describedAs("stat output");
}

if (mm.equals(MODE.trf))
if (selectedModes.contains(MODE.trf))
parser.accepts("buffer", "check TRF region on both sides of indel within this nominated size").withRequiredArg().ofType(Integer.class);//.describedAs("integer");

if (mm.equals(MODE.cadd))
if (selectedModes.contains(MODE.cadd))
parser.accepts("gap", "adjacent variants size").withRequiredArg().ofType(String.class).describedAs("gap size");

if (mm.equals(MODE.vcf2maf)) {
if (selectedModes.contains(MODE.vcf2maf)) {
parser.accepts("outdir", Messages.getMessage("MAF_OUTPUT_DIRECTORY_OPTION_DESCRIPTION")).withRequiredArg().ofType(String.class).describedAs("output file location");
parser.accepts("donor", Messages.getMessage("DONOR_ID_DESCRIPTION")).withRequiredArg().ofType(String.class).describedAs("donor id");
parser.accepts("center", "Genome sequencing center").withRequiredArg().ofType(String.class).describedAs("center");
Expand Down Expand Up @@ -338,6 +341,10 @@ public MODE getMode() {
return mode;
}

public List<MODE> getModes() {
return modes;
}

private void displayHelp(MODE mode) throws IOException {
String mess = Messages.getMessage("USAGE");
if (mode != null) {
Expand Down
26 changes: 26 additions & 0 deletions qannotate/test/au/edu/qimr/qannotate/MainTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package au.edu.qimr.qannotate;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

import java.util.Collections;
import java.util.List;

import org.junit.Test;

public class MainTest {

@Test
public void rewriteArgsForModeReplacesModeAndIo() {
String[] args = {"--mode", "dbsnp", "--mode", "germline", "-i", "in.vcf", "-o", "out.vcf", "-d", "db.vcf"};
String[] rewritten = Main.rewriteArgsForMode(args, Options.MODE.germline, "tmpIn.vcf", "tmpOut.vcf", Collections.singletonList("db2.vcf"));
assertArrayEquals(new String[]{"--mode", "germline", "-i", "tmpIn.vcf", "-o", "tmpOut.vcf", "-d", "db2.vcf"}, rewritten);
}

@Test
public void extractDatabaseArgsInOrder() {
String[] args = {"--mode", "dbsnp", "-d", "db1.vcf", "--database=db2.vcf", "-d=db3.vcf"};
List<String> dbs = Main.extractDatabaseArgs(args);
assertEquals(List.of("db1.vcf", "db2.vcf", "db3.vcf"), dbs);
}
}
11 changes: 11 additions & 0 deletions qannotate/test/au/edu/qimr/qannotate/OptionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Optional;

import org.junit.Rule;
Expand Down Expand Up @@ -82,4 +83,14 @@ public void homReportWindow() throws IOException {
assertEquals(Optional.of(42), o.getHomoplymersReportWindow());
}

@Test
public void multipleModes() throws IOException {
File i = testFolder.newFile();
File o = testFolder.newFile();
File d = testFolder.newFile();
Options options = new Options(new String[]{"--mode", "dbsnp", "--mode", "germline", "-i", i.getAbsolutePath(), "-o", o.getAbsolutePath(), "-d", d.getAbsolutePath()});
assertEquals(Arrays.asList(Options.MODE.dbsnp, Options.MODE.germline), options.getModes());
assertEquals(Options.MODE.dbsnp, options.getMode());
}

}