MultisampleMappingReport.scala 12.4 KB
Newer Older
Peter van 't Hof's avatar
Peter van 't Hof committed
1 2 3 4 5 6 7 8 9 10
/**
 * Biopet is built on top of GATK Queue for building bioinformatic
 * pipelines. It is mainly intended to support LUMC SHARK cluster which is running
 * SGE. But other types of HPC that are supported by GATK Queue (such as PBS)
 * should also be able to execute Biopet tools and pipelines.
 *
 * Copyright 2014 Sequencing Analysis Support Core - Leiden University Medical Center
 *
 * Contact us at: sasc@lumc.nl
 *
11
 * A dual licensing mode is applied. The source code within this project is freely available for non-commercial use under an AGPL
Peter van 't Hof's avatar
Peter van 't Hof committed
12 13 14
 * license; For commercial users or users who do not want to follow the AGPL
 * license, please contact us to obtain a separate license.
 */
15 16
package nl.lumc.sasc.biopet.pipelines.mapping

Peter van 't Hof's avatar
Peter van 't Hof committed
17
import nl.lumc.sasc.biopet.core.report.{ MultisampleReportBuilder, ReportBuilderExtension, ReportPage, ReportSection }
18 19 20
import nl.lumc.sasc.biopet.pipelines.bammetrics.BammetricsReport
import nl.lumc.sasc.biopet.pipelines.flexiprep.FlexiprepReport
import nl.lumc.sasc.biopet.utils.config.Configurable
Peter van 't Hof's avatar
Peter van 't Hof committed
21
import nl.lumc.sasc.biopet.utils.summary.db.SummaryDb.Implicts._
22
import nl.lumc.sasc.biopet.utils.summary.db.SummaryDb._
23

Peter van 't Hof's avatar
Peter van 't Hof committed
24
import scala.concurrent.{ Await, Future }
Peter van 't Hof's avatar
Peter van 't Hof committed
25 26
import scala.concurrent.duration.Duration

27
/**
Peter van 't Hof's avatar
Peter van 't Hof committed
28 29
 * Created by pjvanthof on 11/01/16.
 */
Peter van 't Hof's avatar
Peter van 't Hof committed
30
class MultisampleMappingReport(val parent: Configurable) extends ReportBuilderExtension {
31 32 33 34 35 36 37 38 39
  def builder = MultisampleMappingReport
}

object MultisampleMappingReport extends MultisampleMappingReportTrait {
  /** Name of the report */
  def reportName = "Mapping Report"
}

trait MultisampleMappingReportTrait extends MultisampleReportBuilder {
40
  /** Front section for the report */
Peter van 't Hof's avatar
Peter van 't Hof committed
41
  def frontSection: ReportSection = ReportSection("/nl/lumc/sasc/biopet/pipelines/mapping/multisampleMappingFront.ssp")
42

43 44
  def additionalSections: List[(String, ReportSection)] = Nil

Peter van 't Hof's avatar
Peter van 't Hof committed
45 46
  def pipelineName = "multisamplemapping"

Peter van 't Hof's avatar
Peter van 't Hof committed
47 48 49
  override def extFiles = super.extFiles ++ List("js/gears.js", "js/krona-2.0.js", "img/krona/loading.gif", "img/krona/hidden.png", "img/krona/favicon.ico")
    .map(x => ExtFile("/nl/lumc/sasc/biopet/pipelines/gears/report/ext/" + x, x))

50
  /** Root page for the carp report */
Peter van 't Hof's avatar
Peter van 't Hof committed
51
  def indexPage: Future[ReportPage] = Future {
Peter van 't Hof's avatar
Peter van 't Hof committed
52

Peter van 't Hof's avatar
Peter van 't Hof committed
53 54 55 56 57 58 59 60
    val krakenExecuted = Await.result(summary.getStatsSize(runId, "gearskraken", "krakenreport",
      library = NoLibrary, mustHaveSample = true), Duration.Inf) >= 1
    val centrifugeExecuted = Await.result(summary.getStatsSize(runId, "gearscentrifuge", "centrifuge_report",
      library = NoLibrary, mustHaveSample = true), Duration.Inf) >= 1
    val wgsExecuted = Await.result(summary.getStatsSize(runId, "bammetrics", "wgs",
      library = NoLibrary, mustHaveSample = true), Duration.Inf) >= 1
    val rnaExecuted = Await.result(summary.getStatsSize(runId, "bammetrics", "rna",
      library = NoLibrary, mustHaveSample = true), Duration.Inf) >= 1
61
    val insertsizeExecuted = summary.getStatsForSamples(runId, "bammetrics", "CollectInsertSizeMetrics", keyValues = Map("metrics" -> List("metrics"))).exists(_._2("metrics").isDefined)
Peter van 't Hof's avatar
Peter van 't Hof committed
62 63
    val mappingExecuted = Await.result(summary.getStatsSize(runId, "mapping", NoModule, mustHaveLibrary = true), Duration.Inf) >= 1
    val mappingSettings = summary.getSettingsForLibraries(runId, "mapping", NoModule, keyValues = Map("paired" -> List("paired")))
Peter van 't Hof's avatar
Peter van 't Hof committed
64
    val pairedFound = !mappingExecuted || mappingSettings.exists(_._2.exists(_._2 == Option(true)))
Peter van 't Hof's avatar
Peter van 't Hof committed
65
    val flexiprepExecuted = Await.result(summary.getStatsSize(runId, "flexiprep", mustHaveLibrary = true), Duration.Inf) >= 1
Peter van 't Hof's avatar
Peter van 't Hof committed
66

67 68
    ReportPage(
      List("Samples" -> generateSamplesPage(pageArgs)) ++
Peter van 't Hof's avatar
Peter van 't Hof committed
69
        (if (krakenExecuted) List("Dustbin analysis - Kraken" -> Future(ReportPage(List(), List(
70
          "Krona plot" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp"
Peter van 't Hof's avatar
Peter van 't Hof committed
71 72 73 74 75
          )), Map())))
        else Nil) ++ (if (centrifugeExecuted) List("Centriguge analysis" -> Future(ReportPage(List(
          "Non-unique" -> Future(ReportPage(List(), List("All mappings" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp",
            Map("summaryStatsTag" -> "centrifuge_report")
          )), Map()))), List(
Peter van 't Hof's avatar
Peter van 't Hof committed
76 77
          "Unique mappings" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp",
            Map("summaryStatsTag" -> "centrifuge_unique_report")
Peter van 't Hof's avatar
Peter van 't Hof committed
78
          )), Map("summaryModuleTag" -> "gearscentrifuge", "centrifugeTag" -> Some("centrifuge")))))
79
        else Nil) ++
Peter van 't Hof's avatar
Peter van 't Hof committed
80
        List("Reference" -> Future(ReportPage(List(), List(
Peter van 't Hof's avatar
Peter van 't Hof committed
81
          "Reference" -> ReportSection("/nl/lumc/sasc/biopet/core/report/reference.ssp", Map("pipeline" -> pipelineName))
Peter van 't Hof's avatar
Peter van 't Hof committed
82 83 84 85
        ), Map())),
          "Files" -> filesPage(),
          "Versions" -> Future(ReportPage(List(), List("Executables" -> ReportSection("/nl/lumc/sasc/biopet/core/report/executables.ssp"
          )), Map()))
86 87
        ),
      List(
88 89 90
        "Report" -> frontSection) ++
        additionalSections ++
        List("Alignment" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp",
91
          Map("sampleLevel" -> true, "showPlot" -> true, "showTable" -> false)
Peter van 't Hof's avatar
Peter van 't Hof committed
92
        ), "Mapping Quality" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/mappingQuality.ssp",
93
          Map("sampleLevel" -> true, "showPlot" -> true, "showTable" -> false)
Peter van 't Hof's avatar
Peter van 't Hof committed
94
        ), "Clipping" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/clipping.ssp",
95
          Map("sampleLevel" -> true, "showPlot" -> true, "showTable" -> false)
96
        )) ++
97
        (if (pairedFound && insertsizeExecuted) List("Insert Size" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/insertSize.ssp",
Peter van 't Hof's avatar
Peter van 't Hof committed
98 99
          Map("sampleLevel" -> true, "showPlot" -> true, "showTable" -> false)))
        else Nil) ++
Peter van 't Hof's avatar
Peter van 't Hof committed
100
        (if (wgsExecuted) List("Whole genome coverage" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/wgsHistogram.ssp",
Peter van 't Hof's avatar
Peter van 't Hof committed
101 102
          Map("sampleLevel" -> true, "showPlot" -> true, "showTable" -> false)))
        else Nil) ++
Peter van 't Hof's avatar
Peter van 't Hof committed
103
        (if (rnaExecuted) List("Rna coverage" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/rnaHistogram.ssp",
Peter van 't Hof's avatar
Peter van 't Hof committed
104 105
          Map("sampleLevel" -> true, "showPlot" -> true, "showTable" -> false)))
        else Nil) ++
106
        (if (flexiprepExecuted) List("QC reads" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp",
107
          Map("showPlot" -> true, "showTable" -> false)),
Peter van 't Hof's avatar
Peter van 't Hof committed
108 109
          "QC bases" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp",
            Map("showPlot" -> true, "showTable" -> false))
110 111
        )
        else Nil),
112
      pageArgs ++ Map("pipeline" -> pipelineName)
113 114 115 116
    )
  }

  /** Files page, can be used general or at sample level */
117
  def filesPage(sampleId: Option[Int] = None, libraryId: Option[Int] = None): Future[ReportPage] = {
Peter van 't Hof's avatar
Peter van 't Hof committed
118 119
    val dbFiles = summary.getFiles(runId, sample = sampleId.map(SampleId),
      library = libraryId.map(LibraryId))
120
      .map(_.groupBy(_.pipelineId))
Peter van 't Hof's avatar
Peter van 't Hof committed
121
    val modulePages = dbFiles.map(_.map {
Peter van 't Hof's avatar
Peter van 't Hof committed
122 123 124 125 126 127 128 129 130 131
      case (pipelineId, files) =>
        val moduleSections = files.groupBy(_.moduleId).map {
          case (moduleId, files) =>
            val moduleName: Future[String] = moduleId match {
              case Some(id) => summary.getModuleName(pipelineId, id).map(_.getOrElse("Pipeline"))
              case _        => Future("Pipeline")
            }
            moduleName.map(_ -> ReportSection("/nl/lumc/sasc/biopet/core/report/files.ssp", Map("files" -> files)))
        }
        val moduleSectionsSorted = moduleSections.find(_._1 == "Pipeline") ++ moduleSections.filter(_._1 != "Pipeline")
Peter van 't Hof's avatar
Peter van 't Hof committed
132
        summary.getPipelineName(pipelineId = pipelineId).map(_.get -> Future(ReportPage(Nil, Await.result(Future.sequence(moduleSectionsSorted), Duration.Inf).toList, Map())))
Peter van 't Hof's avatar
Peter van 't Hof committed
133
    })
134

Peter van 't Hof's avatar
Peter van 't Hof committed
135
    val pipelineFiles = summary.getPipelineId(runId, pipelineName).flatMap(pipelinelineId => dbFiles.map(x => x(pipelinelineId.get).filter(_.moduleId.isEmpty)))
Peter van 't Hof's avatar
Peter van 't Hof committed
136

Peter van 't Hof's avatar
Peter van 't Hof committed
137 138 139
    modulePages.flatMap(Future.sequence(_)).map(x => ReportPage(x.toList,
      s"$pipelineName files" -> ReportSection("/nl/lumc/sasc/biopet/core/report/files.ssp", Map("files" -> Await.result(pipelineFiles, Duration.Inf))) ::
        "Sub pipelines/modules" -> ReportSection("/nl/lumc/sasc/biopet/core/report/fileModules.ssp", Map("pipelineIds" -> Await.result(dbFiles.map(_.keys.toList), Duration.Inf))) :: Nil, Map()))
140
  }
141 142

  /** Single sample page */
Peter van 't Hof's avatar
Peter van 't Hof committed
143
  def samplePage(sampleId: Int, args: Map[String, Any]): Future[ReportPage] = Future {
Peter van 't Hof's avatar
Peter van 't Hof committed
144 145 146 147 148 149
    val krakenExecuted = Await.result(summary.getStatsSize(runId, "gearskraken", "krakenreport",
      library = NoLibrary, sample = sampleId), Duration.Inf) >= 1
    val centrifugeExecuted = Await.result(summary.getStatsSize(runId, "gearscentrifuge", "centrifuge_report",
      library = NoLibrary, sample = sampleId, mustHaveSample = true), Duration.Inf) >= 1
    val flexiprepExecuted = Await.result(summary.getStatsSize(runId, "flexiprep",
      sample = sampleId, mustHaveLibrary = true), Duration.Inf) >= 1
150

151 152
    ReportPage(List(
      "Libraries" -> generateLibraryPage(args),
153
      "Alignment" -> BammetricsReport.bamMetricsPage(summary, Some(sampleId), None)) ++
Peter van 't Hof's avatar
Peter van 't Hof committed
154 155 156 157
      (if (centrifugeExecuted) List("Centriguge analysis" -> Future(ReportPage(List(
        "Non-unique" -> Future(ReportPage(List(), List("All mappings" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp",
          Map("summaryStatsTag" -> "centrifuge_report", "centrifugeTag" -> Some("centrifuge"))
        )), Map()))), List(
Peter van 't Hof's avatar
Peter van 't Hof committed
158 159
        "Unique mappings" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp",
          Map("summaryStatsTag" -> "centrifuge_unique_report")
Peter van 't Hof's avatar
Peter van 't Hof committed
160 161
        )), Map("summaryModuleTag" -> "gearscentrifuge"))))
      else Nil) ::: (if (krakenExecuted) List("Dustbin analysis" -> Future(ReportPage(List(), List(
Peter van 't Hof's avatar
Peter van 't Hof committed
162
        "Krona Plot" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp"
Peter van 't Hof's avatar
Peter van 't Hof committed
163
        )), Map())))
164
      else Nil) ++
Peter van 't Hof's avatar
Peter van 't Hof committed
165
      List("Files" -> filesPage(sampleId = sampleId)
Peter van 't Hof's avatar
Peter van 't Hof committed
166
      ), List(
167
      "Alignment" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp",
Peter van 't Hof's avatar
Peter van 't Hof committed
168
        Map("showPlot" -> true)),
169
      "Preprocessing" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp", Map("sampleLevel" -> true))) ++
170
      (if (flexiprepExecuted) List("QC reads" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp"),
171
        "QC bases" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp")
172 173
      )
      else Nil), args)
174 175 176
  }

  /** Library page */
Peter van 't Hof's avatar
Peter van 't Hof committed
177
  def libraryPage(sampleId: Int, libId: Int, args: Map[String, Any]): Future[ReportPage] = Future {
Peter van 't Hof's avatar
Peter van 't Hof committed
178 179 180 181 182 183
    val krakenExecuted = Await.result(summary.getStatsSize(runId, "gearskraken", "krakenreport",
      library = libId, sample = sampleId), Duration.Inf) >= 1
    val centrifugeExecuted = Await.result(summary.getStatsSize(runId, "gearscentrifuge", "centrifuge_report",
      library = libId, sample = sampleId, mustHaveSample = true), Duration.Inf) >= 1
    val flexiprepExecuted = Await.result(summary.getStatsSize(runId, "flexiprep", library = libId,
      sample = sampleId, mustHaveLibrary = true), Duration.Inf) >= 1
Peter van 't Hof's avatar
Peter van 't Hof committed
184

Peter van 't Hof's avatar
Peter van 't Hof committed
185 186
    ReportPage(
      ("Alignment" -> BammetricsReport.bamMetricsPage(summary, Some(sampleId), Some(libId))) ::
187
        (if (flexiprepExecuted) List("QC" -> FlexiprepReport.flexiprepPage) else Nil) :::
Peter van 't Hof's avatar
Peter van 't Hof committed
188 189 190 191
        (if (centrifugeExecuted) List("Centriguge analysis" -> Future(ReportPage(List(
          "Non-unique" -> Future(ReportPage(List(), List("All mappings" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp",
            Map("summaryStatsTag" -> "centrifuge_report")
          )), Map()))), List(
Peter van 't Hof's avatar
Peter van 't Hof committed
192 193
          "Unique mappings" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp",
            Map("summaryStatsTag" -> "centrifuge_unique_report")
Peter van 't Hof's avatar
Peter van 't Hof committed
194 195
          )), Map("summaryModuleTag" -> "gearscentrifuge", "centrifugeTag" -> Some("centrifuge")))))
        else Nil) ::: (if (krakenExecuted) List("Dustbin analysis" -> Future(ReportPage(List(), List(
Peter van 't Hof's avatar
Peter van 't Hof committed
196
          "Krona Plot" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp"
Peter van 't Hof's avatar
Peter van 't Hof committed
197 198
          )), Map())))
        else Nil) ::: List("Files" -> filesPage(sampleId = sampleId, libraryId = libId)),
199 200 201 202 203
      "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)
204 205
  }
}