Commit 26269612 authored by Sander Bollen's avatar Sander Bollen Committed by GitHub
Browse files

Merge pull request #15 from biopet/release-0.8.0

Release 0.8.0
parents cb7a051c 70f92987
[submodule "gatk"]
path = gatk
url = https://github.com/biopet/gatk.git
node('local') {
try {
stage('Init') {
tool 'JDK 8u102'
tool 'Apache Maven 3.3.9'
}
stage('Checkout') {
checkout scm
sh 'git submodule update --init --recursive'
}
stage('Build and Test') {
withMaven(maven: 'Apache Maven 3.3.9', jdk: 'JDK 8u102') {
sh 'mvn -B -T 2 -Dmaven.test.failure.ignore clean package'
}
}
stage('Report tests') {
junit '*/target/surefire-reports/*.xml'
}
if(currentBuild.result == null || "SUCCESS".equals(currentBuild.result)) {
currentBuild.result = "SUCCESS"
slackSend (color: '#00FF00', message: "${currentBuild.result}: Job '${env.JOB_NAME} #${env.BUILD_NUMBER}' (<${env.BUILD_URL}|Open>)", channel: '#biopet-bot', teamDomain: 'lumc', tokenCredentialId: 'lumc')
} else {
slackSend (color: '#FFFF00', message: "${currentBuild.result}: Job '${env.JOB_NAME} #${env.BUILD_NUMBER}' (<${env.BUILD_URL}|Open>)", channel: '#biopet-bot', teamDomain: 'lumc', tokenCredentialId: 'lumc')
}
} catch (e) {
if(currentBuild.result == null || "FAILED".equals(currentBuild.result)) {
currentBuild.result = "FAILED"
}
slackSend (color: '#FF0000', message: "${currentBuild.result}: Job '${env.JOB_NAME} #${env.BUILD_NUMBER}' (<${env.BUILD_URL}|Open>)", channel: '#biopet-bot', teamDomain: 'lumc', tokenCredentialId: 'lumc')
throw e
}
}
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
Biopet (Bio Pipeline Execution Toolkit) is the main pipeline development framework of the LUMC Sequencing Analysis Support Core team. It contains our main pipelines and some of the command line tools we develop in-house. It is meant to be used in the main [SHARK](https://humgenprojects.lumc.nl/trac/shark) computing cluster. While usage outside of SHARK is technically possible, some adjustments may need to be made in order to do so. Biopet (Bio Pipeline Execution Toolkit) is the main pipeline development framework of the LUMC Sequencing Analysis Support Core team. It contains our main pipelines and some of the command line tools we develop in-house. It is meant to be used in the main [SHARK](https://humgenprojects.lumc.nl/trac/shark) computing cluster. While usage outside of SHARK is technically possible, some adjustments may need to be made in order to do so.
Full documantation is here: [Biopet documantation](http://biopet-docs.readthedocs.io/en/latest/)
## Quick Start ## Quick Start
...@@ -13,7 +14,7 @@ Biopet (Bio Pipeline Execution Toolkit) is the main pipeline development framewo ...@@ -13,7 +14,7 @@ Biopet (Bio Pipeline Execution Toolkit) is the main pipeline development framewo
Biopet is available as a JAR package in SHARK. The easiest way to start using it is to activate the `biopet` environment module, which sets useful aliases and environment variables: Biopet is available as a JAR package in SHARK. The easiest way to start using it is to activate the `biopet` environment module, which sets useful aliases and environment variables:
~~~ ~~~
$ module load biopet/v0.6.0 $ module load biopet/v0.8.0
~~~ ~~~
With each Biopet release, an accompanying environment module is also released. The latest release is version 0.4.0, thus `biopet/v0.4.0` is the module you would want to load. With each Biopet release, an accompanying environment module is also released. The latest release is version 0.4.0, thus `biopet/v0.4.0` is the module you would want to load.
...@@ -48,9 +49,9 @@ $ biopet pipeline <pipeline_name> -config <path/to/config.json> -qsub -jobParaEn ...@@ -48,9 +49,9 @@ $ biopet pipeline <pipeline_name> -config <path/to/config.json> -qsub -jobParaEn
It is usually a good idea to do the real run using `screen` or `nohup` to prevent the job from terminating when you log out of SHARK. In practice, using `biopet` as it is is also fine. What you need to keep in mind, is that each pipeline has their own expected config layout. You can check out more about the general structure of our config files [here](docs/config.md). For the specific structure that each pipeline accepts, please consult the respective pipeline page. It is usually a good idea to do the real run using `screen` or `nohup` to prevent the job from terminating when you log out of SHARK. In practice, using `biopet` as it is is also fine. What you need to keep in mind, is that each pipeline has their own expected config layout. You can check out more about the general structure of our config files [here](docs/config.md). For the specific structure that each pipeline accepts, please consult the respective pipeline page.
### Running Biopet in your own computer ## Testing
At the moment, we do not provide links to download the Biopet package. If you are interested in trying out Biopet locally, please contact us as [sasc@lumc.nl](mailto:sasc@lumc.nl). Our code is tested at our local Jenkins installation for every change. We are using a [JenkinsFile](Jenkinsfile) in our repository to do this.
## Contributing to Biopet ## Contributing to Biopet
...@@ -59,27 +60,7 @@ Biopet is based on the Queue framework developed by the Broad Institute as part ...@@ -59,27 +60,7 @@ Biopet is based on the Queue framework developed by the Broad Institute as part
We welcome any kind of contribution, be it merge requests on the code base, documentation updates, or any kinds of other fixes! The main language we use is Scala, though the repository also contains a small bit of Python and R. Our main code repository is located at [https://github.com/biopet/biopet](https://github.com/biopet/biopet/issues), along with our issue tracker. We welcome any kind of contribution, be it merge requests on the code base, documentation updates, or any kinds of other fixes! The main language we use is Scala, though the repository also contains a small bit of Python and R. Our main code repository is located at [https://github.com/biopet/biopet](https://github.com/biopet/biopet/issues), along with our issue tracker.
## Local development setup For more information please go to our [Developer documantation](http://biopet-docs.readthedocs.io/en/develop/developer/getting-started/)
To develop Biopet, Java 7, Maven 3.3.3, and GATK Queue 3.5 is required. Please consult the Java homepage and Maven homepage for the respective installation instruction. After you have both Java and Maven installed, you would then need to install GATK Queue. However, as the GATK Queue package is not yet available as an artifact in Maven Central, you will need to download, compile, and install GATK Queue first.
~~~
$ git clone https://github.com/broadgsa/gatk-protected
$ cd gatk
$ git checkout 3.5 # the current release is based on GATK 3.5
$ mvn -U clean install
~~~
This will install all the required dependencies to your local maven repository. After this is done, you can clone our repository and test if everything builds fine:
~~~
$ git clone https://github.com/biopet/biopet.git
$ cd biopet
$ mvn -U clean install
~~~
If everything builds fine, you're good to go! Otherwise, don't hesitate to contact us or file an issue at our issue tracker.
## About ## About
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
<parent> <parent>
<groupId>nl.lumc.sasc</groupId> <groupId>nl.lumc.sasc</groupId>
<artifactId>Biopet</artifactId> <artifactId>Biopet</artifactId>
<version>0.7.0</version> <version>0.8.0</version>
<relativePath>../</relativePath> <relativePath>../</relativePath>
</parent> </parent>
......
...@@ -68,8 +68,6 @@ object Bam2Wig extends PipelineCommand { ...@@ -68,8 +68,6 @@ object Bam2Wig extends PipelineCommand {
val bamToBigWig = new Bam2Wig(root) val bamToBigWig = new Bam2Wig(root)
bamToBigWig.outputDir = bamFile.getParentFile bamToBigWig.outputDir = bamFile.getParentFile
bamToBigWig.bamFile = bamFile bamToBigWig.bamFile = bamFile
bamToBigWig.init()
bamToBigWig.biopetScript()
bamToBigWig bamToBigWig
} }
} }
\ No newline at end of file
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
<parent> <parent>
<groupId>nl.lumc.sasc</groupId> <groupId>nl.lumc.sasc</groupId>
<artifactId>Biopet</artifactId> <artifactId>Biopet</artifactId>
<version>0.7.0</version> <version>0.8.0</version>
<relativePath>../</relativePath> <relativePath>../</relativePath>
</parent> </parent>
......
...@@ -83,10 +83,10 @@ ...@@ -83,10 +83,10 @@
#if (!sampleLevel) <td><a href="${rootPath}Samples/${sample}/Libraries/${libId}/index.html">${libId}</a></td> #end #if (!sampleLevel) <td><a href="${rootPath}Samples/${sample}/Libraries/${libId}/index.html">${libId}</a></td> #end
#{ #{
val prefixPath = List("samples", sample) ::: (if (libId.isEmpty) Nil else List("libraries", libId)) ::: List("bammetrics", "stats") val prefixPath = List("samples", sample) ::: (if (libId.isEmpty) Nil else List("libraries", libId)) ::: List("bammetrics", "stats")
val total = summary.getValue((prefixPath ::: List("biopet_flagstat", "All")):_*).getOrElse(0L).asInstanceOf[Long] val total = summary.getValue((prefixPath ::: List("bamstats", "flagstats", "All")):_*).getOrElse(0L).asInstanceOf[Long]
val mapped = summary.getValue((prefixPath ::: List("biopet_flagstat", "Mapped")):_*).getOrElse(0L).asInstanceOf[Long] val mapped = summary.getValue((prefixPath ::: List("bamstats", "flagstats", "Mapped")):_*).getOrElse(0L).asInstanceOf[Long]
val duplicates = summary.getValue((prefixPath ::: List("biopet_flagstat", "Duplicates")):_*).getOrElse(0L).asInstanceOf[Long] val duplicates = summary.getValue((prefixPath ::: List("bamstats", "flagstats", "Duplicates")):_*).getOrElse(0L).asInstanceOf[Long]
val secondary = summary.getValue((prefixPath ::: List("biopet_flagstat", "NotPrimaryAlignment")):_*).getOrElse(0L).asInstanceOf[Long] val secondary = summary.getValue((prefixPath ::: List("bamstats", "flagstats", "NotPrimaryAlignment")):_*).getOrElse(0L).asInstanceOf[Long]
}# }#
<td>${total}</td> <td>${total}</td>
<td>${mapped}</td> <td>${mapped}</td>
......
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
#for (field <- fields) #for (field <- fields)
<tr><th>${field}</th><td> <tr><th>${field}</th><td>
#if (libId.isDefined) #if (libId.isDefined)
${summary.getLibraryValue(sampleId.get, libId.get, metricsTag, "stats", "biopet_flagstat", field)} ${summary.getLibraryValue(sampleId.get, libId.get, metricsTag, "stats", "bamstats", "flagstats", field)}
#else #else
${summary.getSampleValue(sampleId.get, metricsTag, "stats", "biopet_flagstat", field)} ${summary.getSampleValue(sampleId.get, metricsTag, "stats", "bamstats", "flagstats", field)}
#end #end
</td></tr> </td></tr>
#end #end
......
#import(nl.lumc.sasc.biopet.utils.summary.Summary)
#import(nl.lumc.sasc.biopet.core.report.ReportPage)
#import(nl.lumc.sasc.biopet.pipelines.bammetrics.BammetricsReport)
#import(java.io.File)
#import(org.apache.commons.io.FileUtils)
<%@ var summary: Summary %>
<%@ var sampleId: Option[String] = None %>
<%@ var libId: Option[String] = None %>
<%@ var rootPath: String %>
<%@ var metricsTag: String = "bammetrics" %>
<%@ var sampleLevel: Boolean = false %>
<%@ var outputDir: File %>
<%@ var fields: List[String] = List("min", "max", "mean", "median", "modal")%>
<%@ var showPlot: Boolean = false %>
<%@ var showTable: Boolean = true %>
<%@ var showIntro: Boolean = true%>
#{
val samples = sampleId match {
case Some(sample) => {
List(sample.toString)
}
case _ => summary.samples.toList
}
}#
#if (showIntro)
<br/>
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-6">
<p>
#if (sampleId.isDefined && libId.isDefined)
This plot shows the clipping distribution for library <b>${libId}</b> of sample <b>${sampleId}</b>.
#elseif(sampleId.isDefined)
This plot shows the clipping distribution for the libraries of sample <b>${sampleId}</b>.
#else
This plot shows the clipping distribution for each of the <b>${samples.size}</b> samples.
#end
</p>
</div>
</div>
#end
#if (showPlot)
#{ BammetricsReport.clippingPlot(outputDir, "clipping", summary, !sampleLevel, sampleId = sampleId, libId = libId) }#
<div class="panel-body">
<img src="clipping.png" class="img-responsive" />
</div>
<div class="panel-footer">
#if (showTable)
<button type="button" class="btn btn-info" data-toggle="collapse" data-target="#clippingTable">
<i class="glyphicon glyphicon-eye-close"></i> Hide table</button>
#else
<button type="button" class="btn btn-info" data-toggle="collapse" data-target="#clippingTable">
<i class="glyphicon glyphicon-eye-open"></i> Show table</button>
#end
<a href="clipping.tsv"><button type="button" class="btn btn-info"><i class="glyphicon glyphicon-cloud-download"></i>TSV file</button></a>
</div>
#end
<div class="panel-body collapse #if (showTable)in#end" id="clippingTable">
<!-- Table -->
<table class="table">
<thead><tr>
<th data-sorted="true" data-sorted-direction="ascending">Sample</th>
#if (!sampleLevel) <th>Library</th> #end
#for (field <- fields)
<th>${field.replaceAll("_", " ")}</th>
#end
</tr></thead>
<tbody>
#for (sample <- samples.toList.sorted)
#{
val libs = (libId, sampleLevel) match {
case (_, true) => List("")
case (Some(libId), _) => List(libId.toString)
case _ => summary.libraries(sample).toList
}
}#
<tr><td rowspan="${libs.size}"><a href="${rootPath}Samples/${sample}/index.html">${sample}</a></td>
#for (libId <- libs)
#if (libs.head != libId) <tr> #end
#if (!sampleLevel) <td><a href="${rootPath}Samples/${sample}/Libraries/${libId}/index.html">${libId}</a></td> #end
#{
val prefixPath = List("samples", sample) ::: (if (libId.isEmpty) Nil else List("libraries", libId)) ::: List("bammetrics", "stats")
val fieldValues = for (field <- fields) yield {
summary.getValue((prefixPath ::: List("bamstats", "clipping", "general", field)):_*).getOrElse("N/A")
}
}#
#for (value <- fieldValues)
<td>${value}</td>
#end
</tr>
#end
#end
</tbody>
</table>
</div>
...@@ -51,12 +51,12 @@ ...@@ -51,12 +51,12 @@
<div class="panel-footer"> <div class="panel-footer">
#if (showTable) #if (showTable)
<button type="button" class="btn btn-info" data-toggle="collapse" data-target="#insertsizeTable"> <button type="button" class="btn btn-info" data-toggle="collapse" data-target="#insertsizeTable">
<i class="glyphicon glyphicon-eye-close"></i> Hide table</button> <i class="glyphicon glyphicon-eye-close"></i>Hide table</button>
#else #else
<button type="button" class="btn btn-info" data-toggle="collapse" data-target="#insertsizeTable"> <button type="button" class="btn btn-info" data-toggle="collapse" data-target="#insertsizeTable">
<i class="glyphicon glyphicon-eye-open"></i> Show table</button> <i class="glyphicon glyphicon-eye-open"></i>Show table</button>
#end #end
<button type="button" class="btn btn-info"><i class="glyphicon glyphicon-cloud-download"> <a href="insertsize.tsv">tsv file</a></i></button> <a href="insertsize.tsv"><button type="button" class="btn btn-info"><i class="glyphicon glyphicon-cloud-download"></i>TSV file</button></a>
</div> </div>
#end #end
......
#import(nl.lumc.sasc.biopet.utils.summary.Summary)
#import(nl.lumc.sasc.biopet.core.report.ReportPage)
#import(nl.lumc.sasc.biopet.pipelines.bammetrics.BammetricsReport)
#import(java.io.File)
#import(org.apache.commons.io.FileUtils)
<%@ var summary: Summary %>
<%@ var sampleId: Option[String] = None %>
<%@ var libId: Option[String] = None %>
<%@ var rootPath: String %>
<%@ var metricsTag: String = "bammetrics" %>
<%@ var sampleLevel: Boolean = false %>
<%@ var outputDir: File %>
<%@ var fields: List[String] = List("min", "max", "mean", "median", "modal")%>
<%@ var showPlot: Boolean = false %>
<%@ var showTable: Boolean = true %>
<%@ var showIntro: Boolean = true%>
#{
val samples = sampleId match {
case Some(sample) => {
List(sample.toString)
}
case _ => summary.samples.toList
}
}#
#if (showIntro)
<br/>
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-6">
<p>
#if (sampleId.isDefined && libId.isDefined)
This plot shows the mapping quality distribution for all libraries combined in sample <b>${sampleId}</b>.
#elseif(sampleId.isDefined)
This plot shows the mapping quality distribution for the libraries of sample <b>${sampleId}</b>.
#else
This plot shows the mapping quality distribution for each of the <b>${samples.size}</b> samples.
#end
</p>
</div>
</div>
#end
#if (showPlot)
#{ BammetricsReport.mappingQualityPlot(outputDir, "mapping_quality", summary, !sampleLevel, sampleId = sampleId, libId = libId) }#
<div class="panel-body">
<img src="mapping_quality.png" class="img-responsive" />
</div>
<div class="panel-footer">
#if (showTable)
<button type="button" class="btn btn-info" data-toggle="collapse" data-target="#mapping_qualityTable">
<i class="glyphicon glyphicon-eye-close"></i> Hide table</button>
#else
<button type="button" class="btn btn-info" data-toggle="collapse" data-target="#mapping_qualityTable">
<i class="glyphicon glyphicon-eye-open"></i> Show table</button>
#end
<a href="mapping_quality.tsv"><button type="button" class="btn btn-info"><i class="glyphicon glyphicon-cloud-download"></i> TSV file</button></a>
</div>
#end
<div class="panel-body collapse #if (showTable)in#end" id="mapping_qualityTable">
<!-- Table -->
<table class="table">
<thead><tr>
<th data-sorted="true" data-sorted-direction="ascending">Sample</th>
#if (!sampleLevel) <th>Library</th> #end
#for (field <- fields)
<th>${field.replaceAll("_", " ")}</th>
#end
</tr></thead>
<tbody>
#for (sample <- samples.toList.sorted)
#{
val libs = (libId, sampleLevel) match {
case (_, true) => List("")
case (Some(libId), _) => List(libId.toString)
case _ => summary.libraries(sample).toList
}
}#
<tr><td rowspan="${libs.size}"><a href="${rootPath}Samples/${sample}/index.html">${sample}</a></td>
#for (libId <- libs)
#if (libs.head != libId) <tr> #end
#if (!sampleLevel) <td><a href="${rootPath}Samples/${sample}/Libraries/${libId}/index.html">${libId}</a></td> #end
#{
val prefixPath = List("samples", sample) ::: (if (libId.isEmpty) Nil else List("libraries", libId)) ::: List("bammetrics", "stats")
val fieldValues = for (field <- fields) yield {
summary.getValue((prefixPath ::: List("bamstats", "mapping_quality", "general", field)):_*).getOrElse("N/A")
}
}#
#for (value <- fieldValues)
<td>${value}</td>
#end
</tr>
#end
#end
</tbody>
</table>
</div>
...@@ -22,7 +22,7 @@ import nl.lumc.sasc.biopet.core.{ BiopetFifoPipe, PipelineCommand, Reference, Sa ...@@ -22,7 +22,7 @@ import nl.lumc.sasc.biopet.core.{ BiopetFifoPipe, PipelineCommand, Reference, Sa
import nl.lumc.sasc.biopet.extensions.bedtools.{ BedtoolsCoverage, BedtoolsIntersect, BedtoolsSort } import nl.lumc.sasc.biopet.extensions.bedtools.{ BedtoolsCoverage, BedtoolsIntersect, BedtoolsSort }
import nl.lumc.sasc.biopet.extensions.picard._ import nl.lumc.sasc.biopet.extensions.picard._
import nl.lumc.sasc.biopet.extensions.samtools.SamtoolsFlagstat import nl.lumc.sasc.biopet.extensions.samtools.SamtoolsFlagstat
import nl.lumc.sasc.biopet.extensions.tools.BiopetFlagstat import nl.lumc.sasc.biopet.extensions.tools.{ BamStats, BiopetFlagstat }
import nl.lumc.sasc.biopet.pipelines.bammetrics.scripts.CoverageStats import nl.lumc.sasc.biopet.pipelines.bammetrics.scripts.CoverageStats
import nl.lumc.sasc.biopet.utils.config.Configurable import nl.lumc.sasc.biopet.utils.config.Configurable
import nl.lumc.sasc.biopet.utils.intervals.BedCheck import nl.lumc.sasc.biopet.utils.intervals.BedCheck
...@@ -82,9 +82,11 @@ class BamMetrics(val root: Configurable) extends QScript ...@@ -82,9 +82,11 @@ class BamMetrics(val root: Configurable) extends QScript
def biopetScript() { def biopetScript() {
add(SamtoolsFlagstat(this, inputBam, outputDir)) add(SamtoolsFlagstat(this, inputBam, outputDir))
val biopetFlagstat = BiopetFlagstat(this, inputBam, outputDir) val bamStats = new BamStats(this)
add(biopetFlagstat) bamStats.bamFile = inputBam
addSummarizable(biopetFlagstat, "biopet_flagstat") bamStats.outputDir = new File(outputDir, "bamstats")
add(bamStats)
addSummarizable(bamStats, "bamstats")
val multiMetrics = new CollectMultipleMetrics(this) val multiMetrics = new CollectMultipleMetrics(this)
multiMetrics.input = inputBam multiMetrics.input = inputBam
...@@ -134,7 +136,7 @@ class BamMetrics(val root: Configurable) extends QScript ...@@ -134,7 +136,7 @@ class BamMetrics(val root: Configurable) extends QScript
ampBedToInterval.isIntermediate = true ampBedToInterval.isIntermediate = true
add(ampBedToInterval) add(ampBedToInterval)
val chsMetrics = CalculateHsMetrics(this, inputBam, val chsMetrics = CollectHsMetrics(this, inputBam,
List(ampIntervals), ampIntervals :: roiIntervals.map(_.intervals), outputDir) List(ampIntervals), ampIntervals :: roiIntervals.map(_.intervals), outputDir)
add(chsMetrics) add(chsMetrics)
addSummarizable(chsMetrics, "hs_metrics") addSummarizable(chsMetrics, "hs_metrics")
...@@ -148,6 +150,10 @@ class BamMetrics(val root: Configurable) extends QScript ...@@ -148,6 +150,10 @@ class BamMetrics(val root: Configurable) extends QScript
} }
// Create stats and coverage plot for each bed/interval file // Create stats and coverage plot for each bed/interval file
val allIntervalNames = (roiIntervals ++ ampIntervals).map(_.bed.getName)
if (allIntervalNames.size != allIntervalNames.toSet.size) {
logger.warn("There are multiple region files with the same name. Metric values might get overwritten")
}
for (intervals <- roiIntervals ++ ampIntervals) { for (intervals <- roiIntervals ++ ampIntervals) {
val targetName = intervals.bed.getName.stripSuffix(".bed") val targetName = intervals.bed.getName.stripSuffix(".bed")
val targetDir = new File(outputDir, targetName) val targetDir = new File(outputDir, targetName)
...@@ -156,21 +162,25 @@ class BamMetrics(val root: Configurable) extends QScript ...@@ -156,21 +162,25 @@ class BamMetrics(val root: Configurable) extends QScript
output = new File(targetDir, inputBam.getName.stripSuffix(".bam") + ".overlap.strict.sam"), output = new File(targetDir, inputBam.getName.stripSuffix(".bam") + ".overlap.strict.sam"),
minOverlap = config("strict_intersect_overlap", default = 1.0)) minOverlap = config("strict_intersect_overlap", default = 1.0))
val biopetFlagstatStrict = BiopetFlagstat(this, biStrict.output, targetDir) val biopetFlagstatStrict = BiopetFlagstat(this, biStrict.output, targetDir)
addSummarizable(biopetFlagstatStrict, targetName + "_biopet_flagstat_strict") addSummarizable(biopetFlagstatStrict, targetName + "_flagstats_strict")
add(new BiopetFifoPipe(this, List(biStrict, biopetFlagstatStrict))) add(new BiopetFifoPipe(this, List(biStrict, biopetFlagstatStrict)))
val biLoose = BedtoolsIntersect(this, inputBam, intervals.bed, val biLoose = BedtoolsIntersect(this, inputBam, intervals.bed,
output = new File(targetDir, inputBam.getName.stripSuffix(".bam") + ".overlap.loose.sam"), output = new File(targetDir, inputBam.getName.stripSuffix(".bam") + ".overlap.loose.sam"),
minOverlap = config("loose_intersect_overlap", default = 0.01)) minOverlap = config("loose_intersect_overlap", default = 0.01))
val biopetFlagstatLoose = BiopetFlagstat(this, biLoose.output, targetDir) val biopetFlagstatLoose = BiopetFlagstat(this, biLoose.output, targetDir)
addSummarizable(biopetFlagstatLoose, targetName + "_biopet_flagstat_loose") addSummarizable(biopetFlagstatLoose, targetName + "_flagstats_loose")
add(new BiopetFifoPipe(this, List(biLoose, biopetFlagstatLoose))) add(new BiopetFifoPipe(this, List(biLoose, biopetFlagstatLoose)))
val sorter = new BedtoolsSort(this) val sortedBed = BamMetrics.sortedbedCache.getOrElse(intervals.bed, {
sorter.input = intervals.bed val sorter = new BedtoolsSort(this)
sorter.output = swapExt(targetDir, intervals.bed, ".bed", ".sorted.bed") sorter.input = intervals.bed
add(sorter) sorter.output = swapExt(targetDir, intervals.bed, ".bed", ".sorted.bed")
val bedCov = BedtoolsCoverage(this, sorter.output, inputBam, depth = true) add(sorter)
BamMetrics.sortedbedCache += intervals.bed -> sorter.output
sorter.output
})
val bedCov = BedtoolsCoverage(this, sortedBed, inputBam, depth = true)
val covStats = CoverageStats(this, targetDir, inputBam.getName.stripSuffix(".bam") + ".coverage") val covStats = CoverageStats(this, targetDir, inputBam.getName.stripSuffix(".bam") + ".coverage")
covStats.title = Some("Coverage Plot") covStats.title = Some("Coverage Plot")
covStats.subTitle = Some(s"for file '$targetName.bed'") covStats.subTitle = Some(s"for file '$targetName.bed'")
...@@ -198,4 +208,6 @@ object BamMetrics extends PipelineCommand { ...@@ -198,4 +208,6 @@ object BamMetrics extends PipelineCommand {
bamMetrics.biopetScript() bamMetrics.biopetScript()
bamMetrics bamMetrics
} }
private var sortedbedCache: Map[File, File] = Map()
} }
...@@ -82,7 +82,9 @@ object BammetricsReport extends ReportBuilder { ...@@ -82,7 +82,9 @@ object BammetricsReport extends ReportBuilder {
targets.map(t => t -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/covstatsPlot.ssp", Map("target" -> Some(t)))), targets.map(t => t -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/covstatsPlot.ssp", Map("target" -> Some(t)))),
Map())), Map())),
List( List(
"Summary" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp")) ++ "Summary" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp"),
"Mapping Quality" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/mappingQuality.ssp", Map("showPlot" -> true)),
"Clipping" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/clipping.ssp", Map("showPlot" -> true))) ++
(if (insertsizeMetrics) List("Insert Size" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/insertSize.ssp", Map("showPlot" -> true)) (if (insertsizeMetrics) List("Insert Size" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/insertSize.ssp", Map("showPlot" -> true))
) )
else Nil) ++ (if (wgsExecuted) List("Whole genome coverage" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/wgsHistogram.ssp",