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
import scala.concurrent.duration.Duration
26
import scala.concurrent.ExecutionContext.Implicits.global
Peter van 't Hof's avatar
Peter van 't Hof committed
27

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

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

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

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

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

Peter van 't Hof's avatar
Peter van 't Hof committed
48
49
50
  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))

51
52
  /** Root page for the carp report */
  def indexPage = {
Peter van 't Hof's avatar
Peter van 't Hof committed
53

Peter van 't Hof's avatar
Peter van 't Hof committed
54
55
56
57
58
59
60
61
    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
62
    val insertsizeExecuted = summary.getSettingsForSamples(runId, pipelineName, NoModule, keyValues = Map()).count(_._2("paired") == Some(true)) >= 1
Peter van 't Hof's avatar
Peter van 't Hof committed
63
64
    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
65
    val pairedFound = !mappingExecuted || mappingSettings.exists(_._2.exists(_._2 == Option(true)))
Peter van 't Hof's avatar
Peter van 't Hof committed
66
    val flexiprepExecuted = Await.result(summary.getStatsSize(runId, "flexiprep", mustHaveLibrary = true), Duration.Inf) >= 1
Peter van 't Hof's avatar
Peter van 't Hof committed
67

68
69
    ReportPage(
      List("Samples" -> generateSamplesPage(pageArgs)) ++
Peter van 't Hof's avatar
Peter van 't Hof committed
70
        (if (krakenExecuted) List("Dustbin analysis - Kraken" -> ReportPage(List(), List(
71
72
          "Krona plot" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp"
          )), Map()))
Peter van 't Hof's avatar
Peter van 't Hof committed
73
74
75
76
77
        else Nil) ++ (if (centrifugeExecuted) List("Centriguge analysis" -> ReportPage(List("Non-unique" -> ReportPage(List(), List("All mappings" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp",
          Map("summaryStatsTag" -> "centrifuge_report")
        )), Map())), List(
          "Unique mappings" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp",
            Map("summaryStatsTag" -> "centrifuge_unique_report")
78
          )), Map("summaryModuleTag" -> "gearscentrifuge", "centrifugeTag" -> Some("centrifuge"))))
79
80
        else Nil) ++
        List("Reference" -> 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))
82
        ), Map()),
83
          "Files" -> Await.result(filesPage(), Duration.Inf),
84
85
86
87
          "Versions" -> ReportPage(List(), List("Executables" -> ReportSection("/nl/lumc/sasc/biopet/core/report/executables.ssp"
          )), Map())
        ),
      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
132
133
      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")
        summary.getPipelineName(pipelineId = pipelineId).map(_.get -> ReportPage(Nil, Await.result(Future.sequence(moduleSectionsSorted), Duration.Inf).toList, Map()))
    })
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]): ReportPage = {
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
      (if (centrifugeExecuted) List("Centriguge analysis" -> ReportPage(List("Non-unique" -> ReportPage(List(), List("All mappings" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp",
155
        Map("summaryStatsTag" -> "centrifuge_report", "centrifugeTag" -> Some("centrifuge"))
Peter van 't Hof's avatar
Peter van 't Hof committed
156
157
158
159
160
      )), Map())), List(
        "Unique mappings" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp",
          Map("summaryStatsTag" -> "centrifuge_unique_report")
        )), Map("summaryModuleTag" -> "gearscentrifuge")))
      else Nil) ::: (if (krakenExecuted) List("Dustbin analysis" -> ReportPage(List(), List(
Peter van 't Hof's avatar
Peter van 't Hof committed
161
        "Krona Plot" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/gears/krakenKrona.ssp"
162
163
        )), Map()))
      else Nil) ++
164
      List("Files" -> Await.result(filesPage(sampleId = sampleId), Duration.Inf)
Peter van 't Hof's avatar
Peter van 't Hof committed
165
      ), List(
166
      "Alignment" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp",
Peter van 't Hof's avatar
Peter van 't Hof committed
167
        Map("showPlot" -> true)),
168
      "Preprocessing" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/bammetrics/alignmentSummary.ssp", Map("sampleLevel" -> true))) ++
169
      (if (flexiprepExecuted) List("QC reads" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepReadSummary.ssp"),
170
        "QC bases" -> ReportSection("/nl/lumc/sasc/biopet/pipelines/flexiprep/flexiprepBaseSummary.ssp")
171
172
      )
      else Nil), args)
173
174
175
  }

  /** Library page */
Peter van 't Hof's avatar
Peter van 't Hof committed
176
  def libraryPage(sampleId: Int, libId: Int, args: Map[String, Any]): ReportPage = {
Peter van 't Hof's avatar
Peter van 't Hof committed
177
178
179
180
181
182
    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
183

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