From 66c2c7c7b91623bed1f31c0b5ed7d2eabf1bae35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciek=20B=C4=85k?= Date: Wed, 10 Jan 2024 16:22:05 +0100 Subject: [PATCH] refactor: update the HTML report (#30) --- resources/activities-3ss.html | 99 +++++++++++++++ resources/activities-5ss.html | 99 +++++++++++++++ resources/activities-pas.html | 99 +++++++++++++++ resources/exon-inclusion.html | 113 +++++++++++++++++ resources/gene-expression.html | 106 ++++++++++++++++ resources/mapp_logo.png | Bin 0 -> 31244 bytes resources/pas-expression.html | 178 +++++++++++++++++++++++++++ resources/template.html | 57 +++++---- resources/transcript-expression.html | 105 ++++++++++++++++ scripts/generate-final-report.py | 91 +++++++++----- 10 files changed, 896 insertions(+), 51 deletions(-) create mode 100644 resources/activities-3ss.html create mode 100644 resources/activities-5ss.html create mode 100644 resources/activities-pas.html create mode 100644 resources/exon-inclusion.html create mode 100644 resources/gene-expression.html create mode 100644 resources/mapp_logo.png create mode 100644 resources/pas-expression.html create mode 100644 resources/transcript-expression.html diff --git a/resources/activities-3ss.html b/resources/activities-3ss.html new file mode 100644 index 00000000..8798ab3d --- /dev/null +++ b/resources/activities-3ss.html @@ -0,0 +1,99 @@ + + + + MAPP reports + + +
+
+ +

MAPP Report

+

Test run with reduced parameters on a sampled dataset

+
+ + + +   + + + +   + + + +   + + + +
+
+ + + +   + + + +   + + + +
+
+
+
+
+ This is a summary report for a MAPP run. + Motif count matrices are located under: ../modules/CREATE_SITECOUNT_MATRICES/output, + unless external pre-computer resources were specified for this specific workflow execution. + In such case please refer to the pipeline's configuration file and inspect the paths provided + under the field: MAE_sitecount_matrices. +
+
+ Fitted motif activities as well as calculated activity z-scores and their statistical significance + are stored in a tab-separated formatted (TSV) table. + Rows of this table denote various sequence motifs in specific sliding windows whereas subsequent columns follow the + structure below: +
+
+ ID : unique ID of a sequence motif in a specific sliding window +
+ activities_{sampleID} : motif activities in distinct RNA-Seq samples +
+ deltas_{sampleID} : standard deviations of motif activities +
+ zscores_{sampleID} : z-scores of motif activities +
+ combined.Zscore : overall z-score for a given motif, combined over all samples +
+ regions_present_fraction : fraction of sites for which the motif was present in a specific window +
+ region : sliding window ID +
+ motif : short sequence motif +
+ standard_zscores_{sampleID} : standardised z-scores of motif activities +
+ pval_{sampleID} : standardised p-values of motif activities +
+ corr_pval_{sampleID} : p-values corrected for multiple hypothesis testing +
+ combined.standard.Zscore : combined standardised z-scores +
+ max.abs.standard.Zscore : maximum absolute standardised z-score +
+ significance-marker : statistical significance marker for this motif in this sliding window +
+
+
+
+ + + +  + + + +
+ + diff --git a/resources/activities-5ss.html b/resources/activities-5ss.html new file mode 100644 index 00000000..a15348d1 --- /dev/null +++ b/resources/activities-5ss.html @@ -0,0 +1,99 @@ + + + + MAPP reports + + +
+
+ +

MAPP Report

+

Test run with reduced parameters on a sampled dataset

+
+ + + +   + + + +   + + + +   + + + +
+
+ + + +   + + + +   + + + +
+
+
+
+
+ This is a summary report for a MAPP run. + Motif count matrices are located under: ../modules/CREATE_SITECOUNT_MATRICES/output, + unless external pre-computer resources were specified for this specific workflow execution. + In such case please refer to the pipeline's configuration file and inspect the paths provided + under the field: MAE_sitecount_matrices. +
+
+ Fitted motif activities as well as calculated activity z-scores and their statistical significance + are stored in a tab-separated formatted (TSV) table. + Rows of this table denote various sequence motifs in specific sliding windows whereas subsequent columns follow the + structure below: +
+
+ ID : unique ID of a sequence motif in a specific sliding window +
+ activities_{sampleID} : motif activities in distinct RNA-Seq samples +
+ deltas_{sampleID} : standard deviations of motif activities +
+ zscores_{sampleID} : z-scores of motif activities +
+ combined.Zscore : overall z-score for a given motif, combined over all samples +
+ regions_present_fraction : fraction of sites for which the motif was present in a specific window +
+ region : sliding window ID +
+ motif : short sequence motif +
+ standard_zscores_{sampleID} : standardised z-scores of motif activities +
+ pval_{sampleID} : standardised p-values of motif activities +
+ corr_pval_{sampleID} : p-values corrected for multiple hypothesis testing +
+ combined.standard.Zscore : combined standardised z-scores +
+ max.abs.standard.Zscore : maximum absolute standardised z-score +
+ significance-marker : statistical significance marker for this motif in this sliding window +
+
+
+
+ + + +  + + + +
+ + diff --git a/resources/activities-pas.html b/resources/activities-pas.html new file mode 100644 index 00000000..c853cddd --- /dev/null +++ b/resources/activities-pas.html @@ -0,0 +1,99 @@ + + + + MAPP reports + + +
+
+ +

MAPP Report

+

Test run with reduced parameters on a sampled dataset

+
+ + + +   + + + +   + + + +   + + + +
+
+ + + +   + + + +   + + + +
+
+
+
+
+ This is a summary report for a MAPP run. + Motif count matrices are located under: ../modules/KAPAC/output, + unless external pre-computer resources were specified for this specific workflow execution. + In such case please refer to the pipeline's configuration file and inspect the paths provided + under the field: KPC_sitecount_matrices. +
+
+ Fitted motif activities as well as calculated activity z-scores and their statistical significance + are stored in a tab-separated formatted (TSV) table. + Rows of this table denote various sequence motifs in specific sliding windows whereas subsequent columns follow the + structure below: +
+
+ ID : unique ID of a sequence motif in a specific sliding window +
+ activities_{sampleID} : motif activities in distinct RNA-Seq samples +
+ deltas_{sampleID} : standard deviations of motif activities +
+ zscores_{sampleID} : z-scores of motif activities +
+ combined.Zscore : overall z-score for a given motif, combined over all samples +
+ regions_present_fraction : fraction of sites for which the motif was present in a specific window +
+ region : sliding window ID +
+ motif : short sequence motif +
+ standard_zscores_{sampleID} : standardised z-scores of motif activities +
+ pval_{sampleID} : standardised p-values of motif activities +
+ corr_pval_{sampleID} : p-values corrected for multiple hypothesis testing +
+ combined.standard.Zscore : combined standardised z-scores +
+ max.abs.standard.Zscore : maximum absolute standardised z-score +
+ significance-marker : statistical significance marker for this motif in this sliding window +
+
+
+
+ + + +  + + + +
+ + diff --git a/resources/exon-inclusion.html b/resources/exon-inclusion.html new file mode 100644 index 00000000..ca7f1d82 --- /dev/null +++ b/resources/exon-inclusion.html @@ -0,0 +1,113 @@ + + + + MAPP reports + + +
+
+ +

MAPP Report

+

Test run with reduced parameters on a sampled dataset

+
+ + + +   + + + +   + + + +   + + + +
+
+ + + +   + + + +   + + + +
+
+
+
+
+ Cassette exon inclusion is represented as a ratio of expression + for transcripts which include a specific exon + to all those transcripts which could have possibly included it. + Numerators and denominators of these ratios are stored separately in a tab-separated format (TSV) table. + Each row in the expression table represents a single cassette exon. The first column + specifies exon coordinates in a BED format. + Each of the next columns stores aggregated TPM values for + specific RNA-Seq samples. Columns with numerators of the inclusion fraction ratios are + denoted with an "_included" suffix whereas denominators are marked with "_total". + Please see the scheme below: +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Sample1_includedSample2_includedSample1_totalSample2_total...
Exon1
Exon2
Exon3
...
+
+
+
+ + + +  + + + +
+ + diff --git a/resources/gene-expression.html b/resources/gene-expression.html new file mode 100644 index 00000000..54279e55 --- /dev/null +++ b/resources/gene-expression.html @@ -0,0 +1,106 @@ + + + + MAPP reports + + +
+
+ +

MAPP Report

+

Test run with reduced parameters on a sampled dataset

+
+ + + +   + + + +   + + + +   + + + +
+
+ + + +   + + + +   + + + +
+
+
+
+
+ Gene expression has been quantified with the Salmon tool + (Patro R. et al.). +
+
+ Expression scores are stored as Transcripts-per-Milion (TPM) values in a tab-separated format (TSV) table. + Transcript expression was aggregated over all transcripts for a specific gene. + Please be aware that the TPM scores should not be used to directly compare gene expression across + distinct RNA-Seq samples. +
+
+ Each row in the expression table represents a single, unique gene. The first column + corresponds to a gene ID. Each of the next columns stores TPM values of + a specific RNA-Seq sample, as in the scheme below: +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Sample1Sample2...
Gene1
Gene2
Gene3
...
+
+
+
+ + + +  + + + +
+ + diff --git a/resources/mapp_logo.png b/resources/mapp_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d0868c2ca6a8ffb84d0d03d84c7d3aa3582ed4b4 GIT binary patch literal 31244 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 Oj5}>^@I=og_WuAzw{zwI literal 0 HcmV?d00001 diff --git a/resources/pas-expression.html b/resources/pas-expression.html new file mode 100644 index 00000000..ea8837ea --- /dev/null +++ b/resources/pas-expression.html @@ -0,0 +1,178 @@ + + + + MAPP reports + + +
+
+
+
+
+
+ Tandem Poly(A) sites' expression has been quantified with the PAQR tool + (Gruber A.J. et al.). +
+
+ Expression scores are stored as Transcripts-per-Milion (TPM) values in a tab-separated format (TSV) table. + Please be aware that the TPM scores should not be used to directly compare Poly(A) sites expression across + distinct RNA-Seq samples. +
+
+ Each row in the expression table represents a single, unique Poly(A) site. + The first 10 columns contain the following information: +
+ chrom : chromosome ID +
+ start : start coordinate (BED format) +
+ end : end coordinate (BED format) +
+ pas : Poly(A)-sites' ID (as in the PAS Atlas) +
+ score : minimal support level for a given Poly(A) site +
+ strand : sequence strand +
+ polyAsite_exon_idx : Poly(A) site's index on a specific terminal exon +
+ nr_polyAsites_on_exon : total number of Poly(A) sites on a specific terminal exon +
+ exon : unique terminal exon ID +
+ gene : transcript ID of this specific terminal exon +
+
+ Each of the next columns stores TPM values of + a specific RNA-Seq sample, as in the scheme below: +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
chromstartendpasscorestrandpolyAsite_exon_idxnr_polyAsites_on_exonexongeneSample1Sample2...
PAS1
PAS2
PAS3
...
+
+
+
+ + + +  + + + +
+ + diff --git a/resources/template.html b/resources/template.html index 6b8157d8..936e6a77 100644 --- a/resources/template.html +++ b/resources/template.html @@ -1,28 +1,43 @@ - MAPP report + MAPP - - -

MAPP report

+ +
+
+ +

MAPP Report

{{AnalysisTitle}}


- -{{MainTable}} - + + + +  + + + +  + + + +  + + + +
+
+ + + +  + + + +  + + + +
+

-
-

For more information feel free to inspect the results directory manually.

-

Apart from the heatmaps it contains:

-
    -
  • BED-formatted coordinates of 3'ss, 5'ss & pas
  • -
  • TSV table with exon inclusion fractions
  • -
  • TSV tables with pas expression and relative positions
  • -
  • TSV tables with genes and transcripts quantifications
  • -
  • TSV tables with motif activities around 3'ss, 5'ss & pas
  • -
  • TXT lists of selected top motifs acting around 3'ss, 5'ss & pas
  • -
- - - diff --git a/resources/transcript-expression.html b/resources/transcript-expression.html new file mode 100644 index 00000000..4be2fb17 --- /dev/null +++ b/resources/transcript-expression.html @@ -0,0 +1,105 @@ + + + + MAPP reports + + +
+
+ +

MAPP Report

+

Test run with reduced parameters on a sampled dataset

+
+ + + +   + + + +   + + + +   + + + +
+
+ + + +   + + + +   + + + +
+
+
+
+
+ Transcript expression has been quantified with the Salmon tool + (Patro R. et al.). +
+
+ Expression scores are stored as Transcripts-per-Milion (TPM) values in a tab-separated format (TSV) table. + Please be aware that the TPM scores should not be used to directly compare transcript expression across + distinct RNA-Seq samples. +
+
+ Each row in the expression table represents a single, unique transcript. The first column + corresponds to a transcript ID. Each of the next columns stores TPM values of + a specific RNA-Seq sample, as in the scheme below: +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Sample1Sample2...
Transcript1
Transcript2
Transcript3
...
+
+
+
+ + + +  + + + +
+ + diff --git a/scripts/generate-final-report.py b/scripts/generate-final-report.py index 020310aa..b1f8ad6a 100644 --- a/scripts/generate-final-report.py +++ b/scripts/generate-final-report.py @@ -74,41 +74,35 @@ def main(): os.path.join(options.summary_directory, "main-table.tsv"), sep="\t" ) summary = summary.round(3).fillna("NA") - print(summary) - - # set distinct columns width parameters for the table - # depending on if we run on kmers or pwms - if configfile["CSM_matrix_type"] == "kmers": - text_col_width = "10" - heatmap_col_width = "50" - heatmap_img_scaling = "30" - else: - assert configfile["CSM_matrix_type"] == "pwms" - text_col_width = "10" - heatmap_col_width = "40" - seqlogo_col_width = "10" - heatmap_img_scaling = "30" - seqlogo_img_scaling = "50" # render the HTML report template MANUALLY (for now) rendered_html = [] - for _ in range(11): + for _ in range(43): rendered_html.append(template_html[_]) - rendered_html[8] = "

" + configfile["MAPP_analysis_name"] + "

" - rendered_html.append("") + rendered_html[10] = "

" + configfile["MAPP_analysis_name"] + "

" + rendered_html.append("
") + rendered_html.append('
') rendered_html.append(" ") - if configfile["CSM_matrix_type"] == "pwms": - rendered_html.append(' ') - rendered_html.append(' ') - rendered_html.append(' ') - rendered_html.append(' ') - rendered_html.append(' ') - rendered_html.append(' ') - rendered_html.append(' ') + if configfile["CSM_matrix_type"] == "kmers": + rendered_html.append(' ') + rendered_html.append(' ') + rendered_html.append(' ') + rendered_html.append(' ') + rendered_html.append(' ') + rendered_html.append(' ') + else: + configfile["CSM_matrix_type"] == "pwms" + rendered_html.append(' ') + rendered_html.append(' ') + rendered_html.append(' ') + rendered_html.append(' ') + rendered_html.append(' ') + rendered_html.append(' ') + rendered_html.append(' ') rendered_html.append(" ") rendered_html.append(" ") for h in summary.columns.values: - rendered_html.append(" ") + rendered_html.append(' ') rendered_html.append(" ") for i, row in summary.iterrows(): rendered_html.append(" ") @@ -143,13 +137,15 @@ def main(): + ">' ) rendered_html.append(" ") rendered_html.append("
" + h + "' + h + '
") - for _ in range(12, len(template_html)): - rendered_html.append(template_html[_]) + rendered_html.append("") + rendered_html.append("
") + rendered_html.append("") + rendered_html.append("") with open(os.path.join(options.summary_directory, "report.html"), "w") as report: for line in rendered_html: @@ -161,6 +157,41 @@ def main(): os.path.join(options.summary_directory, "font-awesome-4.7.0"), ) + # copy the project logo + shutil.copy( + os.path.join(options.resources_directory, "mapp_logo.png"), + os.path.join(options.summary_directory, "mapp_logo.png"), + ) + + # copy the subsites + shutil.copy( + os.path.join(options.resources_directory, "gene-expression.html"), + os.path.join(options.summary_directory, "gene-expression.html"), + ) + shutil.copy( + os.path.join(options.resources_directory, "transcript-expression.html"), + os.path.join(options.summary_directory, "transcript-expression.html"), + ) + shutil.copy( + os.path.join(options.resources_directory, "exon-inclusion.html"), + os.path.join(options.summary_directory, "exon-inclusion.html"), + ) + shutil.copy( + os.path.join(options.resources_directory, "pas-expression.html"), + os.path.join(options.summary_directory, "pas-expression.html"), + ) + shutil.copy( + os.path.join(options.resources_directory, "activities-3ss.html"), + os.path.join(options.summary_directory, "activities-3ss.html"), + ) + shutil.copy( + os.path.join(options.resources_directory, "activities-5ss.html"), + os.path.join(options.summary_directory, "activities-5ss.html"), + ) + shutil.copy( + os.path.join(options.resources_directory, "activities-pas.html"), + os.path.join(options.summary_directory, "activities-pas.html"), + ) ##############################################################################
+ +

MAPP Report

+

Test run with reduced parameters on a sampled dataset

+
+
+ + +   + + + +   + + + +   + + + +
+
+ + + +   + + + +   + + + +