scout-browser 4.83__py3-none-any.whl → 4.85__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scout/__version__.py +1 -1
- scout/adapter/mongo/case.py +5 -1
- scout/adapter/mongo/cytoband.py +13 -0
- scout/adapter/mongo/hgnc.py +1 -1
- scout/adapter/mongo/variant.py +9 -0
- scout/adapter/mongo/variant_loader.py +73 -71
- scout/build/genes/hgnc_gene.py +5 -134
- scout/commands/download/ensembl.py +1 -0
- scout/commands/download/everything.py +1 -0
- scout/commands/download/exac.py +1 -0
- scout/commands/download/hgnc.py +1 -0
- scout/commands/download/hpo.py +1 -0
- scout/commands/download/omim.py +1 -0
- scout/commands/export/database.py +1 -0
- scout/commands/load/panel.py +1 -0
- scout/commands/load/report.py +1 -0
- scout/commands/update/genes.py +9 -13
- scout/commands/update/omim.py +1 -0
- scout/commands/update/panelapp.py +1 -0
- scout/constants/file_types.py +86 -17
- scout/export/exon.py +1 -0
- scout/load/all.py +5 -1
- scout/load/hgnc_gene.py +40 -7
- scout/models/hgnc_map.py +50 -87
- scout/models/phenotype_term.py +3 -3
- scout/parse/hgnc.py +1 -0
- scout/parse/orpha.py +1 -0
- scout/parse/variant/conservation.py +1 -0
- scout/parse/variant/transcript.py +1 -1
- scout/parse/variant/variant.py +10 -4
- scout/server/blueprints/cases/controllers.py +15 -1
- scout/server/blueprints/cases/templates/cases/case.html +96 -89
- scout/server/blueprints/cases/templates/cases/collapsible_actionbar.html +1 -1
- scout/server/blueprints/cases/templates/cases/gene_panel.html +27 -41
- scout/server/blueprints/cases/templates/cases/utils.html +1 -1
- scout/server/blueprints/panels/forms.py +1 -0
- scout/server/blueprints/variant/controllers.py +9 -14
- scout/server/blueprints/variants/controllers.py +11 -27
- scout/server/extensions/bionano_extension.py +1 -0
- scout/server/extensions/chanjo_extension.py +10 -9
- scout/server/extensions/gens_extension.py +1 -0
- scout/server/extensions/ldap_extension.py +5 -3
- scout/server/extensions/loqus_extension.py +16 -14
- scout/server/extensions/matchmaker_extension.py +1 -0
- scout/server/extensions/mongo_extension.py +1 -0
- scout/server/extensions/rerunner_extension.py +1 -0
- scout/server/links.py +4 -4
- scout/server/static/bs_styles.css +5 -5
- scout/server/templates/utils.html +1 -1
- scout/utils/ensembl_rest_clients.py +1 -0
- scout/utils/scout_requests.py +1 -0
- scout/utils/sort.py +21 -0
- {scout_browser-4.83.dist-info → scout_browser-4.85.dist-info}/METADATA +3 -6
- {scout_browser-4.83.dist-info → scout_browser-4.85.dist-info}/RECORD +58 -57
- {scout_browser-4.83.dist-info → scout_browser-4.85.dist-info}/WHEEL +1 -1
- {scout_browser-4.83.dist-info → scout_browser-4.85.dist-info}/entry_points.txt +0 -1
- {scout_browser-4.83.dist-info → scout_browser-4.85.dist-info}/LICENSE +0 -0
- {scout_browser-4.83.dist-info → scout_browser-4.85.dist-info}/top_level.txt +0 -0
scout/load/all.py
CHANGED
@@ -3,6 +3,7 @@ import logging
|
|
3
3
|
|
4
4
|
from scout.constants import FILE_TYPE_MAP
|
5
5
|
from scout.exceptions.config import ConfigError
|
6
|
+
from scout.utils.sort import get_load_priority
|
6
7
|
|
7
8
|
LOG = logging.getLogger(__name__)
|
8
9
|
|
@@ -62,7 +63,10 @@ def load_region(adapter, case_id, hgnc_id=None, chrom=None, start=None, end=None
|
|
62
63
|
(FILE_TYPE_MAP[file_type]["variant_type"], FILE_TYPE_MAP[file_type]["category"])
|
63
64
|
)
|
64
65
|
|
65
|
-
for variant_type, category in
|
66
|
+
for variant_type, category in sorted(
|
67
|
+
case_file_types,
|
68
|
+
key=lambda tup: get_load_priority(variant_type=tup[0], category=tup[1]),
|
69
|
+
):
|
66
70
|
if variant_type == "research" and not case_obj["is_research"]:
|
67
71
|
continue
|
68
72
|
|
scout/load/hgnc_gene.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
import logging
|
3
|
+
from typing import Dict
|
3
4
|
|
4
5
|
from click import progressbar
|
5
6
|
|
@@ -16,6 +17,22 @@ from scout.utils.scout_requests import (
|
|
16
17
|
LOG = logging.getLogger(__name__)
|
17
18
|
|
18
19
|
|
20
|
+
def set_missing_gene_coordinates(gene_data: dict, cytoband_coords: Dict[str, dict]):
|
21
|
+
"""Attempt at collecting gene coordinates from cytoband for genes missing Ensembl ID."""
|
22
|
+
|
23
|
+
if gene_data.get("ensembl_gene_id") not in [
|
24
|
+
"",
|
25
|
+
None,
|
26
|
+
]: # Coordinates are present, since they're collected from the Ensembl file
|
27
|
+
return
|
28
|
+
gene_data["ensembl_gene_id"] = None
|
29
|
+
cytoband_coord: dict = cytoband_coords.get(gene_data["location"])
|
30
|
+
if cytoband_coord:
|
31
|
+
gene_data["chromosome"]: str = cytoband_coord["chromosome"]
|
32
|
+
gene_data["start"]: int = cytoband_coord["start"]
|
33
|
+
gene_data["end"]: int = cytoband_coord["stop"]
|
34
|
+
|
35
|
+
|
19
36
|
def load_hgnc_genes(
|
20
37
|
adapter,
|
21
38
|
genes=None,
|
@@ -36,7 +53,7 @@ def load_hgnc_genes(
|
|
36
53
|
Args:
|
37
54
|
adapter(scout.adapter.MongoAdapter)
|
38
55
|
genes(dict): If genes are already parsed
|
39
|
-
ensembl_lines(iterable(str)): Lines
|
56
|
+
ensembl_lines(iterable(str)): Lines formatted with ensembl gene information
|
40
57
|
hgnc_lines(iterable(str)): Lines with gene information from genenames.org
|
41
58
|
exac_lines(iterable(str)): Lines with information pLi-scores from ExAC
|
42
59
|
mim2gene(iterable(str)): Lines with map from omim id to gene symbol
|
@@ -78,20 +95,36 @@ def load_hgnc_genes(
|
|
78
95
|
genemap_lines=genemap_lines,
|
79
96
|
)
|
80
97
|
|
81
|
-
|
98
|
+
without_coords = 0
|
82
99
|
nr_genes = len(genes)
|
83
100
|
LOG.info(f"Building info for {nr_genes} genes")
|
101
|
+
|
102
|
+
cytoband_coords: Dict[str, dict] = adapter.cytoband_to_coordinates(build=build)
|
103
|
+
|
84
104
|
with progressbar(genes.values(), label="Building genes", length=nr_genes) as bar:
|
85
105
|
for gene_data in bar:
|
106
|
+
set_missing_gene_coordinates(gene_data=gene_data, cytoband_coords=cytoband_coords)
|
107
|
+
|
86
108
|
if not gene_data.get("chromosome"):
|
87
|
-
|
109
|
+
without_coords += 1
|
88
110
|
continue
|
111
|
+
gene_obj = build_hgnc_gene(
|
112
|
+
gene_data,
|
113
|
+
build=build,
|
114
|
+
)
|
115
|
+
|
116
|
+
if gene_obj:
|
117
|
+
gene_objects.append(gene_obj)
|
118
|
+
else:
|
119
|
+
without_coords += 1
|
89
120
|
|
90
|
-
|
91
|
-
|
121
|
+
LOG.info(
|
122
|
+
"Nr of genes without coordinates in build %s and therefore skipped: %s",
|
123
|
+
build,
|
124
|
+
without_coords,
|
125
|
+
)
|
126
|
+
LOG.info(f"Loading {len(gene_objects)} genes into the database")
|
92
127
|
|
93
|
-
LOG.info("Nr of genes without coordinates in build %s: %s", build, non_existing)
|
94
|
-
LOG.info(f"Loading {len(gene_objects)} genes to database")
|
95
128
|
adapter.load_hgnc_bulk(gene_objects)
|
96
129
|
|
97
130
|
LOG.info("Loading done. %s genes loaded", len(gene_objects))
|
scout/models/hgnc_map.py
CHANGED
@@ -2,6 +2,8 @@ from __future__ import unicode_literals
|
|
2
2
|
|
3
3
|
from typing import List, Optional
|
4
4
|
|
5
|
+
from pydantic import BaseModel, Field, field_validator, model_validator
|
6
|
+
|
5
7
|
|
6
8
|
class Exon(dict):
|
7
9
|
"""Exon dictionary
|
@@ -66,90 +68,51 @@ class HgncTranscript(dict):
|
|
66
68
|
self["mane_plus_clinical"] = mane_plus_clinical
|
67
69
|
|
68
70
|
|
69
|
-
class HgncGene(
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
incomplete_penetrance=False,
|
118
|
-
phenotypes=None,
|
119
|
-
build="37",
|
120
|
-
):
|
121
|
-
super(HgncGene, self).__init__()
|
122
|
-
self["hgnc_id"] = int(hgnc_id)
|
123
|
-
self["hgnc_symbol"] = hgnc_symbol
|
124
|
-
self["ensembl_id"] = ensembl_id
|
125
|
-
|
126
|
-
self["chromosome"] = chrom
|
127
|
-
self["start"] = int(start)
|
128
|
-
self["end"] = int(end)
|
129
|
-
self["length"] = self["end"] - self["start"]
|
130
|
-
|
131
|
-
self["description"] = description
|
132
|
-
self["aliases"] = aliases
|
133
|
-
self["primary_transcripts"] = primary_transcripts
|
134
|
-
self["inheritance_models"] = inheritance_models
|
135
|
-
self["phenotypes"] = phenotypes
|
136
|
-
|
137
|
-
self["entrez_id"] = entrez_id
|
138
|
-
if entrez_id:
|
139
|
-
self["entrez_id"] = int(entrez_id)
|
140
|
-
|
141
|
-
self["omim_id"] = omim_id
|
142
|
-
if omim_id:
|
143
|
-
self["omim_id"] = int(omim_id)
|
144
|
-
|
145
|
-
self["ucsc_id"] = ucsc_id
|
146
|
-
self["uniprot_ids"] = uniprot_ids
|
147
|
-
self["vega_id"] = vega_id
|
148
|
-
|
149
|
-
self["pli_score"] = pli_score
|
150
|
-
if pli_score:
|
151
|
-
self["pli_score"] = float(pli_score)
|
152
|
-
|
153
|
-
self["incomplete_penetrance"] = incomplete_penetrance
|
154
|
-
|
155
|
-
self["build"] = build
|
71
|
+
class HgncGene(BaseModel):
|
72
|
+
hgnc_id: int
|
73
|
+
hgnc_symbol: str
|
74
|
+
build: str
|
75
|
+
chromosome: str
|
76
|
+
start: int
|
77
|
+
end: int
|
78
|
+
length: int
|
79
|
+
description: Optional[str] = None
|
80
|
+
ensembl_id: Optional[str] = Field(None, alias="ensembl_gene_id")
|
81
|
+
aliases: Optional[List[str]] = Field(None, alias="previous_symbols")
|
82
|
+
entrez_id: Optional[int] = None
|
83
|
+
omim_id: Optional[int] = None
|
84
|
+
primary_transcripts: Optional[List[str]] = Field(None, alias="ref_seq")
|
85
|
+
ucsc_id: Optional[str] = None
|
86
|
+
uniprot_ids: Optional[List[str]] = None
|
87
|
+
vega_id: Optional[str] = None
|
88
|
+
inheritance_models: Optional[List[str]] = None
|
89
|
+
incomplete_penetrance: Optional[bool] = False
|
90
|
+
phenotypes: Optional[List[dict]] = None
|
91
|
+
pli_score: Optional[float] = None
|
92
|
+
constraint_lof_oe: Optional[float] = None
|
93
|
+
constraint_lof_oe_ci_lower: Optional[float] = None
|
94
|
+
constraint_lof_oe_ci_upper: Optional[float] = None
|
95
|
+
constraint_lof_z: Optional[float] = None
|
96
|
+
constraint_mis_oe: Optional[float] = None
|
97
|
+
constraint_mis_oe_ci_lower: Optional[float] = None
|
98
|
+
constraint_mis_oe_ci_upper: Optional[float] = None
|
99
|
+
constraint_mis_z: Optional[float] = None
|
100
|
+
|
101
|
+
@model_validator(mode="before")
|
102
|
+
def set_gene_length(cls, values) -> "HgncGene":
|
103
|
+
"""Set gene length."""
|
104
|
+
if None in [values.get("end"), values.get("start")]:
|
105
|
+
values.update({"length": None})
|
106
|
+
else:
|
107
|
+
values.update({"length": values.get("end") - values.get("start")})
|
108
|
+
return values
|
109
|
+
|
110
|
+
@field_validator("phenotypes", mode="before")
|
111
|
+
@classmethod
|
112
|
+
def set_phenotypes_inheritance(cls, phenotypes) -> Optional[List[dict]]:
|
113
|
+
"""Convert field 'inheritance' of each phenotype in phenotypes from set to list."""
|
114
|
+
for phenotype in phenotypes:
|
115
|
+
phenotype["inheritance_models"] = list(phenotype.get("inheritance", {}))
|
116
|
+
phenotype.pop("inheritance", None)
|
117
|
+
|
118
|
+
return phenotypes
|
scout/models/phenotype_term.py
CHANGED
@@ -14,9 +14,9 @@ class HpoTerm(BaseModel):
|
|
14
14
|
"""
|
15
15
|
|
16
16
|
hpo_id: str # id field in the hpo.obo file
|
17
|
-
hpo_number: Optional[
|
18
|
-
|
19
|
-
|
17
|
+
hpo_number: Optional[int] = (
|
18
|
+
None # id field in the hpo.obo file, stripped of the 'HP:' part and the zeroes
|
19
|
+
)
|
20
20
|
description: str # name field in the hpo.obo file
|
21
21
|
ancestors: List = []
|
22
22
|
all_ancestors: List = []
|
scout/parse/hgnc.py
CHANGED
@@ -24,6 +24,7 @@ def parse_hgnc_line(line, header):
|
|
24
24
|
hgnc_gene["hgnc_symbol"] = hgnc_symbol
|
25
25
|
hgnc_gene["hgnc_id"] = int(raw_info["hgnc_id"].split(":")[-1])
|
26
26
|
hgnc_gene["description"] = raw_info["name"]
|
27
|
+
hgnc_gene["location"] = raw_info["location"] # cytoband
|
27
28
|
|
28
29
|
# We want to have the current symbol as an alias
|
29
30
|
aliases = set([hgnc_symbol, hgnc_symbol.upper()])
|
scout/parse/orpha.py
CHANGED
scout/parse/variant/variant.py
CHANGED
@@ -231,10 +231,7 @@ def parse_variant(
|
|
231
231
|
parsed_variant["revel_score"] = parsed_transcripts[0].get(
|
232
232
|
"revel_rankscore"
|
233
233
|
) # This is actually the value of REVEL_rankscore
|
234
|
-
|
235
|
-
parsed_variant["revel"] = parsed_transcripts[0].get(
|
236
|
-
"revel_raw_score"
|
237
|
-
) # This is actually the value of REVEL_score
|
234
|
+
parsed_variant["revel"] = get_highest_revel_score(parsed_transcripts)
|
238
235
|
|
239
236
|
###################### Add conservation ######################
|
240
237
|
parsed_variant["conservation"] = parse_conservations(variant, parsed_transcripts)
|
@@ -261,6 +258,15 @@ def parse_variant(
|
|
261
258
|
return parsed_variant
|
262
259
|
|
263
260
|
|
261
|
+
def get_highest_revel_score(parsed_transcripts: List[dict]) -> Optional[float]:
|
262
|
+
"""Retrieve the highest REVEL_score value from parsed variant transcripts."""
|
263
|
+
tx_revel_scores: List(float) = [
|
264
|
+
tx.get("revel_raw_score") for tx in parsed_transcripts if tx.get("revel_raw_score") != None
|
265
|
+
]
|
266
|
+
if tx_revel_scores:
|
267
|
+
return max(tx_revel_scores)
|
268
|
+
|
269
|
+
|
264
270
|
def get_genmod_key(case):
|
265
271
|
"""Gen genmod key
|
266
272
|
|
@@ -64,6 +64,7 @@ JSON_HEADERS = {
|
|
64
64
|
COVERAGE_REPORT_TIMEOUT = 20
|
65
65
|
|
66
66
|
PANEL_PROJECTION = {"version": 1, "display_name": 1, "genes": 1}
|
67
|
+
PANEL_HIDDEN_PROJECTION = {"version": 1, "display_name": 1, "hidden": 1}
|
67
68
|
|
68
69
|
|
69
70
|
def phenomizer_diseases(hpo_ids, case_obj, p_value_treshold=1):
|
@@ -339,6 +340,8 @@ def case(
|
|
339
340
|
|
340
341
|
case_obj["default_genes"] = _get_default_panel_genes(store, case_obj)
|
341
342
|
|
343
|
+
_set_panel_removed(store, case_obj)
|
344
|
+
|
342
345
|
for hpo_term in itertools.chain(
|
343
346
|
case_obj.get("phenotype_groups") or [], case_obj.get("phenotype_terms") or []
|
344
347
|
):
|
@@ -479,6 +482,18 @@ def _limit_genes_on_default_panels(default_genes: list, limit_genes: list) -> li
|
|
479
482
|
return list(default_genes_set.intersection(limit_genes_set))
|
480
483
|
|
481
484
|
|
485
|
+
def _set_panel_removed(store: MongoAdapter, case_obj: dict) -> list:
|
486
|
+
"""Flag panel on list removed if the latest panel version is marked hidden."""
|
487
|
+
|
488
|
+
for panel_info in case_obj.get("panels", []):
|
489
|
+
latest_panel = store.gene_panel(
|
490
|
+
panel_info["panel_name"], projection=PANEL_HIDDEN_PROJECTION
|
491
|
+
)
|
492
|
+
panel_info["removed"] = (
|
493
|
+
latest_panel.get("hidden", False) if latest_panel is not None else False
|
494
|
+
)
|
495
|
+
|
496
|
+
|
482
497
|
def _get_default_panel_genes(store: MongoAdapter, case_obj: dict) -> list:
|
483
498
|
"""Get unique genes on case default panels.
|
484
499
|
|
@@ -510,7 +525,6 @@ def _get_default_panel_genes(store: MongoAdapter, case_obj: dict) -> list:
|
|
510
525
|
projection=PANEL_PROJECTION,
|
511
526
|
)
|
512
527
|
latest_panel = store.gene_panel(panel_name, projection=PANEL_PROJECTION)
|
513
|
-
panel_info["removed"] = False if latest_panel is None else latest_panel.get("hidden", False)
|
514
528
|
if not panel_obj:
|
515
529
|
panel_obj = latest_panel
|
516
530
|
if not panel_obj:
|
@@ -65,7 +65,7 @@
|
|
65
65
|
<span class="badge rounded-pill bg-info text-body" data-bs-toggle="tooltip" data-bs-placement="left" title="Matching causatives and managed variants displayed on case page are NOT filtered by gene panel. Use caution to avoid incidental findings.">off</span>
|
66
66
|
{% endif %}
|
67
67
|
</div>
|
68
|
-
</div> <!--end of
|
68
|
+
</div> <!--end of row -->
|
69
69
|
<div class="row">
|
70
70
|
<form id="case_status_form" method="POST" action="{{ url_for('cases.status', institute_id=institute._id, case_name=case.display_name) }}">
|
71
71
|
<div class="btn-toolbar ms-2" role="toolbar">
|
@@ -105,7 +105,7 @@
|
|
105
105
|
{{ 'Inactive' if case.status == 'ignored' else 'Ignored' }}
|
106
106
|
</button>
|
107
107
|
</div>
|
108
|
-
<div class="btn-group ms-2 role="group">
|
108
|
+
<div class="btn-group ms-2" role="group">
|
109
109
|
<select name="tags" id="status_tags_case" multiple class="selectpicker" data-style="btn btn-secondary">
|
110
110
|
{% for tag, data in case_tag_options.items() %}
|
111
111
|
<option {% if 'tags' in case and tag~"" in case.tags %} selected {% endif %} value="{{ tag }}" title="{{ data.label }}">
|
@@ -119,103 +119,65 @@
|
|
119
119
|
</div>
|
120
120
|
</div>
|
121
121
|
|
122
|
+
{{ matching_variants() }}
|
123
|
+
|
122
124
|
<div class="card panel-default" >
|
123
|
-
<div class="row
|
124
|
-
<div class="col
|
125
|
-
|
126
|
-
|
127
|
-
<strong>{% if hide_matching == false %}
|
128
|
-
<a href="{{ url_for('cases.case', institute_id=institute._id, case_name=case.display_name, hide_matching='True') }}" class="text-body"><span class="me-1 fa fa-caret-right"></span>Search for matching causatives and managed variants</a>
|
129
|
-
{% else %}
|
130
|
-
<a href="{{ url_for('cases.case', institute_id=institute._id, case_name=case.display_name, hide_matching='False') }}" class="text-body"><span class="me-1 fa fa-caret-down"></span>Search for matching causatives and managed variants</a>
|
131
|
-
{% endif %}
|
132
|
-
</strong>
|
133
|
-
</div>
|
134
|
-
</div>
|
125
|
+
<div class="row">
|
126
|
+
<div class="col">{{ causatives_list(causatives, partial_causatives, evaluated_variants, institute, case, manual_rank_options, cancer_tier_options) }}</div>
|
127
|
+
<div class="col">{{ suspects_list(suspects, institute, case, manual_rank_options, cancer_tier_options) }}</div>
|
128
|
+
<!-- end of data sharing panels -->
|
135
129
|
</div>
|
136
|
-
{% if hide_matching == false %}
|
137
|
-
{% if other_causatives|length > 0 %}
|
138
|
-
<div class="row mt-0 ms-3">
|
139
|
-
<div class="col-xs-12 col-md-12 ms-3">{{ matching_causatives(other_causatives, institute, case) }}</div>
|
140
|
-
</div>
|
141
|
-
{% endif %}
|
142
|
-
{% if default_other_causatives|length > 0%}
|
143
|
-
<div class="row mt-0 ms-3">
|
144
|
-
<div class="col-xs-12 col-md-12 ms-3">{{ matching_causatives(default_other_causatives, institute, case, default=True) }}</div>
|
145
|
-
</div>
|
146
|
-
{% endif %}
|
147
|
-
{% if managed_variants|length > 0%}
|
148
|
-
<div class="row mt-0 ms-3">
|
149
|
-
<div class="col-sm-12 col-md-12 ms-3">{{ matching_managed_variants(managed_variants, institute, case) }}</div>
|
150
|
-
</div>
|
151
|
-
{% endif %}
|
152
|
-
{% if default_managed_variants|length > 0%}
|
153
|
-
<div class="row mt-0 ms-3">
|
154
|
-
<div class="col-sm-12 col-md-12 ms-3">{{ matching_managed_variants(default_managed_variants, institute, case, default=True) }}</div>
|
155
|
-
</div>
|
156
|
-
{% endif %}
|
157
|
-
{% if other_causatives|length == 0 and default_other_causatives|length == 0 and managed_variants|length == 0 and default_managed_variants|length == 0%}
|
158
|
-
<div class="row mt-0 ms-3">
|
159
|
-
<div class="col-sm-12 col-md-12 ms-3">No matching causatives or managed variants found</div>
|
160
|
-
</div>
|
161
|
-
{% endif %}
|
162
|
-
{% endif %}
|
163
|
-
<div class="row">
|
164
|
-
<div class="col">{{ causatives_list(causatives, partial_causatives, evaluated_variants, institute, case, manual_rank_options, cancer_tier_options) }}</div>
|
165
|
-
<div class="col">{{ suspects_list(suspects, institute, case, manual_rank_options, cancer_tier_options) }}</div>
|
166
|
-
<!-- end of data sharing panels -->
|
167
|
-
</div>
|
168
130
|
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
131
|
+
<div class="row">
|
132
|
+
{% if case.track == 'cancer' %}
|
133
|
+
<div class="col-sm-12 col-md-12 mt-3">{{ cancer_individuals_table(case, institute, tissue_types, gens_info) }}</div>
|
134
|
+
{% else %}
|
135
|
+
<div class="mt-3 col-sm-8 col-md-{{"8" if case.madeline_info and case.individuals|length > 1 else "12"}}">{{ individuals_table(case, institute, tissue_types, display_rerunner, gens_info) }}</div>
|
136
|
+
{% if case.madeline_info and case.individuals|length > 1 %}
|
137
|
+
<div class="col-sm-4">
|
138
|
+
{{ pedigree_panel(case) }}
|
139
|
+
</div>
|
140
|
+
{% endif %}
|
178
141
|
{% endif %}
|
179
|
-
|
180
|
-
</div>
|
181
|
-
|
182
|
-
<div class="row mt-3">
|
183
|
-
<div class="col-6">{{ synopsis_panel() }}</div>
|
184
|
-
<div class="col-6">{{ comments_panel(institute, case, current_user, comments) }}</div>
|
185
|
-
</div>
|
142
|
+
</div>
|
186
143
|
|
187
|
-
|
188
|
-
|
189
|
-
{{
|
144
|
+
<div class="row mt-3">
|
145
|
+
<div class="col-6">{{ synopsis_panel() }}</div>
|
146
|
+
<div class="col-6">{{ comments_panel(institute, case, current_user, comments) }}</div>
|
190
147
|
</div>
|
191
|
-
</div>
|
192
148
|
|
193
|
-
|
194
|
-
|
195
|
-
|
149
|
+
<div class="row">
|
150
|
+
<div class="col-sm-12">
|
151
|
+
{{ insert_multi_image_panel() }}
|
152
|
+
</div>
|
196
153
|
</div>
|
197
|
-
</div>
|
198
154
|
|
199
|
-
<!-- CASE DIAGNOSES AND PHENOTYPES -->
|
200
|
-
<div class="panel-default">
|
201
|
-
<div class="panel-heading"><span class="fa fa-user-md"></span> Phenotypes & diagnoses</div>
|
202
155
|
<div class="row">
|
203
|
-
<div class="col-sm-
|
204
|
-
|
205
|
-
|
206
|
-
|
156
|
+
<div class="col-sm-12">
|
157
|
+
{{ custom_image_panels() }}
|
158
|
+
</div>
|
159
|
+
</div>
|
160
|
+
|
161
|
+
<!-- CASE DIAGNOSES AND PHENOTYPES -->
|
162
|
+
<div class="panel-default">
|
163
|
+
<div class="panel-heading"><span class="fa fa-user-md"></span> Phenotypes & diagnoses</div>
|
164
|
+
<div class="row">
|
165
|
+
<div class="col-sm-6 ">
|
166
|
+
<div class="card h-100">
|
167
|
+
<div class="card-body">
|
168
|
+
{{ hpo_panel(case, institute, config) }}
|
169
|
+
</div>
|
207
170
|
</div>
|
208
171
|
</div>
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
172
|
+
<div class="col-sm-6">
|
173
|
+
<div class="card h-100">
|
174
|
+
<div class="card-body">
|
175
|
+
{{ hpo_genelist_panel(case, institute, config) }}
|
176
|
+
</div>
|
214
177
|
</div>
|
215
178
|
</div>
|
216
|
-
</div>
|
217
|
-
</div> <!--end of
|
218
|
-
</div>
|
179
|
+
</div> <!--end of row>-->
|
180
|
+
</div> <!--end of card panel-default -->
|
219
181
|
|
220
182
|
<!-- diagnoses-related code-->
|
221
183
|
{% if not case.track == 'cancer' %}
|
@@ -259,8 +221,8 @@
|
|
259
221
|
{{ reanalysis_modal(institute, case) }}
|
260
222
|
{{ beacon_modal(institute, case) }}
|
261
223
|
{{ matchmaker_modal(institute, case, suspects, mme_nodes) }}
|
262
|
-
</div><!-- end of
|
263
|
-
</div><!-- end of
|
224
|
+
</div><!-- end of containter -->
|
225
|
+
</div><!-- end of col -->
|
264
226
|
{% endmacro %}
|
265
227
|
|
266
228
|
{% macro variants_buttons() %}
|
@@ -390,7 +352,7 @@
|
|
390
352
|
<a href="{{ url_for('cases.case', institute_id=grouped_case.owner, case_name=grouped_case.display_name) }}">{{ grouped_case.display_name }}</a>
|
391
353
|
|
392
354
|
<a href="{{ url_for('cases.remove_case_group', institute_id=institute._id, case_name=grouped_case.display_name, case_group=group_id) }}" class="btn btn-link btn-sm">
|
393
|
-
<span class="fa fa-
|
355
|
+
<span class="fa fa-times text-dark"></span></a>
|
394
356
|
|
395
357
|
</div>
|
396
358
|
{% endfor %}
|
@@ -398,7 +360,7 @@
|
|
398
360
|
</div>
|
399
361
|
{% endfor %}
|
400
362
|
{% endif %}
|
401
|
-
</div> <!-- end of
|
363
|
+
</div> <!-- end of list-group -->
|
402
364
|
</div>
|
403
365
|
</div>
|
404
366
|
{% endmacro %}
|
@@ -574,6 +536,51 @@
|
|
574
536
|
</div>
|
575
537
|
{% endmacro %}
|
576
538
|
|
539
|
+
{% macro matching_variants() %}
|
540
|
+
<div class="card mt-3">
|
541
|
+
<div class="row mt-0 ms-3">
|
542
|
+
<div class="col-sm-12 col-md-12">
|
543
|
+
<div data-bs-toggle='tooltip' class="panel-heading" title="Check if there are any variants in this case
|
544
|
+
marked as causative in another case for this institute, or are on the managed variants list.">
|
545
|
+
<strong>
|
546
|
+
{% if hide_matching == false %}
|
547
|
+
<a href="{{ url_for('cases.case', institute_id=institute._id, case_name=case.display_name, hide_matching='True') }}" class="text-body"><span class="me-1 fa fa-caret-down"></span>Search for matching causatives and managed variants</a>
|
548
|
+
{% else %}
|
549
|
+
<a href="{{ url_for('cases.case', institute_id=institute._id, case_name=case.display_name, hide_matching='False') }}" class="text-body"><span class="me-1 fa fa-caret-right"></span>Search for matching causatives and managed variants</a>
|
550
|
+
{% endif %}
|
551
|
+
</strong>
|
552
|
+
</div>
|
553
|
+
</div>
|
554
|
+
{% if hide_matching == false %}
|
555
|
+
{% if other_causatives|length > 0 %}
|
556
|
+
<div class="row mt-0 ms-3">
|
557
|
+
<div class="col-xs-12 col-md-12">{{ matching_causatives(other_causatives, institute, case) }}</div>
|
558
|
+
</div>
|
559
|
+
{% endif %}
|
560
|
+
{% if default_other_causatives|length > 0%}
|
561
|
+
<div class="row mt-0 ms-3">
|
562
|
+
<div class="col-xs-12 col-md-12">{{ matching_causatives(default_other_causatives, institute, case, default=True) }}</div>
|
563
|
+
</div>
|
564
|
+
{% endif %}
|
565
|
+
{% if managed_variants|length > 0%}
|
566
|
+
<div class="row mt-0 ms-3">
|
567
|
+
<div class="col-sm-12 col-md-12">{{ matching_managed_variants(managed_variants, institute, case) }}</div>
|
568
|
+
</div>
|
569
|
+
{% endif %}
|
570
|
+
{% if default_managed_variants|length > 0%}
|
571
|
+
<div class="row mt-0 ms-3">
|
572
|
+
<div class="col-sm-12 col-md-12">{{ matching_managed_variants(default_managed_variants, institute, case, default=True) }}</div>
|
573
|
+
</div>
|
574
|
+
{% endif %}
|
575
|
+
{% if other_causatives|length == 0 and default_other_causatives|length == 0 and managed_variants|length == 0 and default_managed_variants|length == 0%}
|
576
|
+
<div class="row mt-0 ms-3">
|
577
|
+
<div class="col-sm-12 col-md-12">No matching causatives or managed variants found</div>
|
578
|
+
</div>
|
579
|
+
{% endif %}
|
580
|
+
{% endif %}
|
581
|
+
</div>
|
582
|
+
</div>
|
583
|
+
{% endmacro %}
|
577
584
|
|
578
585
|
{% block scripts %}
|
579
586
|
{{ super() }}
|
@@ -247,7 +247,7 @@
|
|
247
247
|
{% else %}
|
248
248
|
<button type="submit" name="action" value="DELETE" class="btn btn-warning btn-xs form-control">
|
249
249
|
{% endif %}
|
250
|
-
<span class="fa fa-
|
250
|
+
<span class="fa fa-times"></span>
|
251
251
|
{{ user.name }}
|
252
252
|
</button>
|
253
253
|
</form>
|