Commit 11cb5d29 authored by Peter van 't Hof's avatar Peter van 't Hof
Browse files

Merge branch 'develop' into feature-unittest_core

Conflicts:
	public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/BiopetCommandLineFunctionTrait.scala
	public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/BiopetQScript.scala
parents 978b8381 9e88effb
......@@ -72,16 +72,16 @@ Global setting examples are:
#### Example settings config
~~~
{
"reference": "/data/LGTC/projects/vandoorn-melanoma/data/references/hg19_nohap/ucsc.hg19_nohap.fasta",
"dbsnp": "/data/LGTC/projects/vandoorn-melanoma/data/references/hg19_nohap/dbsnp_137.hg19_nohap.vcf",
"reference": "/references/hg19_nohap/ucsc.hg19_nohap.fasta",
"dbsnp": "/references/hg19_nohap/dbsnp_137.hg19_nohap.vcf",
"joint_variantcalling": false,
"haplotypecaller": { "scattercount": 100 },
"multisample": { "haplotypecaller": { "scattercount": 1000 } },
"picard": { "validationstringency": "LENIENT" },
"library_variantcalling_temp": true,
"target_bed_temp": "/data/LGTC/projects/vandoorn-melanoma/analysis/target.bed",
"target_bed_temp": "analysis/target.bed",
"min_dp": 5,
"bedtools": {"exe":"/share/isilon/system/local/BEDtools/bedtools-2.17.0/bin/bedtools"},
"bedtools": {"exe":"/BEDtools/bedtools-2.17.0/bin/bedtools"},
"bam_to_fastq": true,
"baserecalibrator": { "memory_limit": 8, "vmem":"16G" },
"samtofastq": {"memory_limit": 8, "vmem": "16G"},
......@@ -95,4 +95,4 @@ Global setting examples are:
### JSON validation
To check if the JSON file created is correct we can use multiple options the simplest way is using [this](http://jsonformatter.curiousconcept.com/)
website. It is also possible to use Python or Scala for validating but this requires some more knowledge.
\ No newline at end of file
website. It is also possible to use Python or Scala for validating but this requires some more knowledge.
......@@ -33,7 +33,7 @@ class Basty(val root: Configurable) extends QScript with MultiSampleQScript {
def makeSample(id: String) = new Sample(id)
class Sample(sampleId: String) extends AbstractSample(sampleId) {
def makeLibrary(id: String) = new Library(id)
class Library(libraryId: String) extends AbstractLibrary(libraryId) {
class Library(libId: String) extends AbstractLibrary(libId) {
protected def addJobs(): Unit = {}
}
......
......@@ -13,13 +13,13 @@ trait GatkGeneral extends CommandLineGATK with BiopetJavaCommandLineFunction {
override def subPath = "gatk" :: super.subPath
jarFile = config("gatk_jar", required = true)
jarFile = config("gatk_jar")
override val defaultVmem = "7G"
if (config.contains("intervals")) intervals = config("intervals").asFileList
if (config.contains("exclude_intervals")) excludeIntervals = config("exclude_intervals").asFileList
reference_sequence = config("reference", required = true)
reference_sequence = config("reference")
if (config.contains("gatk_key")) gatk_key = config("gatk_key")
if (config.contains("pedigree")) pedigree = config("pedigree").asFileList
}
......@@ -35,17 +35,17 @@ class GatkPipeline(val root: Configurable) extends QScript with MultiSampleQScri
var jointGenotyping: Boolean = config("joint_genotyping", default = false)
var singleSampleCalling = config("single_sample_calling", default = true)
var reference: File = config("reference", required = true)
var reference: File = config("reference")
var useAllelesOption: Boolean = config("use_alleles_option", default = false)
val externalGvcfs = config("external_gvcfs_files", default = Nil).asFileList
def makeSample(id: String) = new Sample(id)
class Sample(sampleId: String) extends AbstractSample(sampleId) {
def makeLibrary(id: String) = new Library(id)
class Library(libraryId: String) extends AbstractLibrary(libraryId) {
class Library(libId: String) extends AbstractLibrary(libId) {
val mapping = new Mapping(qscript)
mapping.sampleId = sampleId
mapping.libraryId = libraryId
mapping.libId = libId
mapping.outputDir = libDir + "/variantcalling/"
/** Library variantcalling */
......@@ -66,8 +66,8 @@ class GatkPipeline(val root: Configurable) extends QScript with MultiSampleQScri
if (!bamFile.exists) throw new IllegalStateException("Bam in config does not exist, file: " + bamFile)
if (config("bam_to_fastq", default = false).asBoolean) {
val samToFastq = SamToFastq(qscript, bamFile, libDir + sampleId + "-" + libraryId + ".R1.fastq",
libDir + sampleId + "-" + libraryId + ".R2.fastq")
val samToFastq = SamToFastq(qscript, bamFile, libDir + sampleId + "-" + libId + ".R1.fastq",
libDir + sampleId + "-" + libId + ".R2.fastq")
samToFastq.isIntermediate = true
qscript.add(samToFastq)
mapping.input_R1 = samToFastq.fastqR1
......@@ -82,17 +82,17 @@ class GatkPipeline(val root: Configurable) extends QScript with MultiSampleQScri
val header = inputSam.getFileHeader.getReadGroups
for (readGroup <- inputSam.getFileHeader.getReadGroups) {
if (readGroup.getSample != sampleId) logger.warn("Sample ID readgroup in bam file is not the same")
if (readGroup.getLibrary != libraryId) logger.warn("Library ID readgroup in bam file is not the same")
if (readGroup.getSample != sampleId || readGroup.getLibrary != libraryId) readGroupOke = false
if (readGroup.getLibrary != libId) logger.warn("Library ID readgroup in bam file is not the same")
if (readGroup.getSample != sampleId || readGroup.getLibrary != libId) readGroupOke = false
}
inputSam.close
if (!readGroupOke) {
if (config("correct_readgroups", default = false)) {
logger.info("Correcting readgroups, file:" + bamFile)
val aorrg = AddOrReplaceReadGroups(qscript, bamFile, new File(libDir + sampleId + "-" + libraryId + ".bam"))
aorrg.RGID = sampleId + "-" + libraryId
aorrg.RGLB = libraryId
val aorrg = AddOrReplaceReadGroups(qscript, bamFile, new File(libDir + sampleId + "-" + libId + ".bam"))
aorrg.RGID = sampleId + "-" + libId
aorrg.RGLB = libId
aorrg.RGSM = sampleId
aorrg.isIntermediate = true
qscript.add(aorrg)
......@@ -105,7 +105,7 @@ class GatkPipeline(val root: Configurable) extends QScript with MultiSampleQScri
Some(bamFile)
}
} else {
logger.error("Sample: " + sampleId + ": No R1 found for run: " + libraryId)
logger.error("Sample: " + sampleId + ": No R1 found for run: " + libId)
None
}
......
......@@ -30,7 +30,7 @@ class GatkVariantcalling(val root: Configurable) extends QScript with BiopetQScr
var rawVcfInput: File = _
@Argument(doc = "Reference", shortName = "R", required = false)
var reference: File = config("reference", required = true)
var reference: File = config("reference")
@Argument(doc = "OutputName", required = false)
var outputName: String = _
......
......@@ -78,7 +78,7 @@ trait BiopetCommandLineFunctionTrait extends CommandLineFunction with Configurab
/**
* Checks executable. Follow full CanonicalPath, checks if it is existing and do a md5sum on it to store in job report
*/
protected def checkExecutable {
protected[core] def checkExecutable {
if (!BiopetCommandLineFunctionTrait.executableMd5Cache.contains(executable)) {
try if (executable != null) {
if (!BiopetCommandLineFunctionTrait.executableCache.contains(executable)) {
......@@ -91,8 +91,7 @@ trait BiopetCommandLineFunctionTrait extends CommandLineFunction with Configurab
val file = new File(executable)
executable = file.getCanonicalPath
} else {
logger.error("executable: '" + executable + "' not found, please check config")
throw new QException("executable: '" + executable + "' not found, please check config")
BiopetQScript.addError("executable: '" + executable + "' not found, please check config")
}
BiopetCommandLineFunctionTrait.executableCache += oldExecutable -> executable
BiopetCommandLineFunctionTrait.executableCache += executable -> executable
......@@ -113,9 +112,8 @@ trait BiopetCommandLineFunctionTrait extends CommandLineFunction with Configurab
case ioe: java.io.IOException => logger.warn("Could not use 'which', check on executable skipped: " + ioe)
}
}
val md5 = BiopetCommandLineFunctionTrait.executableMd5Cache(executable)
if (md5 == null) addJobReportBinding("md5sum_exe", md5)
else addJobReportBinding("md5sum_exe", "None")
val md5 = BiopetCommandLineFunctionTrait.executableMd5Cache.get(executable)
addJobReportBinding("md5sum_exe", md5.getOrElse("None"))
}
/**
......@@ -145,6 +143,8 @@ trait BiopetCommandLineFunctionTrait extends CommandLineFunction with Configurab
/** Executes the version command */
private def getVersionInternal: String = {
if (versionCommand == null || versionRegex == null) return "N/A"
val exe = new File(versionCommand.trim.split(" ")(0))
if (!exe.exists()) return "N/A"
val stdout = new StringBuffer()
val stderr = new StringBuffer()
def outputLog = "Version command: \n" + versionCommand +
......@@ -206,4 +206,4 @@ object BiopetCommandLineFunctionTrait {
private val versionCache: Map[String, String] = Map()
private val executableMd5Cache: Map[String, String] = Map()
private val executableCache: Map[String, String] = Map()
}
\ No newline at end of file
}
......@@ -23,6 +23,7 @@ import org.broadinstitute.gatk.queue.QSettings
import org.broadinstitute.gatk.queue.function.QFunction
import org.broadinstitute.gatk.queue.function.scattergather.ScatterGatherableFunction
import org.broadinstitute.gatk.queue.util.{ Logging => GatkLogging }
import scala.collection.mutable.ListBuffer
/**
* Base for biopet pipeline
......@@ -33,8 +34,8 @@ trait BiopetQScript extends Configurable with GatkLogging {
val configfiles: List[File] = Nil
var outputDir: String = {
val temp = Config.getValueFromMap(Config.global.map, ConfigValueIndex(this.configName, configPath, "output_dir"))
if (temp.isEmpty) throw new IllegalArgumentException("No output_dir defined in config")
val temp = Config.getValueFromMap(globalConfig.map, ConfigValueIndex(this.configName, configPath, "output_dir"))
if (temp.isEmpty) ""
else {
val t = temp.get.value.toString
if (!t.endsWith("/")) t + "/" else t
......@@ -62,8 +63,9 @@ trait BiopetQScript extends Configurable with GatkLogging {
* Script from queue itself, final to force some checks for each pipeline and write report
*/
final def script() {
outputDir = config("output_dir", required = true)
if (!outputDir.endsWith("/")) outputDir += "/"
outputDir = config("output_dir")
if (outputDir.isEmpty) outputDir = new File(".").getAbsolutePath()
else if (!outputDir.endsWith("/")) outputDir += "/"
init
biopetScript
......@@ -72,11 +74,17 @@ trait BiopetQScript extends Configurable with GatkLogging {
case _ =>
}
for (function <- functions) function match {
case f: BiopetCommandLineFunctionTrait => f.afterGraph
case _ =>
case f: BiopetCommandLineFunctionTrait => {
f.checkExecutable
f.afterGraph
}
case _ =>
}
Config.global.writeReport(qSettings.runName, outputDir + ".log/" + qSettings.runName)
if (new File(outputDir).canWrite) globalConfig.writeReport(qSettings.runName, outputDir + ".log/" + qSettings.runName)
else BiopetQScript.addError("Output dir: '" + outputDir + "' is not writeable")
BiopetQScript.checkErrors
}
/** Get implemented from org.broadinstitute.gatk.queue.QScript */
......@@ -92,3 +100,28 @@ trait BiopetQScript extends Configurable with GatkLogging {
add(function)
}
}
object BiopetQScript extends Logging {
private val errors: ListBuffer[Exception] = ListBuffer()
def addError(error: String, debug: String = null): Unit = {
val msg = error + (if (debug != null && logger.isDebugEnabled) "; " + debug else "")
errors.append(new Exception(msg))
}
protected def checkErrors: Unit = {
if (!errors.isEmpty) {
logger.error("*************************")
logger.error("Biopet found some errors:")
if (logger.isDebugEnabled) {
for (e <- errors) {
logger.error(e.getMessage)
logger.debug(e.getStackTrace.mkString("Stack trace:\n", "\n", "\n"))
}
} else {
errors.map(_.getMessage).sorted.distinct.foreach(logger.error(_))
}
throw new IllegalStateException("Biopet found errors")
}
}
}
......@@ -28,7 +28,7 @@ trait MultiSampleQScript extends BiopetQScript {
@Argument(doc = "Only Sample", shortName = "sample", required = false)
private val onlySamples: List[String] = Nil
require(Config.global.map.contains("samples"), "No Samples found in config")
require(globalConfig.map.contains("samples"), "No Samples found in config")
/**
* Sample class with basic functions build in
......@@ -40,26 +40,26 @@ trait MultiSampleQScript extends BiopetQScript {
/**
* Library class with basic functions build in
* @param libraryId
* @param libId
*/
abstract class AbstractLibrary(val libraryId: String) {
abstract class AbstractLibrary(val libId: String) {
/** Overrules config of qscript with default sample and default library */
val config = new ConfigFunctions(defaultSample = sampleId, defaultLibrary = libraryId)
val config = new ConfigFunctions(defaultSample = sampleId, defaultLibrary = libId)
/** Adds the library jobs */
final def addAndTrackJobs(): Unit = {
currentSample = Some(sampleId)
currentLib = Some(libraryId)
currentLib = Some(libId)
addJobs()
currentLib = None
currentSample = None
}
/** Creates a library file with given suffix */
def createFile(suffix: String): File = new File(libDir, sampleId + "-" + libraryId + suffix)
def createFile(suffix: String): File = new File(libDir, sampleId + "-" + libId + suffix)
/** Returns library directory */
def libDir = sampleDir + "lib_" + libraryId + File.separator
def libDir = sampleDir + "lib_" + libId + File.separator
/** Function that add library jobs */
protected def addJobs()
......@@ -80,7 +80,7 @@ trait MultiSampleQScript extends BiopetQScript {
/** returns a set with library names */
protected def libIds: Set[String] = {
ConfigUtils.getMapFromPath(Config.global.map, List("samples", sampleId, "libraries")).getOrElse(Map()).keySet
ConfigUtils.getMapFromPath(globalConfig.map, List("samples", sampleId, "libraries")).getOrElse(Map()).keySet
}
/** Adds sample jobs */
......@@ -95,7 +95,7 @@ trait MultiSampleQScript extends BiopetQScript {
/** function add all libraries in one call */
protected final def addPerLibJobs(): Unit = {
for ((libraryId, library) <- libraries) {
for ((libId, library) <- libraries) {
library.addAndTrackJobs()
}
}
......@@ -125,7 +125,7 @@ trait MultiSampleQScript extends BiopetQScript {
val samples: Map[String, Sample] = sampleIds.map(id => id -> makeSample(id)).toMap
/** Returns a list of all sampleIDs */
protected def sampleIds: Set[String] = ConfigUtils.any2map(Config.global.map("samples")).keySet
protected def sampleIds: Set[String] = ConfigUtils.any2map(globalConfig.map("samples")).keySet
/** Runs addAndTrackJobs method for each sample */
final def addSamplesJobs() {
......
......@@ -133,11 +133,11 @@ class Config(var map: Map[String, Any]) extends Logging {
*/
protected[config] def apply(module: String, path: List[String], key: String, default: Any = null, freeVar: Boolean = true): ConfigValue = {
val requestedIndex = ConfigValueIndex(module, path, key, freeVar)
if (contains(requestedIndex)) return foundCache(requestedIndex)
if (contains(requestedIndex)) foundCache(requestedIndex)
else if (default != null) {
defaultCache += (requestedIndex -> ConfigValue(requestedIndex, null, default, freeVar))
return defaultCache(requestedIndex)
} else throw new IllegalStateException("Value in config could not be found but it seems required, index: " + requestedIndex)
defaultCache(requestedIndex)
} else ConfigValue(requestedIndex, null, null, freeVar)
}
def writeReport(id: String, directory: String): Unit = {
......@@ -174,7 +174,7 @@ class Config(var map: Map[String, Any]) extends Logging {
val fullEffective = ConfigUtils.mergeMaps(effectiveFound, effectiveDefaultFound)
val fullEffectiveWithNotFound = ConfigUtils.mergeMaps(fullEffective, notFound)
writeMapToJsonFile(Config.global.map, "input")
writeMapToJsonFile(this.map, "input")
writeMapToJsonFile(found, "found")
writeMapToJsonFile(effectiveFound, "effective.found")
writeMapToJsonFile(effectiveDefaultFound, "effective.defaults")
......
......@@ -21,6 +21,7 @@ import nl.lumc.sasc.biopet.utils.ConfigUtils.ImplicitConversions
trait Configurable extends ImplicitConversions {
/** Should be object of parant object */
val root: Configurable
val globalConfig: Config = if (root != null) root.globalConfig else Config.global
/** subfix to the path */
def subPath: List[String] = Nil
......@@ -79,7 +80,6 @@ trait Configurable extends ImplicitConversions {
* @param key Name of value
* @param default Default value if not found
* @param submodule Adds to the path
* @param required Default false, if true and value is not found this function will raise an exception
* @param freeVar Default true, if set false value must exist in module
* @param sample Default null, when set path is prefixed with "samples" -> "sampleID"
* @param library Default null, when set path is prefixed with "libraries" -> "libraryID"
......@@ -88,7 +88,6 @@ trait Configurable extends ImplicitConversions {
def apply(key: String,
default: Any = null,
submodule: String = null,
required: Boolean = false,
freeVar: Boolean = true,
sample: String = null,
library: String = null): ConfigValue = {
......@@ -100,14 +99,8 @@ trait Configurable extends ImplicitConversions {
val value = Config.getValueFromMap(defaults.toMap, ConfigValueIndex(m, p, key, freeVar))
if (value.isDefined) value.get.value else default
}
if (!contains(key, submodule, freeVar, sample = s, library = l) && d == null) {
if (required) {
Logging.logger.error("Value in config could not be found but it is required, key: " + key + " module: " + m + " path: " + p)
throw new IllegalStateException("Value in config could not be found but it is required, key: " + key + " module: " + m + " path: " + p)
} else return null
}
if (d == null) return Config.global(m, p, key, freeVar = freeVar)
else return Config.global(m, p, key, d, freeVar)
if (d == null) globalConfig(m, p, key, freeVar = freeVar)
else globalConfig(m, p, key, d, freeVar)
}
/**
......@@ -129,7 +122,7 @@ trait Configurable extends ImplicitConversions {
val m = if (submodule != null) submodule else configName
val p = path(s, l, submodule)
Config.global.contains(m, p, key, freeVar) || !(Config.getValueFromMap(defaults.toMap, ConfigValueIndex(m, p, key, freeVar)) == None)
globalConfig.contains(m, p, key, freeVar) || !(Config.getValueFromMap(defaults.toMap, ConfigValueIndex(m, p, key, freeVar)) == None)
}
}
}
......@@ -83,19 +83,15 @@ object BiopetQCommandLine extends GatkLogging {
Runtime.getRuntime.addShutdownHook(shutdownHook)
CommandLineProgram.start(qCommandLine, argv)
try {
CommandLineProgram.start(qCommandLine, argv)
try {
Runtime.getRuntime.removeShutdownHook(shutdownHook)
qCommandLine.shutdown()
} catch {
case e: Exception => /* ignore, example 'java.lang.IllegalStateException: Shutdown in progress' */
}
if (CommandLineProgram.result != 0)
System.exit(CommandLineProgram.result)
Runtime.getRuntime.removeShutdownHook(shutdownHook)
qCommandLine.shutdown()
} catch {
case e: Exception => CommandLineProgram.exitSystemWithError(e)
case e: Exception => /* ignore, example 'java.lang.IllegalStateException: Shutdown in progress' */
}
if (CommandLineProgram.result != 0)
System.exit(CommandLineProgram.result)
}
}
......@@ -116,21 +112,28 @@ class BiopetQCommandLine extends CommandLineProgram with Logging {
private var qScriptClasses: File = _
private var shuttingDown = false
/**
* we modified this in Biopet to skip compiling and show full stacktrace again
*/
private lazy val qScriptPluginManager = {
qScriptClasses = IOUtils.tempDir("Q-Classes-", "", settings.qSettings.tempDirectory)
//qScriptManager.loadScripts(scripts, qScriptClasses)
//var temp: Seq[URL] = Seq()
for (t <- scripts) {
val is = getClass.getResourceAsStream(t.getAbsolutePath)
val os = new FileOutputStream(qScriptClasses.getAbsolutePath + "/" + t.getName)
org.apache.commons.io.IOUtils.copy(is, os)
os.close()
//temp :+= this.getClass.getResource(t.toString)
//logger.info(this.getClass.getResource(t.toString))
val s = if (t.getName.endsWith("/")) t.getName.substring(0, t.getName.length - 1) else t.getName
pipelineName = s.substring(0, s.lastIndexOf(".")) + "." + System.currentTimeMillis
}
new PluginManager[QScript](qPluginType, List(qScriptClasses.toURI.toURL))
// override createByType to pass the correct exceptions
new PluginManager[QScript](qPluginType, List(qScriptClasses.toURI.toURL)) {
override def createByType(plugintype: Class[_ <: QScript]) = {
val noArgsConstructor = plugintype.getDeclaredConstructor()
noArgsConstructor.setAccessible(true)
noArgsConstructor.newInstance()
}
}
}
private lazy val qCommandPlugin = {
......@@ -188,12 +191,7 @@ class BiopetQCommandLine extends CommandLineProgram with Logging {
//if (settings.run)
script.pullInputs()
script.qSettings = settings.qSettings
try {
script.script()
} catch {
case e: Exception =>
throw new UserException.CannotExecuteQScript(script.getClass.getSimpleName + ".script() threw the following exception: " + e, e)
}
script.script()
if (remoteFileConverter != null) {
if (remoteFileConverter.convertToRemoteEnabled)
......
......@@ -29,7 +29,7 @@ class Bowtie(val root: Configurable) extends BiopetCommandLineFunction {
var R2: File = _
@Input(doc = "The reference file for the bam files.", shortName = "R")
var reference: File = config("reference", required = true)
var reference: File = config("reference")
@Output(doc = "Output file SAM", shortName = "output")
var output: File = _
......
......@@ -25,16 +25,16 @@ import nl.lumc.sasc.biopet.core.config.Configurable
class Fastqc(val root: Configurable) extends BiopetCommandLineFunction {
@Input(doc = "Contaminants", required = false)
var contaminants: File = _
var contaminants: Option[File] = None
@Input(doc = "Adapters", required = false)
var adapters: File = _
var adapters: Option[File] = None
@Input(doc = "Fastq file", shortName = "FQ")
var fastqfile: File = _
var fastqfile: File = null
@Output(doc = "Output", shortName = "out")
var output: File = _
var output: File = null
executable = config("exe", default = "fastqc")
var java_exe: String = config("exe", default = "java", submodule = "java", freeVar = false)
......@@ -50,17 +50,31 @@ class Fastqc(val root: Configurable) extends BiopetCommandLineFunction {
override def afterGraph {
this.checkExecutable
if (contaminants == null) {
val fastqcDir = executable.substring(0, executable.lastIndexOf("/"))
val defaultContams = getVersion match {
case "v0.11.2" => new File(fastqcDir + "/Configuration/contaminant_list.txt")
case _ => new File(fastqcDir + "/Contaminants/contaminant_list.txt")
}
val defaultAdapters = getVersion match {
case "v0.11.2" => new File(fastqcDir + "/Configuration/adapter_list.txt")
case _ => null
}
contaminants = config("contaminants", default = defaultContams)
val fastqcDir = new File(executable).getParent
contaminants = contaminants match {
// user-defined contaminants file take precedence
case userDefinedValue @ Some(_) => userDefinedValue
// otherwise, use default contaminants file (depending on FastQC version)
case None =>
val defaultContams = getVersion match {
case "v0.11.2" => new File(fastqcDir + "/Configuration/contaminant_list.txt")
case _ => new File(fastqcDir + "/Contaminants/contaminant_list.txt")
}
config("contaminants", default = defaultContams)
}
adapters = adapters match {
// user-defined contaminants file take precedence
case userDefinedValue @ Some(_) => userDefinedValue
// otherwise, check if adapters are already present (depending on FastQC version)
case None =>
val defaultAdapters = getVersion match {
case "v0.11.2" => Option(new File(fastqcDir + "/Configuration/adapter_list.txt"))
case _ => None
}
defaultAdapters.collect { case adp => config("adapters", default = adp) }
}
}
......@@ -74,6 +88,6 @@ class Fastqc(val root: Configurable) extends BiopetCommandLineFunction {
conditional(noextract, "--noextract") +
conditional(extract, "--extract") +
conditional(quiet, "--quiet") +
required("-o", output.getParent()) +
required("-o", output.getParent) +
required(fastqfile)
}
......@@ -50,6 +50,8 @@ class Raxml(val root: Configurable) extends BiopetCommandLineFunction {
@Argument(doc = "Output directory", required = true)
var w: String = _
var noBfgs: Boolean = config("no_bfgs", default = false)
@Input(required = false)
var t: File = _