From 8cfd1d82da38d52dd3eb676676827ccb9bb55c08 Mon Sep 17 00:00:00 2001 From: Chiara Rasi Date: Tue, 8 Oct 2024 10:49:41 +0200 Subject: [PATCH 01/12] add exons to the list of checked intervals --- src/chanjo2/meta/handle_report_contents.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/chanjo2/meta/handle_report_contents.py b/src/chanjo2/meta/handle_report_contents.py index c42a77d2..adde1251 100644 --- a/src/chanjo2/meta/handle_report_contents.py +++ b/src/chanjo2/meta/handle_report_contents.py @@ -220,12 +220,14 @@ def get_gene_overview_coverage_stats(form_data: GeneReportForm, session: Session return gene_stats gene_stats["gene"] = gene - sql_intervals = set_sql_intervals( + transcripts_intervals = set_sql_intervals( db=session, interval_type=SQLTranscript, genes=[gene], transcript_tags=[], ) + exons_intervals = set_sql_intervals(db=session, interval_type=SQLExon, genes=[gene]) + sql_intervals = transcripts_intervals + exons_intervals gene_stats["samples_coverage_stats_by_interval"] = get_gene_overview_stats( sql_intervals=sql_intervals, samples=form_data.samples, From 13b48ce630cfa9d73c85bc4d817301643fc7460d Mon Sep 17 00:00:00 2001 From: Chiara Rasi Date: Tue, 8 Oct 2024 12:33:41 +0200 Subject: [PATCH 02/12] Wrap it up --- CHANGELOG.md | 1 + src/chanjo2/endpoints/overview.py | 11 +------ src/chanjo2/meta/handle_report_contents.py | 20 +++++++++++-- src/chanjo2/templates/gene-overview.html | 35 ++++++++++++++++++---- 4 files changed, 49 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 538eda67..4437e1a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - Computing coverage completeness stats using d4tools `perc_cov` stat function (much quicker reports) - Moved functions computing the coverage stats to a separate `meta/handle_coverage_stats.py` module - Refactored code collecting stats shown on gene overview report +- Gene report to contain both transcripts and exons stats ### Fixed - Updated dependencies including `certifi` to address dependabot alert - Update pytest to v.7.4.4 to address a `ReDoS` vulnerability diff --git a/src/chanjo2/endpoints/overview.py b/src/chanjo2/endpoints/overview.py index b14e06f1..8b95034a 100644 --- a/src/chanjo2/endpoints/overview.py +++ b/src/chanjo2/endpoints/overview.py @@ -108,16 +108,7 @@ async def gene_overview( ) return templates.TemplateResponse( - request=request, - name="gene-overview.html", - context={ - "interval_type": gene_overview_content["interval_type"], - "gene": gene_overview_content.get("gene"), - "interval_coverage_stats": gene_overview_content.get( - "samples_coverage_stats_by_interval" - ), - "levels": gene_overview_content["levels"], - }, + request=request, name="gene-overview.html", context=gene_overview_content ) diff --git a/src/chanjo2/meta/handle_report_contents.py b/src/chanjo2/meta/handle_report_contents.py index 896b983d..8e593483 100644 --- a/src/chanjo2/meta/handle_report_contents.py +++ b/src/chanjo2/meta/handle_report_contents.py @@ -208,7 +208,7 @@ def get_gene_overview_coverage_stats(form_data: GeneReportForm, session: Session threshold_levels=form_data.completeness_thresholds ), "interval_type": form_data.interval_type.value, - "samples_coverage_stats_by_interval": {}, + "interval_coverage_stats": {}, } set_samples_coverage_files(session=session, samples=form_data.samples) @@ -228,11 +228,27 @@ def get_gene_overview_coverage_stats(form_data: GeneReportForm, session: Session ) exons_intervals = set_sql_intervals(db=session, interval_type=SQLExon, genes=[gene]) sql_intervals = transcripts_intervals + exons_intervals - gene_stats["samples_coverage_stats_by_interval"] = get_gene_overview_stats( + + samples_coverage_by_interval = get_gene_overview_stats( sql_intervals=sql_intervals, samples=form_data.samples, completeness_thresholds=form_data.completeness_thresholds, ) + + for sql_interval in sql_intervals: + if type(sql_interval) == SQLTranscript: + gene_stats["interval_coverage_stats"][sql_interval.ensembl_id] = { + "interval_type": "transcript", + "mane_select": sql_interval.refseq_mane_select, + "mane_plus_clinical": sql_interval.refseq_mane_plus_clinical, + "stats": samples_coverage_by_interval[sql_interval.ensembl_id], + } + else: + gene_stats["interval_coverage_stats"][sql_interval.ensembl_id] = { + "interval_type": "exon", + "stats": samples_coverage_by_interval[sql_interval.ensembl_id], + } + return gene_stats diff --git a/src/chanjo2/templates/gene-overview.html b/src/chanjo2/templates/gene-overview.html index 8619fee9..1b1d1f40 100644 --- a/src/chanjo2/templates/gene-overview.html +++ b/src/chanjo2/templates/gene-overview.html @@ -1,19 +1,42 @@ {% extends "base-layout.html" %} +{% block css %} +{{ super() }} + +{% endblock %} + {% macro gene_stats_macro() %}

Gene: {{ gene.hgnc_symbol or gene.hgnc_id }}


- {% for interval_id, samples_stats in interval_coverage_stats.items() %} + {% for interval_id, interval_features in interval_coverage_stats.items() %}
-
- {{ interval_type }}: {{ interval_id }} +
+ {{ interval_features.interval_type|capitalize }} {{ interval_id }} + {% if interval_features.mane_select %} + MANE Select: {{interval_features.mane_select}} + {% endif %} + {% if interval_features.mane_plus_clinical %} + MANE Plus Clinical: {{interval_features.mane_plus_clinical}} + {% endif %}
- - +
Coverage overview over gene {{ gene.hgnc_symbol or gene.hgnc_id }} - {{interval_id}}
+ @@ -22,7 +45,7 @@

Gene: {{ gene.hgnc_symbol or gene.hgnc_id }}

{% endfor %} - {% for sample_stats in samples_stats %} + {% for sample_stats in interval_features.stats %} {% for level, _ in levels.items() %} From ad8568fb38098783b101aef2fc3971c86886b224 Mon Sep 17 00:00:00 2001 From: Chiara Rasi Date: Tue, 8 Oct 2024 12:37:37 +0200 Subject: [PATCH 03/12] Updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4437e1a0..7d1f4105 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - General report with coverage over the entire genome when no genes or genes panels are provided - A MANE coverage report, showing coverage and coverage completeness only on MANE transcripts for the provided list of genes - Link out from MANE overview to gene overview +- Display MANE badges on gene overview report ### Changed - Do not use stored cases/samples any more and run stats exclusively on d4 files paths provided by the user in real time - How parameters are passed to starlette.templating since it was raising a deprecation warning. From 9559379a11612d8f221e879daf58f7fc4a1a8225 Mon Sep 17 00:00:00 2001 From: Chiara Rasi Date: Tue, 8 Oct 2024 13:51:22 +0200 Subject: [PATCH 04/12] Small fixes --- src/chanjo2/endpoints/overview.py | 2 ++ src/chanjo2/meta/handle_report_contents.py | 1 + src/chanjo2/templates/gene-overview.html | 3 +++ 3 files changed, 6 insertions(+) diff --git a/src/chanjo2/endpoints/overview.py b/src/chanjo2/endpoints/overview.py index 8b95034a..515d46e0 100644 --- a/src/chanjo2/endpoints/overview.py +++ b/src/chanjo2/endpoints/overview.py @@ -107,6 +107,8 @@ async def gene_overview( get_gene_overview_coverage_stats(form_data=validated_form, session=db) ) + print(gene_overview_content) + return templates.TemplateResponse( request=request, name="gene-overview.html", context=gene_overview_content ) diff --git a/src/chanjo2/meta/handle_report_contents.py b/src/chanjo2/meta/handle_report_contents.py index 8e593483..784cbb18 100644 --- a/src/chanjo2/meta/handle_report_contents.py +++ b/src/chanjo2/meta/handle_report_contents.py @@ -217,6 +217,7 @@ def get_gene_overview_coverage_stats(form_data: GeneReportForm, session: Session build=form_data.build, hgnc_id=form_data.hgnc_gene_id, db=session ) if gene is None: + gene_stats["gene"] = {"hgnc_id": form_data.hgnc_gene_id} return gene_stats gene_stats["gene"] = gene diff --git a/src/chanjo2/templates/gene-overview.html b/src/chanjo2/templates/gene-overview.html index 1b1d1f40..d1a6f804 100644 --- a/src/chanjo2/templates/gene-overview.html +++ b/src/chanjo2/templates/gene-overview.html @@ -58,7 +58,10 @@

Gene: {{ gene.hgnc_symbol or gene.hgnc_id }}


+ {% else %} + No intervals found in database for gene {{gene.hgnc_symbol or gene.hgnc_id}}. {% endfor %} + {% endmacro %} {% block title %} From 4aae1fde7a71c0cf9265a92680fe942b378e63e7 Mon Sep 17 00:00:00 2001 From: Chiara Rasi Date: Tue, 8 Oct 2024 13:52:20 +0200 Subject: [PATCH 05/12] Remove debug message --- src/chanjo2/endpoints/overview.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/chanjo2/endpoints/overview.py b/src/chanjo2/endpoints/overview.py index 515d46e0..8b95034a 100644 --- a/src/chanjo2/endpoints/overview.py +++ b/src/chanjo2/endpoints/overview.py @@ -107,8 +107,6 @@ async def gene_overview( get_gene_overview_coverage_stats(form_data=validated_form, session=db) ) - print(gene_overview_content) - return templates.TemplateResponse( request=request, name="gene-overview.html", context=gene_overview_content ) From 767ff95dd24516ff665e3c522939e3f70ea0fd7e Mon Sep 17 00:00:00 2001 From: Chiara Rasi Date: Tue, 8 Oct 2024 14:01:36 +0200 Subject: [PATCH 06/12] Added Create PDF button on MANE overview and gene overview pages --- CHANGELOG.md | 1 + src/chanjo2/templates/gene-overview.html | 6 ++++++ src/chanjo2/templates/mane-overview.html | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d1f4105..e30fe152 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - A MANE coverage report, showing coverage and coverage completeness only on MANE transcripts for the provided list of genes - Link out from MANE overview to gene overview - Display MANE badges on gene overview report +- `Create PDF` button on MANE overview and gene overview pages ### Changed - Do not use stored cases/samples any more and run stats exclusively on d4 files paths provided by the user in real time - How parameters are passed to starlette.templating since it was raising a deprecation warning. diff --git a/src/chanjo2/templates/gene-overview.html b/src/chanjo2/templates/gene-overview.html index d1a6f804..fd932a5b 100644 --- a/src/chanjo2/templates/gene-overview.html +++ b/src/chanjo2/templates/gene-overview.html @@ -17,6 +17,12 @@ {% endblock %} +{% block pdf_export %} + +{% endblock %} + {% macro gene_stats_macro() %}

Gene: {{ gene.hgnc_symbol or gene.hgnc_id }}


diff --git a/src/chanjo2/templates/mane-overview.html b/src/chanjo2/templates/mane-overview.html index fd211cde..090b0280 100644 --- a/src/chanjo2/templates/mane-overview.html +++ b/src/chanjo2/templates/mane-overview.html @@ -14,6 +14,12 @@ {% endblock %} +{% block pdf_export %} + +{% endblock %} + {% macro report_filters() %}
From acc9dad1f51ec79b736a82d09e44ddfc832fcc97 Mon Sep 17 00:00:00 2001 From: Chiara Rasi Date: Tue, 8 Oct 2024 14:04:58 +0200 Subject: [PATCH 07/12] Simplify code --- src/chanjo2/meta/handle_report_contents.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/chanjo2/meta/handle_report_contents.py b/src/chanjo2/meta/handle_report_contents.py index 784cbb18..adff505c 100644 --- a/src/chanjo2/meta/handle_report_contents.py +++ b/src/chanjo2/meta/handle_report_contents.py @@ -244,11 +244,11 @@ def get_gene_overview_coverage_stats(form_data: GeneReportForm, session: Session "mane_plus_clinical": sql_interval.refseq_mane_plus_clinical, "stats": samples_coverage_by_interval[sql_interval.ensembl_id], } - else: - gene_stats["interval_coverage_stats"][sql_interval.ensembl_id] = { - "interval_type": "exon", - "stats": samples_coverage_by_interval[sql_interval.ensembl_id], - } + continue + gene_stats["interval_coverage_stats"][sql_interval.ensembl_id] = { + "interval_type": "exon", + "stats": samples_coverage_by_interval[sql_interval.ensembl_id], + } return gene_stats From 1c145d88e8c731c09491fc36fd222097f3c11a96 Mon Sep 17 00:00:00 2001 From: Chiara Rasi Date: Wed, 9 Oct 2024 12:36:09 +0200 Subject: [PATCH 08/12] Display exons in expandable sections --- src/chanjo2/meta/handle_report_contents.py | 32 ++++-- src/chanjo2/templates/gene-overview.html | 112 ++++++++++++++------- 2 files changed, 101 insertions(+), 43 deletions(-) diff --git a/src/chanjo2/meta/handle_report_contents.py b/src/chanjo2/meta/handle_report_contents.py index adff505c..9e90c1c3 100644 --- a/src/chanjo2/meta/handle_report_contents.py +++ b/src/chanjo2/meta/handle_report_contents.py @@ -208,7 +208,7 @@ def get_gene_overview_coverage_stats(form_data: GeneReportForm, session: Session threshold_levels=form_data.completeness_thresholds ), "interval_type": form_data.interval_type.value, - "interval_coverage_stats": {}, + "transcript_coverage_stats": {}, } set_samples_coverage_files(session=session, samples=form_data.samples) @@ -237,18 +237,38 @@ def get_gene_overview_coverage_stats(form_data: GeneReportForm, session: Session ) for sql_interval in sql_intervals: + interval_length: int = abs(sql_interval.stop - sql_interval.start) + coords: str = ( + f"{sql_interval.chromosome}:{sql_interval.start}-{sql_interval.stop}" + ) + if type(sql_interval) == SQLTranscript: - gene_stats["interval_coverage_stats"][sql_interval.ensembl_id] = { + gene_stats["transcript_coverage_stats"][sql_interval.ensembl_id] = { "interval_type": "transcript", "mane_select": sql_interval.refseq_mane_select, "mane_plus_clinical": sql_interval.refseq_mane_plus_clinical, + "mrna": sql_interval.refseq_mrna, "stats": samples_coverage_by_interval[sql_interval.ensembl_id], + "length": interval_length, + "coordinates": coords, + "exons": [], } continue - gene_stats["interval_coverage_stats"][sql_interval.ensembl_id] = { - "interval_type": "exon", - "stats": samples_coverage_by_interval[sql_interval.ensembl_id], - } + + gene_stats["transcript_coverage_stats"][sql_interval.ensembl_transcript_id][ + "exons" + ].append( + ( + sql_interval.ensembl_id, + { + "interval_type": "exon", + "transcript_rank": sql_interval.rank_in_transcript, + "stats": samples_coverage_by_interval[sql_interval.ensembl_id], + "length": interval_length, + "coordinates": coords, + }, + ) + ) return gene_stats diff --git a/src/chanjo2/templates/gene-overview.html b/src/chanjo2/templates/gene-overview.html index fd932a5b..8c3ae4ca 100644 --- a/src/chanjo2/templates/gene-overview.html +++ b/src/chanjo2/templates/gene-overview.html @@ -4,13 +4,13 @@ {{ super() }}
Coverage overview over gene {{ gene.hgnc_symbol or gene.hgnc_id }} - {{ interval_features.interval_type }} {{interval_id}}
Sample Mean coverage
{{ sample_stats[0] }} {{ sample_stats[1]|round(2) }}