diff --git a/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/rnaHistogram.ssp b/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/rnaHistogram.ssp new file mode 100644 index 0000000000000000000000000000000000000000..9c055ad97492ba782453472a4d7528f92dc28ade --- /dev/null +++ b/public/bammetrics/src/main/resources/nl/lumc/sasc/biopet/pipelines/bammetrics/rnaHistogram.ssp @@ -0,0 +1,93 @@ +#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("PF_ALIGNED_BASES", "MEDIAN_5PRIME_BIAS", "MEDIAN_3PRIME_BIAS", "MEDIAN_5PRIME_TO_3PRIME_BIAS")%> +<%@ 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> + This Show the relative coverage for all transcripts. De data here is generated by picard CollectRnaMetrics + </p> + </div> + </div> +#end + +#if (showPlot) + #{ BammetricsReport.rnaHistogramPlot(outputDir, "rna", summary, !sampleLevel, sampleId = sampleId, libId = libId) }# + + <div class="panel-body"> + <img src="rna.png" class="img-responsive" /> + </div> + <div class="panel-footer"> + #if (showTable) + <button type="button" class="btn btn-info" data-toggle="collapse" data-target="#rnaTable">Hide table</button> + #else + <button type="button" class="btn btn-info" data-toggle="collapse" data-target="#rnaTable">Show table</button> + #end + <i class="glyphicon glyphicon-file"></i> <a href="rna.tsv">tsv file</a> + </div> +#end + +<div class="panel-body collapse #if (showTable)in#end" id="rnaTable"> +<!-- Table --> +<table class="table sortable-theme-bootstrap" data-sortable> + <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("rna", "metrics", field.toUpperCase)):_*).getOrElse(prefixPath ::: metricsTag :: Nil) + } + }# + #for (value <- fieldValues) + <td>${value}</td> + #end + </tr> + #end + #end + </tbody> +</table> + +</div> 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 4da9ec9e5f878262e66473d559cc209580674992..10cecfb2d8c54ff18c78fc74385993bcf17312d7 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 @@ -57,9 +57,13 @@ object BammetricsReport extends ReportBuilder { sampleId: Option[String], libId: Option[String], metricsTag: String = "bammetrics") = { + + val wgsExecuted = summary.getValue(sampleId, libId, metricsTag, "stats", "wgs").isDefined + val rnaExecuted = summary.getValue(sampleId, libId, metricsTag, "stats", "rna").isDefined + val targets = ( - summary.getValue(sampleId, libId, "bammetrics", "settings", "amplicon_name"), - summary.getValue(sampleId, libId, "bammetrics", "settings", "roi_name") + summary.getValue(sampleId, libId, metricsTag, "settings", "amplicon_name"), + summary.getValue(sampleId, libId, metricsTag, "settings", "roi_name") ) match { case (Some(amplicon: String), Some(roi: List[_])) => amplicon :: roi.map(_.toString) case (_, Some(roi: List[_])) => roi.map(_.toString) @@ -74,9 +78,13 @@ 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)), - "Whole genome coverage" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/wgsHistogram.ssp", Map("showPlot" -> true)) - ), + "Insert Size" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/insertSize.ssp", Map("showPlot" -> true)) + ) ++ (if (wgsExecuted) List("Whole genome coverage" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/wgsHistogram.ssp", + Map("showPlot" -> true))) + else Nil) ++ + (if (rnaExecuted) List("Rna coverage" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/rnaHistogram.ssp", + Map("showPlot" -> true))) + else Nil), Map("metricsTag" -> metricsTag) ) } @@ -321,4 +329,94 @@ object BammetricsReport extends ReportBuilder { plot.title = Some("Whole genome coverage") plot.runLocal() } + + /** + * Generate a line plot for rna 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 rnaHistogramPlot(outputDir: File, + prefix: String, + summary: Summary, + libraryLevel: Boolean = false, + sampleId: Option[String] = None, + libId: Option[String] = None): Unit = { + val tsvFile = new File(outputDir, prefix + ".tsv") + val pngFile = new File(outputDir, prefix + ".png") + val tsvWriter = new PrintWriter(tsvFile) + if (libraryLevel) { + tsvWriter.println((for ( + sample <- summary.samples if sampleId.isEmpty || sampleId.get == sample; + lib <- summary.libraries(sample) if libId.isEmpty || libId.get == lib + ) yield s"$sample-$lib") + .mkString("library\t", "\t", "")) + } else { + sampleId match { + case Some(sample) => tsvWriter.println("\t" + sample) + case _ => tsvWriter.println(summary.samples.mkString("Sample\t", "\t", "")) + } + } + + var map: Map[Int, Map[String, Double]] = Map() + + def fill(sample: String, lib: Option[String]): Unit = { + + val insertSize = new SummaryValue(List("bammetrics", "stats", "rna", "histogram", "normalized_position"), + summary, Some(sample), lib).value.getOrElse(List()) + val counts = new SummaryValue(List("bammetrics", "stats", "rna", "histogram", "All_Reads.normalized_coverage"), + summary, Some(sample), lib).value.getOrElse(List()) + + (insertSize, counts) match { + case (l: List[_], l2: List[_]) => + l.zip(l2).foreach(i => { + val insertSize = i._1.toString.toInt + val count = i._2.toString.toDouble + val old = map.getOrElse(insertSize, Map()) + if (libraryLevel) map += insertSize -> (old + ((s"$sample-" + lib.get) -> count)) + else map += insertSize -> (old + (sample -> count)) + }) + case _ => throw new IllegalStateException("Must be a list") + } + } + + if (libraryLevel) { + for ( + sample <- summary.samples if sampleId.isEmpty || sampleId.get == sample; + lib <- summary.libraries(sample) if libId.isEmpty || libId.get == lib + ) fill(sample, Some(lib)) + } else if (sampleId.isDefined) fill(sampleId.get, None) + else summary.samples.foreach(fill(_, None)) + + for ((insertSize, counts) <- map) { + tsvWriter.print(insertSize) + if (libraryLevel) { + for ( + sample <- summary.samples if sampleId.isEmpty || sampleId.get == sample; + lib <- summary.libraries(sample) if libId.isEmpty || libId.get == lib + ) { + tsvWriter.print("\t" + counts.getOrElse(s"$sample-$lib", "0")) + } + } else { + for (sample <- summary.samples if sampleId.isEmpty || sampleId.get == sample) { + tsvWriter.print("\t" + counts.getOrElse(sample, "0")) + } + } + tsvWriter.println() + } + + tsvWriter.close() + + val plot = new LinePlot(null) + plot.input = tsvFile + plot.output = pngFile + plot.xlabel = Some("Reletive position") + plot.ylabel = Some("Coverage") + plot.width = Some(1200) + plot.removeZero = true + plot.title = Some("Rna coverage") + plot.runLocal() + } } 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 fcc6afa62dd7ff72b046e009fdd931312214a079..17e358d2d86f870f983fe692df9c02475aabf5e4 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 @@ -18,6 +18,7 @@ package nl.lumc.sasc.biopet.pipelines.carp import java.io.File import nl.lumc.sasc.biopet.core._ +import nl.lumc.sasc.biopet.core.report.ReportBuilderExtension import nl.lumc.sasc.biopet.extensions.macs2.Macs2CallPeak import nl.lumc.sasc.biopet.extensions.picard.BuildBamIndex import nl.lumc.sasc.biopet.extensions.samtools.SamtoolsView @@ -95,7 +96,7 @@ class Carp(val root: Configurable) extends QScript with MultisampleMappingTrait } } - override def reportClass = { + override def reportClass: Option[ReportBuilderExtension] = { val carp = new CarpReport(this) carp.outputDir = new File(outputDir, "report") carp.summaryFile = summaryFile 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 index a06cef16f169732aba3ebe31357f907d24ac2eca..756d1e33d32f8008ed5c06fc0f8d2595c15d3b76 100644 --- 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 @@ -15,10 +15,9 @@ */ package nl.lumc.sasc.biopet.pipelines.carp +import nl.lumc.sasc.biopet.core.report.{ ReportSection, ReportBuilderExtension } +import nl.lumc.sasc.biopet.pipelines.mapping.MultisampleMappingReportTrait import nl.lumc.sasc.biopet.utils.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 /** * Class for report for CArp @@ -29,71 +28,10 @@ class CarpReport(val root: Configurable) extends ReportBuilderExtension { def 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()), - "Merged" -> 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) - } - +object CarpReport extends MultisampleMappingReportTrait { /** Name of the report */ def reportName = "Carp Report" + override def frontSection = ReportSection("/nl/lumc/sasc/biopet/pipelines/carp/carpFront.ssp") + + override def pipelineName = "carp" } \ No newline at end of file diff --git a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/Gentrap.scala b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/Gentrap.scala index fbb095945778b9dcb727cccf668f50184990e161..0eab05598fc49307439534a0845a03d415b863fd 100644 --- a/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/Gentrap.scala +++ b/public/gentrap/src/main/scala/nl/lumc/sasc/biopet/pipelines/gentrap/Gentrap.scala @@ -19,6 +19,7 @@ import java.io.File import nl.lumc.sasc.biopet.FullVersion import nl.lumc.sasc.biopet.core._ +import nl.lumc.sasc.biopet.core.report.ReportBuilderExtension import nl.lumc.sasc.biopet.extensions.picard.{ MergeSamFiles, SortSam } import nl.lumc.sasc.biopet.extensions.samtools.SamtoolsView import nl.lumc.sasc.biopet.extensions.tools.{ MergeTables, WipeReads } @@ -53,6 +54,13 @@ class Gentrap(val root: Configurable) extends QScript // alternative constructor for initialization with empty configuration def this() = this(null) + override def reportClass: Option[ReportBuilderExtension] = { + val report = new GentrapReport(this) + report.outputDir = new File(outputDir, "report") + report.summaryFile = summaryFile + Some(report) + } + /** Split aligner to use */ var aligner: String = config("aligner", default = "gsnap") @@ -124,8 +132,7 @@ class Gentrap(val root: Configurable) extends QScript ), // disable markduplicates since it may not play well with all aligners (this can still be overriden via config) "mapping" -> Map( - "skip_markduplicates" -> true, - "skip_metrics" -> true + "skip_markduplicates" -> true ) ) 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 index 55f50882862db3bdc787fffdbeb6be35cf24d009..16b8a6fff7076ae9aa9d09a59c4d8fb52c4b75f9 100644 --- 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 @@ -15,10 +15,9 @@ */ package nl.lumc.sasc.biopet.pipelines.gentrap +import nl.lumc.sasc.biopet.core.report.{ ReportBuilderExtension, ReportSection } +import nl.lumc.sasc.biopet.pipelines.mapping.MultisampleMappingReportTrait import nl.lumc.sasc.biopet.utils.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 /** * Class to generate report for [[Gentrap]] @@ -29,69 +28,12 @@ class GentrapReport(val root: Configurable) extends ReportBuilderExtension { def builder = GentrapReport } -object GentrapReport extends MultisampleReportBuilder { +object GentrapReport extends MultisampleMappingReportTrait { - /** 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) - } + override def frontSection = ReportSection("/nl/lumc/sasc/biopet/pipelines/gentrap/gentrapFront.ssp") /** Name of the report */ def reportName = "Gentrap Report" + + override def pipelineName = "gentrap" } \ No newline at end of file diff --git a/public/mapping/src/main/resources/nl/lumc/sasc/biopet/pipelines/mapping/multisampleMappingFront.ssp b/public/mapping/src/main/resources/nl/lumc/sasc/biopet/pipelines/mapping/multisampleMappingFront.ssp new file mode 100644 index 0000000000000000000000000000000000000000..a7027c4681c22f8119456fd445c5ddf83bb2366b --- /dev/null +++ b/public/mapping/src/main/resources/nl/lumc/sasc/biopet/pipelines/mapping/multisampleMappingFront.ssp @@ -0,0 +1,36 @@ +#import(nl.lumc.sasc.biopet.utils.summary.Summary) +#import(nl.lumc.sasc.biopet.core.report.ReportPage) +<%@ var summary: Summary %> +<%@ var rootPath: String %> + +<table class="table"> +<tbody> + <tr><th>Pipeline</th><td>Shiva</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>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> +<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>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 <em>Versions</em> from the top menu. + </p> + + <p> + <small>Brought to you by <a href="https://sasc.lumc.nl" target="_blank"><abbr + title="Sequence Analysis Support Core">SASC</abbr></a> and <a + href="https://www.lumc.nl/org/klinische-genetica/" target="_blank"><abbr title="Clinical Genetics LUMC">KG</abbr></a>, + LUMC. + </small> + </p> + </div> +</div> \ No newline at end of file diff --git a/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/MultisampleMappingReport.scala b/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/MultisampleMappingReport.scala new file mode 100644 index 0000000000000000000000000000000000000000..30e4e3e3433838cc0e07af1e54c91dca0e796b8f --- /dev/null +++ b/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/MultisampleMappingReport.scala @@ -0,0 +1,97 @@ +package nl.lumc.sasc.biopet.pipelines.mapping + +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 +import nl.lumc.sasc.biopet.utils.config.Configurable + +/** + * Created by pjvanthof on 11/01/16. + */ +class MultisampleMappingReport(val root: Configurable) extends ReportBuilderExtension { + def builder = MultisampleMappingReport +} + +object MultisampleMappingReport extends MultisampleMappingReportTrait { + /** Name of the report */ + def reportName = "Mapping Report" +} + +trait MultisampleMappingReportTrait extends MultisampleReportBuilder { + /** Front section for the report */ + def frontSection: ReportSection = ReportSection("/nl/lumc/sasc/biopet/pipelines/mapping/multisampleMappingFront.ssp") + + def pipelineName = "multisamplemapping" + + /** Root page for the carp report */ + def indexPage = { + + val wgsExecuted = summary.getSampleValues("bammetrics", "stats", "wgs").values.exists(_.isDefined) + val rnaExecuted = summary.getSampleValues("bammetrics", "stats", "rna").values.exists(_.isDefined) + + ReportPage( + List("Samples" -> generateSamplesPage(pageArgs)) ++ + Map("Reference" -> ReportPage(List(), List( + "Reference" -> ReportSection("/nl/lumc/sasc/biopet/core/report/reference.ssp", Map("pipeline" -> pipelineName)) + ), Map()), + "Files" -> filesPage, + "Versions" -> ReportPage(List(), List("Executables" -> ReportSection("/nl/lumc/sasc/biopet/core/report/executables.ssp" + )), Map()) + ), + List( + "Report" -> frontSection, + "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))) ++ + (if (wgsExecuted) List("Whole genome coverage" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/wgsHistogram.ssp", + Map("sampleLevel" -> true, "showPlot" -> true, "showTable" -> false))) + else Nil) ++ + (if (rnaExecuted) List("Rna coverage" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/rnaHistogram.ssp", + Map("sampleLevel" -> true, "showPlot" -> true, "showTable" -> false))) + else Nil) ++ + List("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" -> pipelineName, "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))) ++ + List("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) + } +} \ No newline at end of file diff --git a/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/MultisampleMappingTrait.scala b/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/MultisampleMappingTrait.scala index 22066304263f234d000f2111f061e78f4ed54cb5..496ee2260d83757d8913b95e13080cc0f25080e3 100644 --- a/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/MultisampleMappingTrait.scala +++ b/public/mapping/src/main/scala/nl/lumc/sasc/biopet/pipelines/mapping/MultisampleMappingTrait.scala @@ -3,6 +3,7 @@ package nl.lumc.sasc.biopet.pipelines.mapping import java.io.File import htsjdk.samtools.SamReaderFactory +import nl.lumc.sasc.biopet.core.report.ReportBuilderExtension import nl.lumc.sasc.biopet.core.{ PipelineCommand, Reference, MultiSampleQScript } import nl.lumc.sasc.biopet.extensions.Ln import nl.lumc.sasc.biopet.extensions.picard.{ MarkDuplicates, MergeSamFiles, AddOrReplaceReadGroups, SamToFastq } @@ -37,6 +38,13 @@ trait MultisampleMappingTrait extends MultiSampleQScript addSummaryJobs() } + override def reportClass: Option[ReportBuilderExtension] = { + val report = new MultisampleMappingReport(this) + report.outputDir = new File(outputDir, "report") + report.summaryFile = summaryFile + Some(report) + } + def addMultiSampleJobs(): Unit = { // this code will be executed after all code of all samples is executed } 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 5c88189833b1b6bd169c3da475c6c2370957abf9..decc33b463fb35a03e1d6db575ae9d81cbe69fb1 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 @@ -17,12 +17,11 @@ package nl.lumc.sasc.biopet.pipelines.shiva import java.io.{ File, PrintWriter } -import nl.lumc.sasc.biopet.utils.config.Configurable import nl.lumc.sasc.biopet.core.report._ -import nl.lumc.sasc.biopet.utils.summary.{ Summary, SummaryValue } +import nl.lumc.sasc.biopet.pipelines.mapping.MultisampleMappingReportTrait +import nl.lumc.sasc.biopet.utils.config.Configurable import nl.lumc.sasc.biopet.utils.rscript.StackedBarPlot -import nl.lumc.sasc.biopet.pipelines.bammetrics.BammetricsReport -import nl.lumc.sasc.biopet.pipelines.flexiprep.FlexiprepReport +import nl.lumc.sasc.biopet.utils.summary.{ Summary, SummaryValue } /** * With this extension the report is executed within a pipeline @@ -34,52 +33,32 @@ class ShivaReport(val root: Configurable) extends ReportBuilderExtension { } /** Object for report generation for Shiva pipeline */ -object ShivaReport extends MultisampleReportBuilder { +object ShivaReport extends MultisampleMappingReportTrait { def variantcallingExecuted = summary.getValue("shiva", "settings", "multisample_variantcalling") match { case Some(true) => true case _ => false } + override def frontSection = ReportSection("/nl/lumc/sasc/biopet/pipelines/shiva/shivaFront.ssp") + + override def pipelineName = "shiva" + override def extFiles = super.extFiles ++ List("js/gears.js") .map(x => ExtFile("/nl/lumc/sasc/biopet/pipelines/gears/report/ext/" + x, x)) /** Root page for the shiva report */ - def indexPage = { + override def indexPage = { + val variantcallingSection = (if (variantcallingExecuted) List("Variantcalling" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/shiva/sampleVariants.ssp", + Map("showPlot" -> true, "showTable" -> false))) + else Nil) + val regions = regionsPage - ReportPage( - List("Samples" -> generateSamplesPage(pageArgs)) ++ - (if (regions.isDefined) Map(regions.get) else Map()) ++ - 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()) - ), - List( - "Report" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/shiva/shivaFront.ssp")) ++ - (if (variantcallingExecuted) List("Variantcalling" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/shiva/sampleVariants.ssp", - Map("showPlot" -> true, "showTable" -> false))) - else Nil) ++ - List("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 - ) + val oldPage = super.indexPage + + oldPage.copy(sections = variantcallingSection ++ oldPage.sections, subPages = oldPage.subPages ++ 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") @@ -121,49 +100,19 @@ object ShivaReport extends MultisampleReportBuilder { } /** 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"))) ++ - (if (variantcallingExecuted) List("VCF files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/shiva/outputVcfFiles.ssp", + override def filesPage: ReportPage = { + val vcfFilesSection = if (variantcallingExecuted) List("VCF files" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/shiva/outputVcfFiles.ssp", Map("sampleId" -> None))) - else Nil), 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))) ++ - (if (variantcallingExecuted) List("Variantcalling" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/shiva/sampleVariants.ssp")) else Nil) ++ - List("QC reads" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp"), - "QC bases" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp") - ), args) + else Nil + val oldPage = super.filesPage + oldPage.copy(sections = oldPage.sections ++ vcfFilesSection) } - /** Library page */ - def libraryPage(sampleId: String, libId: String, args: Map[String, Any]): ReportPage = { - val flexiprepExecuted = summary.getLibraryValue(sampleId, libId, "flexiprep").isDefined - val krakenExecuted = summary.getValue(Some(sampleId), Some(libId), "gears", "stats", "krakenreport").isDefined - - ReportPage( - "Alignment" -> BammetricsReport.bamMetricsPage(summary, Some(sampleId), Some(libId)) :: - (if (flexiprepExecuted) List("QC" -> FlexiprepReport.flexiprepPage) else Nil - ) ::: (if (krakenExecuted) List("Gears - Metagenomics" -> ReportPage(List(), List( - "Sunburst analysis" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/gearsSunburst.ssp" - )), Map())) - else Nil), "Alignment" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp") :: - (if (flexiprepExecuted) List( - "QC reads" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp"), - "QC bases" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp") - ) - else Nil), args) + /** Single sample page */ + override def samplePage(sampleId: String, args: Map[String, Any]): ReportPage = { + val variantcallingSection = if (variantcallingExecuted) List("Variantcalling" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/shiva/sampleVariants.ssp")) else Nil + val oldPage = super.samplePage(sampleId, args) + oldPage.copy(sections = variantcallingSection ++ oldPage.sections) } /** Name of the report */ 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 58a4710cad1019ed79dba8a46a1c06053d14e436..f0fe2c1291d647815f8d336902fbd944f6312f3f 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 @@ -16,8 +16,9 @@ package nl.lumc.sasc.biopet.pipelines.shiva import nl.lumc.sasc.biopet.core.Reference +import nl.lumc.sasc.biopet.core.report.ReportBuilderExtension import nl.lumc.sasc.biopet.pipelines.bammetrics.TargetRegions -import nl.lumc.sasc.biopet.pipelines.mapping.{ MultisampleMappingTrait } +import nl.lumc.sasc.biopet.pipelines.mapping.MultisampleMappingTrait import nl.lumc.sasc.biopet.pipelines.toucan.Toucan import org.broadinstitute.gatk.queue.QScript @@ -28,7 +29,7 @@ import org.broadinstitute.gatk.queue.QScript */ trait ShivaTrait extends MultisampleMappingTrait with Reference with TargetRegions { qscript: QScript => - override def reportClass = { + override def reportClass: Option[ReportBuilderExtension] = { val shiva = new ShivaReport(this) shiva.outputDir = new File(outputDir, "report") shiva.summaryFile = summaryFile