diff --git a/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/bamMetricsFront.ssp b/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/bamMetricsFront.ssp index 8701c981a774cf44daf0bd39ccf837a7d69afe1b..b8828bb9bbca0822875fe9d4643f369b6f931ba1 100644 --- a/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/bamMetricsFront.ssp +++ b/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/bamMetricsFront.ssp @@ -1,3 +1,33 @@ -#{ //TODO: Need content }# +#import(nl.lumc.sasc.biopet.core.summary.Summary) +#import(nl.lumc.sasc.biopet.core.report.ReportPage) +<%@ var summary: Summary %> +<%@ var rootPath: String %> +<%@ var sampleId: Option[String] %> +<%@ var libId: Option[String] = None %> -Todo \ No newline at end of file +<table class="table"> +<tbody> + <tr><th>Pipeline</th><td>BamMetrics</td></tr> + <tr><th>Version</th><td>${summary.getValue("meta", "pipeline_version")}</td></tr> + <tr><th>Last commit hash</th><td>${summary.getValue("meta", "last_commit_hash")}</td></tr> + <tr><th>Output directory</th><td>${summary.getValue("meta", "output_dir")}</td></tr> + <tr><th>Sample ID</th><td>${sampleId}</td></tr> + #if (libId.isDefined) <tr><th>Library ID</th><td>${libId}</td></tr> #end +</tbody> +</table> +<br/> +<div class="row"> +<div class="col-md-1"></div> +<div class="col-md-6"> + <p> + In this web document you can find your <em>BamMetrics</em> pipeline report. + Different categories of data can be found in the left-side menu. + Statistics per sample and library can be accessed through the top-level menu. + Futhermore, you can view all versions of software tools used by selecting <em>Versions</em> from the top menu. + </p> + + <p> + <small>Brought to you by <a href="https://sasc.lumc.nl">SASC</a> and <a href="https://www.lumc.nl/org/klinische-genetica/">KG</a>, LUMC. </small> + </p> +</div> +</div> \ No newline at end of file diff --git a/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/bammetricsInputFile.ssp b/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/bammetricsInputFile.ssp new file mode 100644 index 0000000000000000000000000000000000000000..6497546891055ccdc882cbf2be5b609a7c1ae229 --- /dev/null +++ b/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/bammetricsInputFile.ssp @@ -0,0 +1,20 @@ +#import(nl.lumc.sasc.biopet.core.summary.Summary) +#import(nl.lumc.sasc.biopet.core.report.ReportPage) +#import(java.io.File) +<%@ var summary: Summary %> +<%@ var sampleId: Option[String] %> +<%@ var libId: Option[String] = None %> +<%@ var metricsTag: String = "bammetrics" %> + +<table class="table sortable-theme-bootstrap"> +<thead><tr> + <th>Path</th> + <th>MD5</th> +</tr></thead> +<tbody> +<tr> +<td>${summary.getValue(sampleId, libId, metricsTag, "files", "pipeline", "bamfile", "path")}</td> +<td>${summary.getValue(sampleId, libId, metricsTag, "files", "pipeline", "bamfile", "md5")}</td> +</tr> +</tbody> +</table> \ No newline at end of file diff --git a/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/covstatsPlot.ssp b/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/covstatsPlot.ssp index 6aa6ff46ade93f4e7fcfa65527c133fc0392c6b9..ddb6817dd9e8dc90345881517637cbac53fcea56 100644 --- a/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/covstatsPlot.ssp +++ b/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/covstatsPlot.ssp @@ -10,17 +10,17 @@ <%@ var metricsTag: String = "bammetrics" %> <%@ var target: String %> #{ - val originalPlot = new File(summary.getLibraryValue(sampleId, libId, metricsTag, "files", target + "_cov_stats", "plot", "path") + val originalPlot = new File(summary.getValue(sampleId, libId, metricsTag, "files", target + "_cov_stats", "plot", "path") .getOrElse(throw new IllegalArgumentException("No plot found in summary")).toString) val plot = new File(outputDir, target + "_cov_stats.png") - val values = summary.getLibraryValue(sampleId, libId, metricsTag, "stats", target + "_cov_stats", "coverage", "_all") + val values = summary.getValue(sampleId, libId, metricsTag, "stats", target + "_cov_stats", "coverage", "_all") .getOrElse(throw new IllegalArgumentException("No plot found in summary")).asInstanceOf[Map[String, Any]] if (originalPlot.exists()) IoUtils.copyFile(originalPlot, plot) }# -<img src="${plot}"> +<img src="${plot.getName}"> <table class="table"> <thead><tr> diff --git a/public/bammetrics/src/main/scala/nl/lumc/sasc/biopet/pipelines/bammetrics/BamMetrics.scala b/public/bammetrics/src/main/scala/nl/lumc/sasc/biopet/pipelines/bammetrics/BamMetrics.scala index 103e642ef20f72efd57c85bfd35c529f70083bd4..49ee3faf9f4be8c3c687624c5aaa0063087e7a71 100644 --- a/public/bammetrics/src/main/scala/nl/lumc/sasc/biopet/pipelines/bammetrics/BamMetrics.scala +++ b/public/bammetrics/src/main/scala/nl/lumc/sasc/biopet/pipelines/bammetrics/BamMetrics.scala @@ -58,6 +58,17 @@ class BamMetrics(val root: Configurable) extends QScript with SummaryQScript wit def summarySettings = Map("amplicon_name" -> ampliconBedFile.collect { case x => x.getName.stripSuffix(".bed") }, "roi_name" -> roiBedFiles.map(_.getName.stripSuffix(".bed"))) + override def reportClass = { + val bammetricsReport = new BammetricsReport(this) + bammetricsReport.outputDir = new File(outputDir, "report") + bammetricsReport.summaryFile = summaryFile + bammetricsReport.args = if (libId.isDefined) Map( + "sampleId" -> sampleId.getOrElse("."), + "libId" -> libId.getOrElse(".")) + else Map("sampleId" -> sampleId.getOrElse(".")) + Some(bammetricsReport) + } + /** executed before script */ def init() { } diff --git a/public/bammetrics/src/main/scala/nl/lumc/sasc/biopet/pipelines/bammetrics/BammetricsReport.scala b/public/bammetrics/src/main/scala/nl/lumc/sasc/biopet/pipelines/bammetrics/BammetricsReport.scala index 55095b4199db67a97e6bd344e24bd68bc087d11a..e48b6ba739af8fdf7c76e2c7658303152d13276e 100644 --- a/public/bammetrics/src/main/scala/nl/lumc/sasc/biopet/pipelines/bammetrics/BammetricsReport.scala +++ b/public/bammetrics/src/main/scala/nl/lumc/sasc/biopet/pipelines/bammetrics/BammetricsReport.scala @@ -2,24 +2,48 @@ package nl.lumc.sasc.biopet.pipelines.bammetrics import java.io.{ PrintWriter, File } -import nl.lumc.sasc.biopet.core.report.{ ReportBuilder, ReportPage, ReportSection } +import nl.lumc.sasc.biopet.core.config.Configurable +import nl.lumc.sasc.biopet.core.report.{ ReportBuilderExtension, ReportBuilder, ReportPage, ReportSection } import nl.lumc.sasc.biopet.core.summary.{ SummaryValue, Summary } import nl.lumc.sasc.biopet.extensions.rscript.{ XYPlot, StackedBarPlot } +class BammetricsReport(val root: Configurable) extends ReportBuilderExtension { + val builder = BammetricsReport +} + /** * Created by pjvan_thof on 3/30/15. */ object BammetricsReport extends ReportBuilder { - // FIXME: Not yet finished + /** Name of report */ val reportName = "Bam Metrics" - def indexPage = ReportPage(List(), List(), Map()) + /** Root page for single BamMetrcis report */ + def indexPage = { + val bamMetricsPage = this.bamMetricsPage(summary, sampleId, libId) + ReportPage(bamMetricsPage.subPages ::: List( + "Versions" -> ReportPage(List(), List(( + "Executables" -> ReportSection("/nl/lumc/sasc/biopet/core/report/executables.ssp" + ))), Map()), + "Files" -> ReportPage(List(), List( + "Input fastq files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/bammetricsInputFile.ssp") + ), Map()) + ), List( + "Report" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/bamMetricsFront.ssp") + ) ::: bamMetricsPage.sections, + Map() + ) + } - def bamMetricsPage(summary: Summary, sampleId: Option[String], libId: Option[String]) = { + /** Generates a page with alignment stats */ + def bamMetricsPage(summary: Summary, + sampleId: Option[String], + libId: Option[String], + metricsTag: String = "bammetrics") = { val targets = ( - summary.getLibraryValue(sampleId, libId, "bammetrics", "settings", "amplicon_name"), - summary.getLibraryValue(sampleId, libId, "bammetrics", "settings", "roi_name") + summary.getValue(sampleId, libId, "bammetrics", "settings", "amplicon_name"), + summary.getValue(sampleId, libId, "bammetrics", "settings", "roi_name") ) match { case (Some(amplicon: String), Some(roi: List[_])) => amplicon :: roi.map(_.toString) case (_, Some(roi: List[_])) => roi.map(_.toString) @@ -33,12 +57,21 @@ object BammetricsReport extends ReportBuilder { Map()))), List( "Summary" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp"), - "Insert Size" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/insertSize.ssp", Map("showPlot" -> true)) + "Insert Size" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/insertSize.ssp", Map("showPlot" -> true)), + "Whole genome coverage" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/wgsHistogram.ssp", Map("showPlot" -> true)) ), - Map() + Map("metricsTag" -> metricsTag) ) } + /** + * Generate a stackbar plot for alignment stats + * @param outputDir OutputDir for the tsv and png file + * @param prefix Prefix of the tsv and png file + * @param summary Summary class + * @param libraryLevel Default false, when set true plot will be based on library stats instead of sample stats + * @param sampleId Default it selects all sampples, when sample is giving it limits to selected sample + */ def alignmentSummaryPlot(outputDir: File, prefix: String, summary: Summary, @@ -94,6 +127,14 @@ object BammetricsReport extends ReportBuilder { plot.runLocal() } + /** + * Generate a line plot for insertsize + * @param outputDir OutputDir for the tsv and png file + * @param prefix Prefix of the tsv and png file + * @param summary Summary class + * @param libraryLevel Default false, when set true plot will be based on library stats instead of sample stats + * @param sampleId Default it selects all sampples, when sample is giving it limits to selected sample + */ def insertSizePlot(outputDir: File, prefix: String, summary: Summary, @@ -174,6 +215,14 @@ object BammetricsReport extends ReportBuilder { plot.runLocal() } + /** + * Generate a line plot for wgs coverage + * @param outputDir OutputDir for the tsv and png file + * @param prefix Prefix of the tsv and png file + * @param summary Summary class + * @param libraryLevel Default false, when set true plot will be based on library stats instead of sample stats + * @param sampleId Default it selects all sampples, when sample is giving it limits to selected sample + */ def wgsHistogramPlot(outputDir: File, prefix: String, summary: Summary, diff --git a/public/biopet-framework/src/main/resources/nl/lumc/sasc/biopet/core/report/executables.ssp b/public/biopet-framework/src/main/resources/nl/lumc/sasc/biopet/core/report/executables.ssp index 24e70a5bd96b18d63338dfaac2b9b6ba9462b806..e3eaba475acffa68c38293624e09e436e8976f62 100644 --- a/public/biopet-framework/src/main/resources/nl/lumc/sasc/biopet/core/report/executables.ssp +++ b/public/biopet-framework/src/main/resources/nl/lumc/sasc/biopet/core/report/executables.ssp @@ -4,9 +4,9 @@ <%@ var rootPath: String %> <%@ var sampleId: Option[String] = None %> <%@ var libId: Option[String] = None %> +<%@ var pipeline: String = summary.getValue("meta", "pipeline_name").getOrElse("").toString %> #{ - val pipeline = summary.getValue("meta", "pipeline_name").getOrElse("").toString - val executables = summary.getLibraryValue(sampleId, libId, pipeline, "executables").getOrElse(Map()).asInstanceOf[Map[String, Map[String, Any]]] + val executables = summary.getValue(sampleId, libId, pipeline, "executables").getOrElse(Map()).asInstanceOf[Map[String, Map[String, Any]]] }# <table class="table"> diff --git a/public/biopet-framework/src/main/resources/nl/lumc/sasc/biopet/core/report/reference.ssp b/public/biopet-framework/src/main/resources/nl/lumc/sasc/biopet/core/report/reference.ssp new file mode 100644 index 0000000000000000000000000000000000000000..530d217358475f76461b79fc1fea83aee2746fc2 --- /dev/null +++ b/public/biopet-framework/src/main/resources/nl/lumc/sasc/biopet/core/report/reference.ssp @@ -0,0 +1,31 @@ +#import(nl.lumc.sasc.biopet.core.summary.Summary) +#import(nl.lumc.sasc.biopet.core.report.ReportPage) +<%@ var summary: Summary %> +<%@ var rootPath: String %> +<%@ var pipeline: String %> + +#{ + val contigs = summary.getValue(pipeline, "settings", "reference", "contigs").get.asInstanceOf[Map[String, Map[String, Any]]] +}# + +<table class="table"> + <tbody> + <tr><th>Species</th><td>${summary.getValue(pipeline, "settings", "reference", "species")}</td></tr> + <tr><th>Name</th><td>${summary.getValue(pipeline, "settings", "reference", "name")}</td></tr> + <tr><th>File</th><td>${summary.getValue(pipeline, "files", "pipeline", "referenceFasta", "path")}</td></tr> + <tr><th>MD5</th><td>${summary.getValue(pipeline, "files", "pipeline", "referenceFasta", "md5")}</td></tr> + </tbody> +</table> + +<br/> + +<table class="table sortable-theme-bootstrap" data-sortable> + <thead> + <tr><th>Contig Name</th><th data-sorted="true" data-sorted-direction="descending">Length</th><th>MD5</th></tr> + </thead> + <tbody> + #for (c <- contigs.toList.sortBy(_._2("length").asInstanceOf[Long]).reverse) + <tr><th>${c._1}</th><td>${c._2.get("length")}</td><td>${c._2.get("md5")}</td></tr> + #end + </tbody> +</table> \ No newline at end of file diff --git a/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/MultisampleReportBuilder.scala b/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/MultisampleReportBuilder.scala index 3b43b435bf5a60862506fec8c41b99d499eb530b..98bc9225f33df713d10e9a9868fff21c2c986ad7 100644 --- a/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/MultisampleReportBuilder.scala +++ b/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/MultisampleReportBuilder.scala @@ -4,22 +4,28 @@ package nl.lumc.sasc.biopet.core.report * Created by pjvan_thof on 3/30/15. */ trait MultisampleReportBuilder extends ReportBuilder { + + /** Method to generate a single sample page */ def samplePage(sampleId: String, args: Map[String, Any]): ReportPage + /** Default list of samples, can be override */ def samplesSections: List[(String, ReportSection)] = { List( ("Samples", ReportSection("/nl/lumc/sasc/biopet/core/report/samplesList.ssp")) ) } + /** Method to generate a single library page */ def libraryPage(sampleId: String, libraryId: String, args: Map[String, Any]): ReportPage + /** Default list of libraries, can be override */ def libririesSections: List[(String, ReportSection)] = { List( ("Libraries", ReportSection("/nl/lumc/sasc/biopet/core/report/librariesList.ssp")) ) } + /** Generate the samples page including a single sample page for each sample in the summary */ def generateSamplesPage(args: Map[String, Any]): ReportPage = { val samplePages = summary.samples .map(sampleId => (sampleId -> samplePage(sampleId, args ++ Map("sampleId" -> Some(sampleId))))) @@ -27,6 +33,7 @@ trait MultisampleReportBuilder extends ReportBuilder { ReportPage(samplePages, samplesSections, args) } + /** Generate the libraries page for a single sample with a subpage for eacht library */ def generateLibraryPage(args: Map[String, Any]): ReportPage = { val sampleId = args("sampleId") match { case Some(x) => x.toString diff --git a/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/ReportBuilder.scala b/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/ReportBuilder.scala index bf40c89ee83b432f9659117919299871b37ca35f..0312853bd97aa2dfa7793015ddf51d42977370f5 100644 --- a/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/ReportBuilder.scala +++ b/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/ReportBuilder.scala @@ -2,65 +2,81 @@ package nl.lumc.sasc.biopet.core.report import java.io._ -import nl.lumc.sasc.biopet.core.{ ToolCommandFuntion, BiopetJavaCommandLineFunction, ToolCommand } +import nl.lumc.sasc.biopet.core.{ Logging, ToolCommandFuntion, ToolCommand } import nl.lumc.sasc.biopet.core.summary.Summary import org.broadinstitute.gatk.utils.commandline.Input import org.fusesource.scalate.{ TemplateSource, TemplateEngine } import nl.lumc.sasc.biopet.utils.IoUtils +import scala.collection.mutable /** * Created by pjvan_thof on 3/27/15. */ trait ReportBuilderExtension extends ToolCommandFuntion { + /** Report builder object */ val builder: ReportBuilder @Input(required = true) var summaryFile: File = _ + /** OutputDir for the report */ var outputDir: File = _ + /** Arguments that are passed on the commandline */ var args: Map[String, String] = Map() + override val defaultCoreMemory = 3.0 + override def beforeGraph: Unit = { super.beforeGraph jobOutputFile = new File(outputDir, ".report.log.out") javaMainClass = builder.getClass.getName.takeWhile(_ != '$') } + /** Command to generate the report */ override def commandLine: String = { super.commandLine + required("--summary", summaryFile) + required("--outputDir", outputDir) + - args.map(x => required(x._1, x._2)).mkString + args.map(x => required("-a", x._1 + "=" + x._2)).mkString } } trait ReportBuilder extends ToolCommand { - case class Args(summary: File = null, outputDir: File = null, pageArgs: Map[String, String] = Map()) extends AbstractArgs + case class Args(summary: File = null, outputDir: File = null, pageArgs: mutable.Map[String, Any] = mutable.Map()) extends AbstractArgs class OptParser extends AbstractOptParser { - opt[File]('s', "summary") required () maxOccurs 1 valueName "<file>" action { (x, c) => + opt[File]('s', "summary") unbounded () required () maxOccurs 1 valueName "<file>" action { (x, c) => c.copy(summary = x) } - opt[File]('o', "outputDir") required () maxOccurs 1 valueName "<file>" action { (x, c) => + opt[File]('o', "outputDir") unbounded () required () maxOccurs 1 valueName "<file>" action { (x, c) => c.copy(outputDir = x) } - opt[Map[String, String]]('a', "args") action { (x, c) => + opt[Map[String, String]]('a', "args") unbounded () action { (x, c) => c.copy(pageArgs = c.pageArgs ++ x) } } + /** summary object internaly */ private var setSummary: Summary = _ + /** Retrival of summary, read only */ final def summary = setSummary + /** default args that are passed to all page withing the report */ def pageArgs: Map[String, Any] = Map() private var done = 0 private var total = 0 + private var _sampleId: Option[String] = None + protected def sampleId = _sampleId + private var _libId: Option[String] = None + protected def libId = _libId + + /** Main function to for building the report */ def main(args: Array[String]): Unit = { logger.info("Start") @@ -70,6 +86,22 @@ trait ReportBuilder extends ToolCommand { require(cmdArgs.outputDir.exists(), "Output dir does not exist") require(cmdArgs.outputDir.isDirectory, "Output dir is not a directory") + cmdArgs.pageArgs.get("sampleId") match { + case Some(s: String) => { + cmdArgs.pageArgs += "sampleId" -> Some(s) + _sampleId = Some(s) + } + case _ => + } + + cmdArgs.pageArgs.get("libId") match { + case Some(l: String) => { + cmdArgs.pageArgs += "libId" -> Some(l) + _libId = Some(l) + } + case _ => + } + logger.info("Copy Base files") // Static files that will be copied to the output folder, then file is added to [resourceDir] it's need to be added here also @@ -95,25 +127,32 @@ trait ReportBuilder extends ToolCommand { logger.info("Parsing summary") setSummary = new Summary(cmdArgs.summary) - total = countPages(indexPage) + total = ReportBuilder.countPages(indexPage) logger.info(total + " pages to be generated") logger.info("Generate pages") val jobs = generatePage(summary, indexPage, cmdArgs.outputDir, - args = pageArgs ++ cmdArgs.pageArgs ++ + args = pageArgs ++ cmdArgs.pageArgs.toMap ++ Map("summary" -> summary, "reportName" -> reportName, "indexPage" -> indexPage)) logger.info(jobs + " Done") } + /** This must be implemented, this will be the root page of the report */ def indexPage: ReportPage + /** This must be implemented, this will because the title of the report */ def reportName: String - def countPages(page: ReportPage): Int = { - page.subPages.map(x => countPages(x._2)).fold(1)(_ + _) - } - + /** + * This method will render the page and the subpages recursivly + * @param summary The summary object + * @param page Page to render + * @param outputDir Root output dir of the report + * @param path Path from root to current page + * @param args Args to add to this sub page, are args from current page are passed automaticly + * @return Number of pages including all subpages that are rendered + */ def generatePage(summary: Summary, page: ReportPage, outputDir: File, @@ -151,10 +190,17 @@ trait ReportBuilder extends ToolCommand { object ReportBuilder { + /** Single template render engine, this will have a cache for all compile templates */ protected val engine = new TemplateEngine() + /** Cache of temp file for templates from the classpath / jar */ private var templateCache: Map[String, File] = Map() + /** This will give the total number of pages including all nested pages */ + def countPages(page: ReportPage): Int = { + page.subPages.map(x => countPages(x._2)).fold(1)(_ + _) + } + /** * This method will render a template that is located in the classpath / jar * @param location location in the classpath / jar @@ -162,6 +208,12 @@ object ReportBuilder { * @return Rendered result of template */ def renderTemplate(location: String, args: Map[String, Any] = Map()): String = { + Logging.logger.info("Rendering: " + location) + + if (location == "/nl/lumc/sasc/biopet/pipelines/carp/carpFront.ssp") { + println("hier dus") + } + val templateFile: File = templateCache.get(location) match { case Some(template) => template case _ => { diff --git a/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/ReportPage.scala b/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/ReportPage.scala index 533c18384cda6ea60dbce4c587f8224611568ccf..2253d338f929988e47ce5fc6970a35a00eb41ce3 100644 --- a/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/ReportPage.scala +++ b/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/ReportPage.scala @@ -2,6 +2,10 @@ package nl.lumc.sasc.biopet.core.report /** * Created by pjvan_thof on 3/27/15. + * + * @param subPages Subpages for this page + * @param sections Sections for this page + * @param args Arguments for this page, this arguments get passed to all section and subpages */ case class ReportPage(subPages: List[(String, ReportPage)], sections: List[(String, ReportSection)], diff --git a/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/ReportSection.scala b/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/ReportSection.scala index a2a258f2aa348114ca6356c6e49c22969d6e89a8..53825b1422826c336ed5ab334e2a94e5a2f5a2b2 100644 --- a/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/ReportSection.scala +++ b/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/report/ReportSection.scala @@ -2,15 +2,18 @@ package nl.lumc.sasc.biopet.core.report /** * Created by pjvan_thof on 4/8/15. + * + * @param location Location inside the classpath / jar + * @param args arguments only for current section, this is not passed to other sub pages */ case class ReportSection(location: String, - args: Map[String, Any] = Map(), - intro: Option[String] = None) { - - def render(args: Map[String, Any]): String = { - (intro match { - case Some(template) => ReportBuilder.renderTemplate(location, args ++ this.args) - case _ => "" - }) + ReportBuilder.renderTemplate(location, args ++ this.args) + args: Map[String, Any] = Map()) { + /** + * This method will render this section + * @param args Possible to give more arguments + * @return Rendered result for this section + */ + def render(args: Map[String, Any] = Map()): String = { + ReportBuilder.renderTemplate(location, args ++ this.args) } } diff --git a/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/summary/Summary.scala b/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/summary/Summary.scala index 662ec704850f28a64bc1df154030f1454b5eb075..809dfb6142ec425526950ef26b5daae7dfb9081d 100644 --- a/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/summary/Summary.scala +++ b/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/core/summary/Summary.scala @@ -10,6 +10,7 @@ import nl.lumc.sasc.biopet.utils.ConfigUtils class Summary(file: File) { val map = ConfigUtils.fileToConfigMap(file) + /** List of all samples in the summary */ lazy val samples: Set[String] = { ConfigUtils.getValueFromPath(map, List("samples")) match { case Some(samples) => ConfigUtils.any2map(samples).keySet @@ -17,6 +18,7 @@ class Summary(file: File) { } } + /** List of all libraries for each sample */ lazy val libraries: Map[String, Set[String]] = { (for (sample <- samples) yield sample -> { ConfigUtils.getValueFromPath(map, List("samples", sample, "libraries")) match { @@ -26,27 +28,33 @@ class Summary(file: File) { }).toMap } + /** getValue from on given nested path */ def getValue(path: String*): Option[Any] = { ConfigUtils.getValueFromPath(map, path.toList) } + /** getValue from on given nested path with prefix "samples" -> [sampleId] */ def getSampleValue(sampleId: String, path: String*): Option[Any] = { ConfigUtils.getValueFromPath(map, "samples" :: sampleId :: path.toList) } + /** Get values for all samples on given path with prefix "samples" -> [sampleId] */ def getSampleValues(path: String*): Map[String, Option[Any]] = { (for (sample <- samples) yield sample -> getSampleValue(sample, path: _*)).toMap } + /** Executes given function for each sample */ def getSampleValues(function: (Summary, String) => Option[Any]): Map[String, Option[Any]] = { (for (sample <- samples) yield sample -> function(this, sample)).toMap } + /** Get value on nested path with prefix "samples" -> [sampleId] -> "libraries" -> [libId] */ def getLibraryValue(sampleId: String, libId: String, path: String*): Option[Any] = { ConfigUtils.getValueFromPath(map, "samples" :: sampleId :: "libraries" :: libId :: path.toList) } - def getLibraryValue(sampleId: Option[String], libId: Option[String], path: String*): Option[Any] = { + /** Get value on nested path with prefix depending is sampleId and/or libId is None or not */ + def getValue(sampleId: Option[String], libId: Option[String], path: String*): Option[Any] = { (sampleId, libId) match { case (Some(sample), Some(lib)) => getLibraryValue(sample, lib, path: _*) case (Some(sample), _) => getSampleValue(sample, path: _*) @@ -54,12 +62,22 @@ class Summary(file: File) { } } + /** + * Get values for all libraries on a given path + * @param path path to of value + * @return (sampleId, libId) -> value + */ def getLibraryValues(path: String*): Map[(String, String), Option[Any]] = { (for (sample <- samples; lib <- libraries.getOrElse(sample, Set())) yield { (sample, lib) -> getLibraryValue(sample, lib, path: _*) }).toMap } + /** + * Executes method for each library + * @param function Function to execute + * @return (sampleId, libId) -> value + */ def getLibraryValues(function: (Summary, String, String) => Option[Any]): Map[(String, String), Option[Any]] = { (for (sample <- samples; lib <- libraries.getOrElse(sample, Set())) yield { (sample, lib) -> function(this, sample, lib) diff --git a/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/tools/BastyGenerateFasta.scala b/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/tools/BastyGenerateFasta.scala index 19752d72b4c19426050388351fcd6e6b613bf57d..2f8225d883f2822dc971686174cfeed149ba3f40 100644 --- a/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/tools/BastyGenerateFasta.scala +++ b/public/biopet-framework/src/main/scala/nl/lumc/sasc/biopet/tools/BastyGenerateFasta.scala @@ -21,14 +21,14 @@ import htsjdk.variant.variantcontext.VariantContext import htsjdk.variant.vcf.VCFFileReader import java.io.File import java.io.PrintWriter -import nl.lumc.sasc.biopet.core.{ ToolCommandFuntion, BiopetJavaCommandLineFunction, ToolCommand } +import nl.lumc.sasc.biopet.core.{ Reference, ToolCommandFuntion, BiopetJavaCommandLineFunction, ToolCommand } import nl.lumc.sasc.biopet.core.config.Configurable import org.broadinstitute.gatk.utils.commandline.{ Input, Output } import scala.collection.JavaConversions._ import nl.lumc.sasc.biopet.utils.VcfUtils._ import scala.collection.mutable.ListBuffer -class BastyGenerateFasta(val root: Configurable) extends ToolCommandFuntion { +class BastyGenerateFasta(val root: Configurable) extends ToolCommandFuntion with Reference { javaMainClass = getClass.getName @Input(doc = "Input vcf file", required = false) @@ -38,7 +38,7 @@ class BastyGenerateFasta(val root: Configurable) extends ToolCommandFuntion { var bamFile: File = _ @Input(doc = "reference", required = false) - var reference: File = config("reference") + var reference: File = _ @Output(doc = "Output fasta, variants only", required = false) var outputVariants: File = _ @@ -57,6 +57,11 @@ class BastyGenerateFasta(val root: Configurable) extends ToolCommandFuntion { override val defaultCoreMemory = 4.0 + override def beforeGraph: Unit = { + super.beforeGraph + reference = referenceFasta() + } + override def commandLine = super.commandLine + optional("--inputVcf", inputVcf) + optional("--bamFile", bamFile) + diff --git a/public/carp/src/main/resources/nl/lumc/sasc/biopet/pipelines/carp/carpFront.ssp b/public/carp/src/main/resources/nl/lumc/sasc/biopet/pipelines/carp/carpFront.ssp new file mode 100644 index 0000000000000000000000000000000000000000..e6fe9b7bbad28cfd433692f1ed164cd8e5378713 --- /dev/null +++ b/public/carp/src/main/resources/nl/lumc/sasc/biopet/pipelines/carp/carpFront.ssp @@ -0,0 +1,26 @@ +#import(nl.lumc.sasc.biopet.core.summary.Summary) +<%@ var summary: Summary %> +<table class="table"> +<tbody> + <tr><th>Pipeline</th><td>Carp</td></tr> + <tr><th>Version</th><td>${summary.getValue("meta", "pipeline_version")}</td></tr> + <tr><th>Last commit hash</th><td>${summary.getValue("meta", "last_commit_hash")}</td></tr> + <tr><th>Output directory</th><td>${summary.getValue("meta", "output_dir")}</td></tr> +</tbody> +</table> +<br/> +<div class="row"> +<div class="col-md-1"></div> +<div class="col-md-6"> + <p> + In this web document you can find your <em>Carp</em> pipeline report. + Different categories of data can be found in the left-side menu. + Statistics per sample and library can be accessed through the top-level menu. + Futhermore, you can view all versions of software tools used by selecting <em>Versions</em> from the top menu. + </p> + + <p> + <small>Brought to you by <a href="https://sasc.lumc.nl">SASC</a> and <a href="https://www.lumc.nl/org/klinische-genetica/">KG</a>, LUMC. </small> + </p> +</div> +</div> \ No newline at end of file diff --git a/public/carp/src/main/scala/nl/lumc/sasc/biopet/pipelines/carp/Carp.scala b/public/carp/src/main/scala/nl/lumc/sasc/biopet/pipelines/carp/Carp.scala index acaae3489fe31e3fff4bd81a75aae89f56822eea..e2b769144f0f5250954fee8a93cf1be1503eb1d4 100644 --- a/public/carp/src/main/scala/nl/lumc/sasc/biopet/pipelines/carp/Carp.scala +++ b/public/carp/src/main/scala/nl/lumc/sasc/biopet/pipelines/carp/Carp.scala @@ -21,6 +21,7 @@ import nl.lumc.sasc.biopet.core.summary.SummaryQScript import nl.lumc.sasc.biopet.extensions.Ln import nl.lumc.sasc.biopet.extensions.macs2.Macs2CallPeak import nl.lumc.sasc.biopet.extensions.picard.MergeSamFiles +import nl.lumc.sasc.biopet.pipelines.bammetrics.BamMetrics import nl.lumc.sasc.biopet.pipelines.bamtobigwig.Bam2Wig import nl.lumc.sasc.biopet.utils.ConfigUtils import org.broadinstitute.gatk.queue.QScript @@ -40,7 +41,10 @@ class Carp(val root: Configurable) extends QScript with MultiSampleQScript with def this() = this(null) override def defaults = ConfigUtils.mergeMaps(Map( - "mapping" -> Map("skip_markduplicates" -> true, "aligner" -> "bwa-mem") + "mapping" -> Map( + "skip_markduplicates" -> true, + "aligner" -> "bwa-mem" + ) ), super.defaults) def summaryFile = new File(outputDir, "Carp.summary.json") @@ -105,6 +109,9 @@ class Carp(val root: Configurable) extends QScript with MultiSampleQScript with add(merge) } + val bamMetrics = BamMetrics(qscript, bamFile, new File(sampleDir, "metrics")) + addAll(bamMetrics.functions) + addSummaryQScript(bamMetrics) addAll(Bam2Wig(qscript, bamFile).functions) val macs2 = new Macs2CallPeak(qscript) @@ -117,6 +124,13 @@ class Carp(val root: Configurable) extends QScript with MultiSampleQScript with } } + override def reportClass = { + val carp = new CarpReport(this) + carp.outputDir = new File(outputDir, "report") + carp.summaryFile = summaryFile + Some(carp) + } + def init() = { // ensure that no samples are called 'control' since that is our reserved keyword require(!sampleIds.contains("control"), diff --git a/public/carp/src/main/scala/nl/lumc/sasc/biopet/pipelines/carp/CarpReport.scala b/public/carp/src/main/scala/nl/lumc/sasc/biopet/pipelines/carp/CarpReport.scala new file mode 100644 index 0000000000000000000000000000000000000000..398fda7a78bb7e7469375935b0d224c09ad09848 --- /dev/null +++ b/public/carp/src/main/scala/nl/lumc/sasc/biopet/pipelines/carp/CarpReport.scala @@ -0,0 +1,83 @@ +package nl.lumc.sasc.biopet.pipelines.carp + +import nl.lumc.sasc.biopet.core.config.Configurable +import nl.lumc.sasc.biopet.core.report.{ ReportBuilderExtension, ReportSection, ReportPage, MultisampleReportBuilder } +import nl.lumc.sasc.biopet.pipelines.bammetrics.BammetricsReport +import nl.lumc.sasc.biopet.pipelines.flexiprep.FlexiprepReport + +/** + * Created by pjvanthof on 25/06/15. + */ +class CarpReport(val root: Configurable) extends ReportBuilderExtension { + val builder = CarpReport +} + +object CarpReport extends MultisampleReportBuilder { + + /** Root page for the carp report */ + def indexPage = { + //Source.fromInputStream(getClass.getResourceAsStream("/nl/lumc/sasc/biopet/pipelines/carp/carpFont.ssp")).foreach(print(_)) + ReportPage( + List("Samples" -> generateSamplesPage(pageArgs)) ++ + Map("Files" -> filesPage, + "Versions" -> ReportPage(List(), List(( + "Executables" -> ReportSection("/nl/lumc/sasc/biopet/core/report/executables.ssp" + ))), Map()) + ), + List( + "Report" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/carp/carpFront.ssp"), + "Alignment" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp", + Map("sampleLevel" -> true, "showPlot" -> true, "showTable" -> false) + ), + "Insert Size" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/insertSize.ssp", + Map("sampleLevel" -> true, "showPlot" -> true, "showTable" -> false)), + "Whole genome coverage" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/wgsHistogram.ssp", + Map("sampleLevel" -> true, "showPlot" -> true, "showTable" -> false)), + "QC reads" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp", + Map("showPlot" -> true, "showTable" -> false)), + "QC bases" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp", + Map("showPlot" -> true, "showTable" -> false)) + ), + pageArgs + ) + } + + /** Files page, can be used general or at sample level */ + def filesPage: ReportPage = ReportPage(List(), List( + "Input fastq files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepInputfiles.ssp"), + "After QC fastq files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepOutputfiles.ssp"), + "Bam files per lib" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/mapping/outputBamfiles.ssp", Map("sampleLevel" -> false)) //, + //"Preprocessed bam files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/mapping/outputBamfiles.ssp", + // Map("pipelineName" -> "shiva", "fileTag" -> "preProcessBam")) + ), Map()) + + /** Single sample page */ + def samplePage(sampleId: String, args: Map[String, Any]): ReportPage = { + ReportPage(List( + "Libraries" -> generateLibraryPage(args), + "Alignment" -> BammetricsReport.bamMetricsPage(summary, Some(sampleId), None), + "Files" -> filesPage + ), List( + "Alignment" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp", + if (summary.libraries(sampleId).size > 1) Map("showPlot" -> true) else Map()), + "Preprocessing" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp", Map("sampleLevel" -> true)), + "QC reads" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp"), + "QC bases" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp") + ), args) + } + + /** Library page */ + def libraryPage(sampleId: String, libId: String, args: Map[String, Any]): ReportPage = { + ReportPage(List( + "Alignment" -> BammetricsReport.bamMetricsPage(summary, Some(sampleId), Some(libId)), + "QC" -> FlexiprepReport.flexiprepPage + ), List( + "Alignment" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp"), + "QC reads" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp"), + "QC bases" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp") + ), args) + } + + /** Name of the report */ + def reportName = "Carp Report" +} \ No newline at end of file diff --git a/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp b/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp index 46d98d6b7aca05c13803fcae169d62e116dfc68e..b0bc4784d7720596be11b4c4dd8a889fa8e88300 100644 --- a/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp +++ b/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp @@ -10,6 +10,7 @@ <%@ var showPlot: Boolean = false %> <%@ var showTable: Boolean = true %> <%@ var showIntro: Boolean = true %> +<%@ var multisample: Boolean = true %> #{ val samples = sampleId match { case Some(sample) => List(sample.toString) @@ -106,11 +107,23 @@ libs.count(summary.getLibraryValue(sample, _, "flexiprep", "settings", "paired").getOrElse(false) == true) } }# - <tr><td rowspan="${sampleRowspan}"><a href="${rootPath}Samples/${sample}/index.html">${sample}</a></td> + <tr><td rowspan="${sampleRowspan}"> + #if (multisample) + <a href="${rootPath}Samples/${sample}/index.html">${sample}</a> + #else + ${sample} + #end + </td> #for (libId <- libs) #if (libs.head != libId) <tr> #end #{ val paired = summary.getLibraryValue(sample, libId, "flexiprep", "settings", "paired").getOrElse(false) }# - <td #if (paired == true) rowspan="2" #end><a href="${rootPath}Samples/${sample}/Libraries/${libId}/index.html">${libId}</a></td> + <td #if (paired == true) rowspan="2" #end> + #if (multisample) + <a href="${rootPath}Samples/${sample}/Libraries/${libId}/index.html">${libId}</a> + #else + ${libId} + #end + </td> #{ val reads = if (paired == true) List("R1", "R2") else List("R1") }# #for (read <- reads) #if (read == "R2") </tr><tr> #end diff --git a/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepFront.ssp b/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepFront.ssp index 8701c981a774cf44daf0bd39ccf837a7d69afe1b..e07d67e1d420822cf35334ec6e6e526f705e5d90 100644 --- a/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepFront.ssp +++ b/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepFront.ssp @@ -1,3 +1,33 @@ -#{ //TODO: Need content }# +#import(nl.lumc.sasc.biopet.core.summary.Summary) +#import(nl.lumc.sasc.biopet.core.report.ReportPage) +<%@ var summary: Summary %> +<%@ var rootPath: String %> +<%@ var sampleId: Option[String] %> +<%@ var libId: Option[String] %> -Todo \ No newline at end of file +<table class="table"> +<tbody> + <tr><th>Pipeline</th><td>Flexiprep</td></tr> + <tr><th>Version</th><td>${summary.getValue("meta", "pipeline_version")}</td></tr> + <tr><th>Last commit hash</th><td>${summary.getValue("meta", "last_commit_hash")}</td></tr> + <tr><th>Output directory</th><td>${summary.getValue("meta", "output_dir")}</td></tr> + <tr><th>Sample ID</th><td>${sampleId}</td></tr> + <tr><th>Library ID</th><td>${libId}</td></tr> +</tbody> +</table> +<br/> +<div class="row"> +<div class="col-md-1"></div> +<div class="col-md-6"> + <p> + In this web document you can find your <em>Flexiprep</em> pipeline report. + Different categories of data can be found in the left-side menu. + Statistics per sample and library can be accessed through the top-level menu. + Futhermore, you can view all versions of software tools used by selecting <em>Versions</em> from the top menu. + </p> + + <p> + <small>Brought to you by <a href="https://sasc.lumc.nl">SASC</a> and <a href="https://www.lumc.nl/org/klinische-genetica/">KG</a>, LUMC. </small> + </p> +</div> +</div> \ No newline at end of file diff --git a/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepInputfiles.ssp b/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepInputfiles.ssp index ced6349bb7752fc5a86df328f2216f6650a1aaef..0ecc838cc733dd80d04455060071e6295246175e 100644 --- a/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepInputfiles.ssp +++ b/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepInputfiles.ssp @@ -17,16 +17,16 @@ val pipelineOutputDir = summary.getValue("meta", "output_dir").getOrElse("").toString def removeDir(value: Option[Any]): Option[Any] = { value.collect { case a => - if (a.toString.startsWith(pipelineOutputDir) && pipelineOutputDir.nonEmpty) "./" + a.toString.stripPrefix(pipelineOutputDir) + if (a.toString.startsWith(pipelineOutputDir) && pipelineOutputDir.nonEmpty) "./" + a.toString.stripPrefix(pipelineOutputDir + File.separator) else a } } }# -<table class="table sortable-theme-bootstrap" data-sortable> +<table class="table"> <thead><tr> - <th data-sorted="true" data-sorted-direction="ascending">Sample</th> + <th>Sample</th> <th colspan="2">Library</th> <th>Path</th> <th>MD5</th> diff --git a/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepOutputfiles.ssp b/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepOutputfiles.ssp index 439fa99f6b0b206e8898ad39deea447ad28aff30..3807e6c8790c21948927f3e25323d59bc620eee0 100644 --- a/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepOutputfiles.ssp +++ b/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepOutputfiles.ssp @@ -17,16 +17,16 @@ val pipelineOutputDir = summary.getValue("meta", "output_dir").getOrElse("").toString def removeDir(value: Option[Any]): Option[Any] = { value.collect { case a => - if (a.toString.startsWith(pipelineOutputDir) && pipelineOutputDir.nonEmpty) "./" + a.toString.stripPrefix(pipelineOutputDir) + if (a.toString.startsWith(pipelineOutputDir) && pipelineOutputDir.nonEmpty) "./" + a.toString.stripPrefix(pipelineOutputDir + File.separator) else a } } }# -<table class="table sortable-theme-bootstrap" data-sortable> +<table class="table"> <thead><tr> - <th data-sorted="true" data-sorted-direction="ascending">Sample</th> + <th>Sample</th> <th colspan="2">Library</th> <th>Path</th> <th>MD5</th> diff --git a/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp b/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp index 11a5a593f0f1ccb04fe74199a35a876cb9a946c9..f0b9ee75d46045ba1a99e9d38b4fcfd01462f59c 100644 --- a/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp +++ b/public/flexiprep/src/main/resources/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp @@ -10,6 +10,7 @@ <%@ var showPlot: Boolean = false %> <%@ var showTable: Boolean = true %> <%@ var showIntro: Boolean = true %> +<%@ var multisample: Boolean = true %> #{ val samples = sampleId match { case Some(sample) => List(sample.toString) @@ -110,11 +111,23 @@ libs.count(summary.getLibraryValue(sample, _, "flexiprep", "settings", "paired").getOrElse(false) == true) } }# - <tr><td rowspan="${sampleRowspan}"><a href="${rootPath}Samples/${sample}/index.html">${sample}</a></td> + <tr><td rowspan="${sampleRowspan}"> + #if (multisample) + <a href="${rootPath}Samples/${sample}/index.html">${sample}</a> + #else + ${sample} + #end + </td> #for (libId <- libs) #if (libs.head != libId) <tr> #end #{ val paired = summary.getLibraryValue(sample, libId, "flexiprep", "settings", "paired").getOrElse(false) }# - <td #if (paired == true) rowspan="2" #end><a href="${rootPath}Samples/${sample}/Libraries/${libId}/index.html">${libId}</a></td> + <td #if (paired == true) rowspan="2" #end> + #if (multisample) + <a href="${rootPath}Samples/${sample}/Libraries/${libId}/index.html">${libId}</a> + #else + ${libId} + #end + </td> #{ val reads = if (paired == true) List("R1", "R2") else List("R1") }# #for (read <- reads) #if (read == "R2") </tr><tr> #end diff --git a/public/flexiprep/src/main/scala/nl/lumc/sasc/biopet/pipelines/flexiprep/Flexiprep.scala b/public/flexiprep/src/main/scala/nl/lumc/sasc/biopet/pipelines/flexiprep/Flexiprep.scala index 4efb8d0f2f736229603231d3609462cd08dbdf8f..94934aa5647dfcc7d3d019701a468b9335bae4db 100644 --- a/public/flexiprep/src/main/scala/nl/lumc/sasc/biopet/pipelines/flexiprep/Flexiprep.scala +++ b/public/flexiprep/src/main/scala/nl/lumc/sasc/biopet/pipelines/flexiprep/Flexiprep.scala @@ -19,7 +19,7 @@ import nl.lumc.sasc.biopet.core.summary.SummaryQScript import org.broadinstitute.gatk.queue.QScript import org.broadinstitute.gatk.utils.commandline.{ Input, Argument } -import nl.lumc.sasc.biopet.core.{ SampleLibraryTag, BiopetQScript, PipelineCommand } +import nl.lumc.sasc.biopet.core.{ SampleLibraryTag, PipelineCommand } import nl.lumc.sasc.biopet.core.config.Configurable import nl.lumc.sasc.biopet.extensions._ import nl.lumc.sasc.biopet.tools.SeqStat @@ -63,6 +63,16 @@ class Flexiprep(val root: Configurable) extends QScript with SummaryQScript with var fastqc_R1_after: Fastqc = _ var fastqc_R2_after: Fastqc = _ + override def reportClass = { + val flexiprepReport = new FlexiprepReport(this) + flexiprepReport.outputDir = new File(outputDir, "report") + flexiprepReport.summaryFile = summaryFile + flexiprepReport.args = Map( + "sampleId" -> sampleId.getOrElse("."), + "libId" -> libId.getOrElse(".")) + Some(flexiprepReport) + } + /** Function that's need to be executed before the script is accessed */ def init() { require(outputDir != null, "Missing output directory on flexiprep module") diff --git a/public/flexiprep/src/main/scala/nl/lumc/sasc/biopet/pipelines/flexiprep/FlexiprepReport.scala b/public/flexiprep/src/main/scala/nl/lumc/sasc/biopet/pipelines/flexiprep/FlexiprepReport.scala index 5981f2a33f3bd166f72a27337677cbeabc79a622..bfb1ddfdcdeb8cc9d1b0b6b7d85a8ab9058cc12b 100644 --- a/public/flexiprep/src/main/scala/nl/lumc/sasc/biopet/pipelines/flexiprep/FlexiprepReport.scala +++ b/public/flexiprep/src/main/scala/nl/lumc/sasc/biopet/pipelines/flexiprep/FlexiprepReport.scala @@ -2,25 +2,42 @@ package nl.lumc.sasc.biopet.pipelines.flexiprep import java.io.{ PrintWriter, File } -import nl.lumc.sasc.biopet.core.report.{ ReportSection, ReportPage, ReportBuilder } +import nl.lumc.sasc.biopet.core.config.Configurable +import nl.lumc.sasc.biopet.core.report.{ ReportBuilderExtension, ReportSection, ReportPage, ReportBuilder } import nl.lumc.sasc.biopet.core.summary.{ SummaryValue, Summary } import nl.lumc.sasc.biopet.extensions.rscript.StackedBarPlot +class FlexiprepReport(val root: Configurable) extends ReportBuilderExtension { + val builder = FlexiprepReport +} + /** * Created by pjvan_thof on 3/30/15. */ object FlexiprepReport extends ReportBuilder { val reportName = "Flexiprep" - def indexPage = ReportPage(List( - "QC" -> flexiprepPage - ), List( - "Report" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepFront.ssp") - ), - Map() - ) + override def pageArgs = Map("multisample" -> false) + + /** Index page for a flexiprep report */ + def indexPage = { + val flexiprepPage = this.flexiprepPage + ReportPage(List("Versions" -> ReportPage(List(), List(( + "Executables" -> ReportSection("/nl/lumc/sasc/biopet/core/report/executables.ssp" + ))), Map()), + "Files" -> ReportPage(List(), List( + "Input fastq files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepInputfiles.ssp"), + "After QC fastq files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepOutputfiles.ssp") + ), Map()) + ), List( + "Report" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepFront.ssp") + ) ::: flexiprepPage.sections, + Map() + ) + } - def flexiprepPage = ReportPage( + /** Generate a QC report page for 1 single library, sampleId and libId must be defined in the arguments */ + def flexiprepPage: ReportPage = ReportPage( List(), List( "Read Summary" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp"), @@ -41,8 +58,14 @@ object FlexiprepReport extends ReportBuilder { name -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepFastaqcPlot.ssp", Map("plot" -> tag)) } - // FIXME: Not yet finished - + /** + * Generated a stacked bar plot for reads QC + * @param outputDir OutputDir for plot + * @param prefix prefix for tsv and png file + * @param read Must give "R1" or "R2" + * @param summary Summary class + * @param sampleId Default selects all samples, when given plot is limits on given sample + */ def readSummaryPlot(outputDir: File, prefix: String, read: String, @@ -92,6 +115,14 @@ object FlexiprepReport extends ReportBuilder { plot.runLocal() } + /** + * Generated a stacked bar plot for bases QC + * @param outputDir OutputDir for plot + * @param prefix prefix for tsv and png file + * @param read Must give "R1" or "R2" + * @param summary Summary class + * @param sampleId Default selects all samples, when given plot is limits on given sample + */ def baseSummaryPlot(outputDir: File, prefix: String, read: String, diff --git a/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/gentrapFront.ssp b/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/gentrapFront.ssp new file mode 100644 index 0000000000000000000000000000000000000000..eb1cff542de84648c42919d5d072dcbe2afa6808 --- /dev/null +++ b/public/gentrap/src/main/resources/nl/lumc/sasc/biopet/pipelines/gentrap/gentrapFront.ssp @@ -0,0 +1,26 @@ +#import(nl.lumc.sasc.biopet.core.summary.Summary) +<%@ var summary: Summary %> +<table class="table"> +<tbody> + <tr><th>Pipeline</th><td>Gentrap</td></tr> + <tr><th>Version</th><td>${summary.getValue("meta", "pipeline_version")}</td></tr> + <tr><th>Last commit hash</th><td>${summary.getValue("meta", "last_commit_hash")}</td></tr> + <tr><th>Output directory</th><td>${summary.getValue("meta", "output_dir")}</td></tr> +</tbody> +</table> +<br/> +<div class="row"> +<div class="col-md-1"></div> +<div class="col-md-6"> + <p> + In this web document you can find your <em>Gentrap</em> pipeline report. + Different categories of data can be found in the left-side menu. + Statistics per sample and library can be accessed through the top-level menu. + Futhermore, you can view all versions of software tools used by selecting <em>Versions</em> from the top menu. + </p> + + <p> + <small>Brought to you by <a href="https://sasc.lumc.nl">SASC</a> and <a href="https://www.lumc.nl/org/klinische-genetica/">KG</a>, LUMC. </small> + </p> +</div> +</div> \ No newline at end of file diff --git a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/GentrapReport.scala b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/GentrapReport.scala new file mode 100644 index 0000000000000000000000000000000000000000..920b704ede34438fdba9ee2356c8f40076bee219 --- /dev/null +++ b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/GentrapReport.scala @@ -0,0 +1,81 @@ +package nl.lumc.sasc.biopet.pipelines.gentrap + +import nl.lumc.sasc.biopet.core.config.Configurable +import nl.lumc.sasc.biopet.core.report.{ ReportBuilderExtension, ReportSection, ReportPage, MultisampleReportBuilder } +import nl.lumc.sasc.biopet.pipelines.bammetrics.BammetricsReport +import nl.lumc.sasc.biopet.pipelines.flexiprep.FlexiprepReport + +/** + * Created by pjvanthof on 25/06/15. + */ +class GentrapReport(val root: Configurable) extends ReportBuilderExtension { + val builder = GentrapReport +} + +object GentrapReport extends MultisampleReportBuilder { + + /** Root page for the carp report */ + def indexPage = { + //Source.fromInputStream(getClass.getResourceAsStream("/nl/lumc/sasc/biopet/pipelines/carp/carpFont.ssp")).foreach(print(_)) + ReportPage( + List("Samples" -> generateSamplesPage(pageArgs)) ++ + Map("Files" -> filesPage, + "Versions" -> ReportPage(List(), List(( + "Executables" -> ReportSection("/nl/lumc/sasc/biopet/core/report/executables.ssp" + ))), Map()) + ), + List( + "Report" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gentrap/gentrapFront.ssp"), + "Alignment" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp", + Map("sampleLevel" -> true, "showPlot" -> true, "showTable" -> false) + ), + "Insert Size" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/insertSize.ssp", + Map("sampleLevel" -> true, "showPlot" -> true, "showTable" -> false)), + "QC reads" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp", + Map("showPlot" -> true, "showTable" -> false)), + "QC bases" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp", + Map("showPlot" -> true, "showTable" -> false)) + ), + pageArgs + ) + } + + /** Files page, can be used general or at sample level */ + def filesPage: ReportPage = ReportPage(List(), List( + "Input fastq files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepInputfiles.ssp"), + "After QC fastq files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepOutputfiles.ssp"), + "Bam files per lib" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/mapping/outputBamfiles.ssp", Map("sampleLevel" -> false)) //, + //"Preprocessed bam files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/mapping/outputBamfiles.ssp", + // Map("pipelineName" -> "shiva", "fileTag" -> "preProcessBam")) + ), Map()) + + /** Single sample page */ + def samplePage(sampleId: String, args: Map[String, Any]): ReportPage = { + ReportPage(List( + "Libraries" -> generateLibraryPage(args), + "Alignment" -> BammetricsReport.bamMetricsPage(summary, Some(sampleId), None), + "Files" -> filesPage + ), List( + "Alignment" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp", + if (summary.libraries(sampleId).size > 1) Map("showPlot" -> true) else Map()), + "Preprocessing" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp", Map("sampleLevel" -> true)), + "QC reads" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp"), + "QC bases" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp") + ), args) + } + + /** Library page */ + def libraryPage(sampleId: String, libId: String, args: Map[String, Any]): ReportPage = { + ReportPage(List( + "Alignment" -> BammetricsReport.bamMetricsPage(summary, Some(sampleId), Some(libId)), + "QC" -> FlexiprepReport.flexiprepPage + ), List( + "Alignment" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp"), + "QC reads" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp"), + "QC bases" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp") + ), args) + } + + /** Name of the report */ + def reportName = "Gentrap Report" +} \ No newline at end of file diff --git a/public/mapping/src/main/resources/nl/lumc/sasc/biopet/pipelines/mapping/mappingFront.ssp b/public/mapping/src/main/resources/nl/lumc/sasc/biopet/pipelines/mapping/mappingFront.ssp new file mode 100644 index 0000000000000000000000000000000000000000..8deb106af770eeb5f6c7bbb9508a81cb9e85f84b --- /dev/null +++ b/public/mapping/src/main/resources/nl/lumc/sasc/biopet/pipelines/mapping/mappingFront.ssp @@ -0,0 +1,33 @@ +#import(nl.lumc.sasc.biopet.core.summary.Summary) +#import(nl.lumc.sasc.biopet.core.report.ReportPage) +<%@ var summary: Summary %> +<%@ var rootPath: String %> +<%@ var sampleId: Option[String] %> +<%@ var libId: Option[String] %> + +<table class="table"> +<tbody> + <tr><th>Pipeline</th><td>Mapping</td></tr> + <tr><th>Version</th><td>${summary.getValue("meta", "pipeline_version")}</td></tr> + <tr><th>Last commit hash</th><td>${summary.getValue("meta", "last_commit_hash")}</td></tr> + <tr><th>Output directory</th><td>${summary.getValue("meta", "output_dir")}</td></tr> + <tr><th>Sample ID</th><td>${sampleId}</td></tr> + <tr><th>Library ID</th><td>${libId}</td></tr> +</tbody> +</table> +<br/> +<div class="row"> +<div class="col-md-1"></div> +<div class="col-md-6"> + <p> + In this web document you can find your <em>Mapping</em> pipeline report. + Different categories of data can be found in the left-side menu. + Statistics per sample and library can be accessed through the top-level menu. + Futhermore, you can view all versions of software tools used by selecting <em>Versions</em> from the top menu. + </p> + + <p> + <small>Brought to you by <a href="https://sasc.lumc.nl">SASC</a> and <a href="https://www.lumc.nl/org/klinische-genetica/">KG</a>, LUMC. </small> + </p> +</div> +</div> \ No newline at end of file diff --git a/public/mapping/src/main/resources/nl/lumc/sasc/biopet/pipelines/mapping/outputBamfiles.ssp b/public/mapping/src/main/resources/nl/lumc/sasc/biopet/pipelines/mapping/outputBamfiles.ssp index 4570ad240a6220dd06eb4412fc1456d426b36ffe..d35962f5d53969c6d04700d9c1a76f747bc3b239 100644 --- a/public/mapping/src/main/resources/nl/lumc/sasc/biopet/pipelines/mapping/outputBamfiles.ssp +++ b/public/mapping/src/main/resources/nl/lumc/sasc/biopet/pipelines/mapping/outputBamfiles.ssp @@ -20,7 +20,7 @@ val pipelineOutputDir = summary.getValue("meta", "output_dir").getOrElse("").toString def removeDir(value: Option[Any]): Option[Any] = { value.collect { case a => - if (a.toString.startsWith(pipelineOutputDir) && pipelineOutputDir.nonEmpty) "./" + a.toString.stripPrefix(pipelineOutputDir) + if (a.toString.startsWith(pipelineOutputDir) && pipelineOutputDir.nonEmpty) "./" + a.toString.stripPrefix(pipelineOutputDir + File.separator) else a } } @@ -28,9 +28,9 @@ <div class="panel-body"> <!-- Table --> -<table class="table sortable-theme-bootstrap" data-sortable> +<table class="table"> <thead><tr> - <th data-sorted="true" data-sorted-direction="ascending">Sample</th> + <th>Sample</th> #if (!sampleLevel) <th>Library</th> #end <th>Path</th> <th>MD5</th> @@ -48,8 +48,8 @@ #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 - <td>${removeDir(summary.getLibraryValue(Some(sample), (if (sampleLevel) None else Some(libId)), pipelineName, "files", "pipeline", fileTag, "path"))}</td> - <td>${summary.getLibraryValue(Some(sample), (if (sampleLevel) None else Some(libId)), pipelineName, "files", "pipeline", fileTag, "md5")}</td> + <td>${removeDir(summary.getValue(Some(sample), (if (sampleLevel) None else Some(libId)), pipelineName, "files", "pipeline", fileTag, "path"))}</td> + <td>${summary.getValue(Some(sample), (if (sampleLevel) None else Some(libId)), pipelineName, "files", "pipeline", fileTag, "md5")}</td> </tr> #end #end diff --git a/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/Mapping.scala b/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/Mapping.scala index 9c9d7d49226f2dde8e5cdeed22986dd62e26b1e5..98b3aa0fc4791432376053e52cab3f4de7578272 100644 --- a/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/Mapping.scala +++ b/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/Mapping.scala @@ -113,6 +113,16 @@ class Mapping(val root: Configurable) extends QScript with SummaryQScript with S "numberChunks" -> numberChunks.getOrElse(1) ) ++ (if (root == null) Map("reference" -> referenceSummary) else Map()) + override def reportClass = { + val mappingReport = new MappingReport(this) + mappingReport.outputDir = new File(outputDir, "report") + mappingReport.summaryFile = summaryFile + mappingReport.args = Map( + "sampleId" -> sampleId.getOrElse("."), + "libId" -> libId.getOrElse(".")) + Some(mappingReport) + } + /** Will be executed before script */ def init() { require(outputDir != null, "Missing output directory on mapping module") diff --git a/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/MappingReport.scala b/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/MappingReport.scala new file mode 100644 index 0000000000000000000000000000000000000000..b7c41922257ded86f851c198f0cabbccfeb40a1b --- /dev/null +++ b/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/MappingReport.scala @@ -0,0 +1,37 @@ +package nl.lumc.sasc.biopet.pipelines.mapping + +import nl.lumc.sasc.biopet.core.config.Configurable +import nl.lumc.sasc.biopet.core.report.{ ReportBuilderExtension, ReportSection, ReportPage, ReportBuilder } +import nl.lumc.sasc.biopet.pipelines.bammetrics.BammetricsReport +import nl.lumc.sasc.biopet.pipelines.flexiprep.FlexiprepReport + +class MappingReport(val root: Configurable) extends ReportBuilderExtension { + val builder = MappingReport +} + +/** + * Created by pjvanthof on 24/06/15. + */ +object MappingReport extends ReportBuilder { + /** Name of report */ + val reportName = "Mapping Report" + + /** Root page for single BamMetrcis report */ + def indexPage = { + val bamMetricsPage = BammetricsReport.bamMetricsPage(summary, sampleId, libId) + ReportPage(List("QC" -> FlexiprepReport.flexiprepPage) ::: bamMetricsPage.subPages ::: List( + "Versions" -> ReportPage(List(), List(( + "Executables" -> ReportSection("/nl/lumc/sasc/biopet/core/report/executables.ssp" + ))), Map()), + "Files" -> ReportPage(List(), List( + "Input fastq files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepInputfiles.ssp"), + "After QC fastq files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepOutputfiles.ssp"), + "Bam files per lib" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/mapping/outputBamfiles.ssp", Map("sampleLevel" -> false)) + ), Map()) + ), List( + "Report" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/mapping/mappingFront.ssp") + ) ::: bamMetricsPage.sections, + Map() + ) + } +} diff --git a/public/shiva/src/main/resources/nl/lumc/sasc/biopet/pipelines/shiva/outputVcfFiles.ssp b/public/shiva/src/main/resources/nl/lumc/sasc/biopet/pipelines/shiva/outputVcfFiles.ssp index a17e87c9e17596abbdba6ca55110779ac6d246d8..bd00a8618bee788821e683ac9c32f6837d3c6464 100644 --- a/public/shiva/src/main/resources/nl/lumc/sasc/biopet/pipelines/shiva/outputVcfFiles.ssp +++ b/public/shiva/src/main/resources/nl/lumc/sasc/biopet/pipelines/shiva/outputVcfFiles.ssp @@ -9,11 +9,11 @@ <%@ var rootPath: String %> <%@ var outputDir: File %> #{ - val variantCallers = summary.getLibraryValue(sampleId, libId, "shivavariantcalling", "settings", "variantcallers").get.asInstanceOf[List[String]] + val variantCallers = summary.getValue(sampleId, libId, "shivavariantcalling", "settings", "variantcallers").get.asInstanceOf[List[String]] val pipelineOutputDir = summary.getValue("meta", "output_dir").getOrElse("").toString def removeDir(value: Option[Any]): Option[Any] = { value.collect { case a => - if (a.toString.startsWith(pipelineOutputDir) && pipelineOutputDir.nonEmpty) "./" + a.toString.stripPrefix(pipelineOutputDir) + if (a.toString.startsWith(pipelineOutputDir) && pipelineOutputDir.nonEmpty) "./" + a.toString.stripPrefix(pipelineOutputDir + File.separator) else a } } @@ -21,7 +21,7 @@ <div class="panel-body"> <!-- Table --> -<table class="table sortable-theme-bootstrap" data-sortable> +<table class="table"> <thead><tr> <th>Variantcaller</th> <th>Path</th> @@ -31,15 +31,15 @@ #if (variantCallers.size > 1) <tr> <td>Final (merged)</td> - <td>${removeDir(summary.getLibraryValue(sampleId, libId, "shivavariantcalling", "files", "pipeline", "final", "path"))}</td> - <td>${summary.getLibraryValue(sampleId, libId, "shivavariantcalling", "files", "pipeline", "final", "md5")}</td> + <td>${removeDir(summary.getValue(sampleId, libId, "shivavariantcalling", "files", "pipeline", "final", "path"))}</td> + <td>${summary.getValue(sampleId, libId, "shivavariantcalling", "files", "pipeline", "final", "md5")}</td> </tr> #end #for (variantCaller <- variantCallers) <tr> <td>${variantCaller}</td> - <td>${removeDir(summary.getLibraryValue(sampleId, libId, "shivavariantcalling", "files", "pipeline", variantCaller, "path"))}</td> - <td>${summary.getLibraryValue(sampleId, libId, "shivavariantcalling", "files", "pipeline", variantCaller, "md5")}</td> + <td>${removeDir(summary.getValue(sampleId, libId, "shivavariantcalling", "files", "pipeline", variantCaller, "path"))}</td> + <td>${summary.getValue(sampleId, libId, "shivavariantcalling", "files", "pipeline", variantCaller, "md5")}</td> </tr> #end </tbody> diff --git a/public/shiva/src/main/resources/nl/lumc/sasc/biopet/pipelines/shiva/shivaFront.ssp b/public/shiva/src/main/resources/nl/lumc/sasc/biopet/pipelines/shiva/shivaFront.ssp index d078792d62929bba393e73603ede48f2e5d3e204..a5a07ab53240da743b801b4f15208b1d39704f37 100644 --- a/public/shiva/src/main/resources/nl/lumc/sasc/biopet/pipelines/shiva/shivaFront.ssp +++ b/public/shiva/src/main/resources/nl/lumc/sasc/biopet/pipelines/shiva/shivaFront.ssp @@ -13,6 +13,7 @@ <th>Variantcallers</th> <td>${summary.getValue("shivavariantcalling", "settings", "variantcallers").get.asInstanceOf[List[String]].mkString(", ")}</td> </tr> + <tr><th>Reference</th><td>${summary.getValue("shiva", "settings", "reference", "species")} - ${summary.getValue("shiva", "settings", "reference", "name")}</td></tr> <tr><th>Number of samples</th><td>${summary.samples.size}</td></tr> </tbody> </table> @@ -21,11 +22,11 @@ <div class="col-md-1"></div> <div class="col-md-6"> <p> - In this web document you can find your Shiva pipeline report. + In this web document you can find your <em>Shiva</em> pipeline report. Different categories of data can be found in the left-side menu. Statistics per sample and library can be accessed through the top-level menu. Some statistics for target regions can be found in the regions tab. - Futhermore, you can view all versions of software tools used by selecting "Versions" from the top menu. + Futhermore, you can view all versions of software tools used by selecting <em>Versions</em> from the top menu. </p> <p> diff --git a/public/shiva/src/main/scala/nl/lumc/sasc/biopet/pipelines/shiva/ShivaReport.scala b/public/shiva/src/main/scala/nl/lumc/sasc/biopet/pipelines/shiva/ShivaReport.scala index e3a2634896730962d8fd636eac7861e02506055f..4463b192ae940770d7655fda03dac79aaa0d7d6c 100644 --- a/public/shiva/src/main/scala/nl/lumc/sasc/biopet/pipelines/shiva/ShivaReport.scala +++ b/public/shiva/src/main/scala/nl/lumc/sasc/biopet/pipelines/shiva/ShivaReport.scala @@ -14,20 +14,21 @@ import nl.lumc.sasc.biopet.pipelines.flexiprep.FlexiprepReport */ class ShivaReport(val root: Configurable) extends ReportBuilderExtension { val builder = ShivaReport - - override val defaultCoreMemory = 3.0 } +/** Object for report generation for Shiva pipeline */ object ShivaReport extends MultisampleReportBuilder { - // FIXME: Not yet finished - + /** Root page for the shiva report */ def indexPage = { val regions = regionsPage ReportPage( List("Samples" -> generateSamplesPage(pageArgs)) ++ (if (regions.isDefined) Map(regions.get) else Map()) ++ - Map("Files" -> filesPage, + Map("Reference" -> ReportPage(List(), List( + "Reference" -> ReportSection("/nl/lumc/sasc/biopet/core/report/reference.ssp", Map("pipeline" -> "shiva")) + ), Map()), + "Files" -> filesPage, "Versions" -> ReportPage(List(), List(( "Executables" -> ReportSection("/nl/lumc/sasc/biopet/core/report/executables.ssp" ))), Map()) @@ -52,7 +53,9 @@ object ShivaReport extends MultisampleReportBuilder { ) } - def regionsPage = { + //TODO: Add variants per target + /** Generate a page with all target coverage stats */ + def regionsPage: Option[(String, ReportPage)] = { val roi = summary.getValue("shiva", "settings", "regions_of_interest") val amplicon = summary.getValue("shiva", "settings", "amplicon_bed") @@ -88,7 +91,8 @@ object ShivaReport extends MultisampleReportBuilder { else None } - def filesPage = ReportPage(List(), List( + /** Files page, can be used general or at sample level */ + def filesPage: ReportPage = ReportPage(List(), List( "Input fastq files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepInputfiles.ssp"), "After QC fastq files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepOutputfiles.ssp"), "Bam files per lib" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/mapping/outputBamfiles.ssp", Map("sampleLevel" -> false)), @@ -97,7 +101,8 @@ object ShivaReport extends MultisampleReportBuilder { "VCF files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/shiva/outputVcfFiles.ssp", Map("sampleId" -> None)) ), Map()) - def samplePage(sampleId: String, args: Map[String, Any]) = { + /** Single sample page */ + def samplePage(sampleId: String, args: Map[String, Any]): ReportPage = { ReportPage(List( "Libraries" -> generateLibraryPage(args), "Alignment" -> BammetricsReport.bamMetricsPage(summary, Some(sampleId), None), @@ -112,7 +117,8 @@ object ShivaReport extends MultisampleReportBuilder { ), args) } - def libraryPage(sampleId: String, libId: String, args: Map[String, Any]) = { + /** Library page */ + def libraryPage(sampleId: String, libId: String, args: Map[String, Any]): ReportPage = { ReportPage(List( "Alignment" -> BammetricsReport.bamMetricsPage(summary, Some(sampleId), Some(libId)), "QC" -> FlexiprepReport.flexiprepPage @@ -123,8 +129,17 @@ object ShivaReport extends MultisampleReportBuilder { ), args) } + /** Name of the report */ def reportName = "Shiva Report" + /** + * Generate a stackbar plot for found variants + * @param outputDir OutputDir for the tsv and png file + * @param prefix Prefix of the tsv and png file + * @param summary Summary class + * @param libraryLevel Default false, when set true plot will be based on library stats instead of sample stats + * @param sampleId Default it selects all sampples, when sample is giving it limits to selected sample + */ def variantSummaryPlot(outputDir: File, prefix: String, summary: Summary, diff --git a/public/shiva/src/main/scala/nl/lumc/sasc/biopet/pipelines/shiva/ShivaTrait.scala b/public/shiva/src/main/scala/nl/lumc/sasc/biopet/pipelines/shiva/ShivaTrait.scala index 5ab369782a4aeeef70bf86ad8af197080a0e1db6..cacb6846711d360a80a8422b6c4b3f9a348ece0e 100644 --- a/public/shiva/src/main/scala/nl/lumc/sasc/biopet/pipelines/shiva/ShivaTrait.scala +++ b/public/shiva/src/main/scala/nl/lumc/sasc/biopet/pipelines/shiva/ShivaTrait.scala @@ -250,7 +250,7 @@ trait ShivaTrait extends MultiSampleQScript with SummaryQScript with Reference { val bamMetrics = new BamMetrics(qscript) bamMetrics.sampleId = Some(sampleId) bamMetrics.inputBam = preProcessBam.get - bamMetrics.outputDir = sampleDir + bamMetrics.outputDir = new File(sampleDir, "metrics") bamMetrics.init() bamMetrics.biopetScript() addAll(bamMetrics.functions)