scout-browser 4.89.1__py3-none-any.whl → 4.90__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/hgnc.py +1 -1
- scout/adapter/mongo/panel.py +21 -58
- scout/adapter/mongo/query.py +9 -0
- scout/build/panel.py +36 -72
- scout/constants/__init__.py +28 -45
- scout/constants/acmg.py +76 -16
- scout/constants/gene_tags.py +4 -2
- scout/constants/panels.py +11 -0
- scout/constants/query_terms.py +1 -0
- scout/constants/variant_tags.py +58 -3
- scout/export/panel.py +30 -33
- scout/parse/panel.py +55 -51
- scout/server/blueprints/alignviewers/views.py +3 -0
- scout/server/blueprints/cases/controllers.py +4 -0
- scout/server/blueprints/cases/templates/cases/case_sma.html +14 -6
- scout/server/blueprints/cases/templates/cases/collapsible_actionbar.html +10 -2
- scout/server/blueprints/cases/templates/cases/matchmaker.html +12 -7
- scout/server/blueprints/institutes/controllers.py +11 -4
- scout/server/blueprints/institutes/templates/overview/causatives.html +1 -1
- scout/server/blueprints/institutes/templates/overview/gene_variants.html +3 -5
- scout/server/blueprints/institutes/templates/overview/utils.html +2 -2
- scout/server/blueprints/institutes/templates/overview/verified.html +1 -1
- scout/server/blueprints/institutes/views.py +22 -6
- scout/server/blueprints/omics_variants/templates/omics_variants/outliers.html +1 -1
- scout/server/blueprints/omics_variants/views.py +2 -0
- scout/server/blueprints/panels/controllers.py +8 -16
- scout/server/blueprints/panels/templates/panels/gene-edit.html +2 -2
- scout/server/blueprints/panels/templates/panels/panel.html +21 -13
- scout/server/blueprints/panels/templates/panels/panel_pdf_simple.html +25 -18
- scout/server/blueprints/panels/views.py +9 -6
- scout/server/blueprints/variant/templates/variant/acmg.html +28 -24
- scout/server/blueprints/variant/templates/variant/gene_disease_relations.html +1 -3
- scout/server/blueprints/variant/templates/variant/utils.html +1 -1
- scout/server/blueprints/variant/utils.py +1 -0
- scout/server/blueprints/variant/views.py +5 -2
- scout/server/blueprints/variants/templates/variants/cancer-sv-variants.html +7 -11
- scout/server/blueprints/variants/templates/variants/components.html +55 -38
- scout/server/blueprints/variants/templates/variants/mei-variants.html +2 -6
- scout/server/blueprints/variants/templates/variants/str-variants.html +8 -2
- scout/server/blueprints/variants/templates/variants/sv-variants.html +4 -8
- scout/server/blueprints/variants/templates/variants/variants.html +23 -18
- scout/server/blueprints/variants/views.py +6 -0
- scout/utils/acmg.py +155 -28
- scout/utils/scout_requests.py +8 -13
- {scout_browser-4.89.1.dist-info → scout_browser-4.90.dist-info}/METADATA +1 -1
- {scout_browser-4.89.1.dist-info → scout_browser-4.90.dist-info}/RECORD +51 -50
- {scout_browser-4.89.1.dist-info → scout_browser-4.90.dist-info}/LICENSE +0 -0
- {scout_browser-4.89.1.dist-info → scout_browser-4.90.dist-info}/WHEEL +0 -0
- {scout_browser-4.89.1.dist-info → scout_browser-4.90.dist-info}/entry_points.txt +0 -0
- {scout_browser-4.89.1.dist-info → scout_browser-4.90.dist-info}/top_level.txt +0 -0
@@ -1,4 +1,6 @@
|
|
1
|
-
{%
|
1
|
+
{% from "variant/gene_disease_relations.html" import inheritance_badge %}
|
2
|
+
|
3
|
+
{% macro variant_gene_symbols_cell(variant, inherit_palette) %}
|
2
4
|
<div class="d-flex justify-content-between align-items-center">
|
3
5
|
<div>
|
4
6
|
{% if variant.hgnc_symbols|length >= 5 %}
|
@@ -16,7 +18,30 @@
|
|
16
18
|
{% if variant.hgnc_symbols %}
|
17
19
|
<span class="badge bg-secondary mr-3 text-white">{{ variant.hgnc_symbols|length }}</span>
|
18
20
|
{% endif %}
|
19
|
-
|
21
|
+
{% for gene in variant.genes %}
|
22
|
+
<a data-bs-toggle="tooltip" data-bs-html="true" title="
|
23
|
+
<div>
|
24
|
+
<div>
|
25
|
+
<strong>{{ gene.hgnc_symbol }}</strong>: {{ gene.description }}
|
26
|
+
</div>
|
27
|
+
{% if gene.inheritance %}
|
28
|
+
<div>
|
29
|
+
<strong>Models</strong>: {{ gene.inheritance|join(',') }}
|
30
|
+
</div>
|
31
|
+
{% endif %}
|
32
|
+
{% if gene.phenotypes %}
|
33
|
+
<div><strong>OMIM disease</strong>
|
34
|
+
{% for disease in gene.phenotypes %}
|
35
|
+
<div>
|
36
|
+
{{ disease.description }}
|
37
|
+
</div>
|
38
|
+
{% endfor %}
|
39
|
+
</div>
|
40
|
+
{% endif %}
|
41
|
+
</div>"
|
42
|
+
href="{{ url_for('genes.gene', hgnc_id=gene.hgnc_id) }}">{{ gene.hgnc_symbol or gene.hgnc_id }}
|
43
|
+
{% for model in gene.inheritance %} {{ inheritance_badge(model,inherit_palette) }}{% endfor %}</a>
|
44
|
+
{% endfor %}
|
20
45
|
</div>
|
21
46
|
{% endif %}
|
22
47
|
</div>
|
@@ -38,8 +63,8 @@
|
|
38
63
|
<th id="frame_status" style="width:8%" title="Frame status of the fusion">Frame Status</th>
|
39
64
|
<th id="transcripts" style="width:8%" title="Transcript ID">Transcript ID</th>
|
40
65
|
<th id="exons" style="width:4%" title="Exon Number">Exon Number</th>
|
41
|
-
<th id="
|
42
|
-
<th id="
|
66
|
+
<th id="breakpoints" style="width:4%" title="Breakpoints">Breakpoints</th>
|
67
|
+
<th id="orientation" style="width:4%" title="Orientation">Orientation</th>
|
43
68
|
</tr>
|
44
69
|
</thead>
|
45
70
|
{% endmacro %}
|
@@ -100,10 +125,20 @@
|
|
100
125
|
|
101
126
|
{% macro variant_funct_anno_cell(variant) %}
|
102
127
|
<div class="d-flex justify-content-between align-items-center">
|
103
|
-
<div>
|
104
|
-
{% if variant.
|
105
|
-
|
128
|
+
<div data-bs-toggle="tooltip" data-bs-html="true" title="<div class='text-start'>
|
129
|
+
{% if variant.functional_annotations|length >= 5 %}
|
130
|
+
Regional annotations<br>
|
131
|
+
{% if variant.missing_data %}[first 30 genes]{% endif %}
|
132
|
+
{% for annotation in variant.region_annotations|sort %}
|
133
|
+
{{ annotation }}<br>
|
134
|
+
{% endfor %}
|
106
135
|
{% else %}
|
136
|
+
{{ variant.region_annotations|sort|join(', ') }}
|
137
|
+
{% endif %}
|
138
|
+
</div>">
|
139
|
+
{% if variant.category == "fusion" %}
|
140
|
+
{{ variant.frame_status|lower if variant.frame_status else "-" }}
|
141
|
+
{% else %}
|
107
142
|
{% if variant.functional_annotations|length >= 5 %}
|
108
143
|
<a class="mr-3" data-bs-toggle="collapse" href="#_functanno_{{variant._id}}" role="button" aria-expanded="false" aria-controls="_{{variant._id}}">{% if variant.missing_data %}[first 30 genes]{% else %}[...]{% endif %}</a>
|
109
144
|
<div class="collapse" id="_functanno_{{variant._id}}">
|
@@ -123,26 +158,8 @@
|
|
123
158
|
</div>
|
124
159
|
{% endmacro %}
|
125
160
|
|
126
|
-
{% macro variant_region_anno_cell(variant) %}
|
127
|
-
<div class="d-flex justify-content-between align-items-center">
|
128
|
-
<div>
|
129
|
-
{% if variant.functional_annotations|length >= 5 %}
|
130
|
-
<a class="mr-3" data-bs-toggle="collapse" href="#_regionanno_{{variant._id}}" role="button" aria-expanded="false" aria-controls="_{{variant._id}}">{% if variant.missing_data %}[first 30 genes]{% else %}[...]{% endif %}</a>
|
131
|
-
<div class="collapse" id="_regionanno_{{variant._id}}">
|
132
|
-
{% for annotation in variant.region_annotations|sort %}
|
133
|
-
{{ annotation }}<br>
|
134
|
-
{% endfor %}
|
135
|
-
</div>
|
136
|
-
{% else %}
|
137
|
-
<div>
|
138
|
-
{{ variant.region_annotations|sort|join(", ") }}
|
139
|
-
</div>
|
140
|
-
{% endif %}
|
141
|
-
</div>
|
142
|
-
</div>
|
143
|
-
{% endmacro %}
|
144
161
|
|
145
|
-
{% macro gene_cell(variant) %}
|
162
|
+
{% macro gene_cell(variant, inherit_palette) %}
|
146
163
|
<div class="align-items-center">
|
147
164
|
{% if variant.category == "cancer" or variant.category == "sv_cancer" %}
|
148
165
|
<a data-bs-toggle="tooltip" data-bs-html="true" title="
|
@@ -191,7 +208,9 @@
|
|
191
208
|
</a>
|
192
209
|
{% endif %}
|
193
210
|
{% else %}
|
211
|
+
{% set panel_count = variant.case_panels|rejectattr('removed')|list|count %}
|
194
212
|
{% for gene in variant.genes %}
|
213
|
+
<div>
|
195
214
|
<a data-bs-toggle="tooltip" data-bs-html="true" title="
|
196
215
|
<div>
|
197
216
|
<div>
|
@@ -213,12 +232,8 @@
|
|
213
232
|
{% endif %}
|
214
233
|
</div>"
|
215
234
|
href="{{ url_for('genes.gene', hgnc_id=gene.hgnc_id) }}">{{ gene.hgnc_symbol or gene.hgnc_id }}
|
216
|
-
</a>
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
{% set panel_count = variant.case_panels|rejectattr('removed')|list|count %}
|
221
|
-
{% if panel_count > 0 %}
|
235
|
+
{% for model in gene.inheritance %} {{ inheritance_badge(model,inherit_palette) }}{% endfor %}</a>
|
236
|
+
{% if panel_count > 0 %}
|
222
237
|
<a
|
223
238
|
class="badge bg-secondary text-white"
|
224
239
|
data-bs-toggle="popover"
|
@@ -229,7 +244,10 @@
|
|
229
244
|
{% endfor %}"
|
230
245
|
title="Overlapping gene panels">{{panel_count}}
|
231
246
|
</a>
|
232
|
-
|
247
|
+
{% endif %}
|
248
|
+
</div>
|
249
|
+
{% endfor %}
|
250
|
+
|
233
251
|
{% endif %}
|
234
252
|
</div>
|
235
253
|
{% endmacro %}
|
@@ -272,21 +290,20 @@
|
|
272
290
|
">
|
273
291
|
{% if variant.clinsig_human %}
|
274
292
|
<span class="badge bg-secondary">ClinVar</span>
|
275
|
-
<br>
|
276
293
|
{% endif%}
|
277
294
|
{% if variant.cosmic_ids %}
|
278
295
|
<span class="badge bg-secondary">COSMIC</span>
|
279
|
-
|
296
|
+
|
280
297
|
{% endif %}
|
281
298
|
{% if variant.mitomap_associated_diseases %}
|
282
299
|
<span class="badge bg-secondary">MITOMAP</span>
|
283
|
-
<br>
|
284
300
|
{% endif %}
|
285
301
|
{% if variant.clingen_cgh_pathogenic %}
|
286
|
-
<span class="badge bg-secondary">CGH Pathogenic</span
|
302
|
+
<span class="badge bg-secondary">CGH Pathogenic</span>
|
287
303
|
{% endif %}
|
288
304
|
{% if variant.local_obs_old or variant.local_obs_cancer_germline_old or variant.local_obs_cancer_somatic_old %}
|
289
|
-
<span class="badge bg-secondary">Local
|
305
|
+
<span class="badge bg-secondary">Local {% if variant.category in ['snv', 'sv'] %}<span class="badge bg-dark text-white">
|
306
|
+
{{ variant.local_obs_old or 0 }}</span>{% endif %}</span>
|
290
307
|
<br>
|
291
308
|
{% endif %}
|
292
309
|
</div>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{% extends "layout.html" %}
|
2
2
|
{% from "variants/utils.html" import mei_filters, cell_rank, pagination_footer, pagination_hidden_div, dismiss_variants_block, filter_form_footer, filter_script_main, update_stash_filter_button_status %}
|
3
|
-
{% from "variants/components.html" import external_scripts, external_stylesheets, frequency_cell_general, variant_gene_symbols_cell, variant_funct_anno_cell
|
3
|
+
{% from "variants/components.html" import external_scripts, external_stylesheets, frequency_cell_general, variant_gene_symbols_cell, variant_funct_anno_cell %}
|
4
4
|
|
5
5
|
{% block title %}
|
6
6
|
{{ super() }} - {{ institute.display_name }} - {{ case.display_name }} - Mobile Element Insertion variants
|
@@ -65,7 +65,6 @@ onsubmit="return validateForm()">
|
|
65
65
|
<th style="width:9%">Start loc</th>
|
66
66
|
<th>Frequency</th>
|
67
67
|
<th>Gene(s)</th>
|
68
|
-
<th>Region</th>
|
69
68
|
<th>Function</th>
|
70
69
|
</tr>
|
71
70
|
</thead>
|
@@ -109,10 +108,7 @@ onsubmit="return validateForm()">
|
|
109
108
|
{{ frequency_cell_general(variant) }}
|
110
109
|
</td>
|
111
110
|
<td>
|
112
|
-
{{ variant_gene_symbols_cell(variant) }}
|
113
|
-
</td>
|
114
|
-
<td style="word-wrap:break-word;">
|
115
|
-
{{ variant_region_anno_cell(variant) }}
|
111
|
+
{{ variant_gene_symbols_cell(variant, inherit_palette) }}
|
116
112
|
</td>
|
117
113
|
<td style="word-wrap:break-word;">
|
118
114
|
{{ variant_funct_anno_cell(variant) }}
|
@@ -1,10 +1,11 @@
|
|
1
1
|
{% extends "layout.html" %}
|
2
2
|
{% from "utils.html" import comments_table, pedigree_panel %}
|
3
|
-
{% from "variants/components.html" import external_scripts, external_stylesheets, gene_cell, frequency_cell_general %}
|
4
3
|
{% from "variant/buttons.html" import reviewer_button%}
|
5
|
-
|
4
|
+
{% from "variant/gene_disease_relations.html" import inheritance_badge %}
|
5
|
+
{% from "variants/components.html" import external_scripts, external_stylesheets, frequency_cell_general %}
|
6
6
|
{% from "variants/utils.html" import cell_rank, dismiss_variants_block, filter_form_footer, update_stash_filter_button_status, pagination_footer, pagination_hidden_div, str_filters, filter_script_main %}
|
7
7
|
|
8
|
+
|
8
9
|
{% block title %}
|
9
10
|
{{ super() }} - {{ institute.display_name }} - {{ case.display_name }} - STR variants
|
10
11
|
{% endblock %}
|
@@ -239,6 +240,11 @@
|
|
239
240
|
{% for gene in variant.genes %} {{ gene.symbol }} {% endfor %} {% endif %}
|
240
241
|
</a>
|
241
242
|
{% for gene in variant.genes %}
|
243
|
+
{% if variant.str_disease %}
|
244
|
+
{{ inheritance_badge(variant.str_inheritance_mode,inherit_palette) }}
|
245
|
+
{% else %}
|
246
|
+
{% for model in gene.inheritance %} {{ inheritance_badge(model,inherit_palette) }} {% endfor %}
|
247
|
+
{% endif %}
|
242
248
|
<span class="badge bg-secondary"><a href="{{ gene.stripy_link }}" class="text-white" referrerpolicy="no-referrer" rel="noopener" target="_blank">S</a></span>
|
243
249
|
<span class="badge bg-secondary"><a href="{{ gene.gnomad_str_link }}" class="text-white" referrerpolicy="no-referrer" rel="noopener" target="_blank">G</a></span>
|
244
250
|
{% endfor %}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
{% extends "layout.html" %}
|
2
2
|
{% from "variants/utils.html" import sv_filters, cell_rank, pagination_footer, pagination_hidden_div, dismiss_variants_block, filter_form_footer, filter_script_main, update_stash_filter_button_status %}
|
3
|
-
{% from "variants/components.html" import external_scripts, external_stylesheets, frequency_cell_general, observed_cell_general, variant_gene_symbols_cell, variant_funct_anno_cell
|
3
|
+
{% from "variants/components.html" import external_scripts, external_stylesheets, frequency_cell_general, observed_cell_general, variant_gene_symbols_cell, variant_funct_anno_cell %}
|
4
4
|
|
5
5
|
{% block title %}
|
6
6
|
{{ super() }} - {{ institute.display_name }} - {{ case.display_name }} - SV variants
|
@@ -67,13 +67,12 @@ onsubmit="return validateForm()">
|
|
67
67
|
<th>Pop Freq</th>
|
68
68
|
<th>Observed</th>
|
69
69
|
<th>Gene(s)</th>
|
70
|
-
<th>Region</th>
|
71
70
|
<th>Function</th>
|
72
71
|
</tr>
|
73
72
|
</thead>
|
74
73
|
<tbody>
|
75
74
|
{% for variant in variants %}
|
76
|
-
{{ variant_row(variant) }}
|
75
|
+
{{ variant_row(variant, inherit_palette) }}
|
77
76
|
{% else %}
|
78
77
|
<tr>
|
79
78
|
<td colspan="11">No matching variants</td>
|
@@ -90,7 +89,7 @@ onsubmit="return validateForm()">
|
|
90
89
|
</div>
|
91
90
|
{% endblock %}
|
92
91
|
|
93
|
-
{% macro variant_row(variant) %}
|
92
|
+
{% macro variant_row(variant, inherit_palette) %}
|
94
93
|
{% if variant.dismiss_variant %}
|
95
94
|
<tr class="dismiss">
|
96
95
|
{% elif 'causatives' in case and variant._id in case.causatives %}
|
@@ -114,10 +113,7 @@ onsubmit="return validateForm()">
|
|
114
113
|
</td>
|
115
114
|
<td>{{observed_cell_general(variant)}}</td>
|
116
115
|
<td>
|
117
|
-
{{ variant_gene_symbols_cell(variant) }}
|
118
|
-
</td>
|
119
|
-
<td style="word-wrap:break-word;">
|
120
|
-
{{ variant_region_anno_cell(variant) }}
|
116
|
+
{{ variant_gene_symbols_cell(variant, inherit_palette) }}
|
121
117
|
</td>
|
122
118
|
<td style="word-wrap:break-word;">
|
123
119
|
{{ variant_funct_anno_cell(variant) }}
|
@@ -56,16 +56,15 @@
|
|
56
56
|
<tr>
|
57
57
|
<th style="width:2%"></th>
|
58
58
|
<th style="width:12%" title="Rank position">Rank</th>
|
59
|
-
<th style="width:
|
59
|
+
<th style="width:5%" title="Rank score">Score</th>
|
60
60
|
<th style="width:4%" title="Chromosome">Chr.</th>
|
61
|
-
<th style="width:
|
62
|
-
<th style="width:
|
63
|
-
<th style="width:
|
61
|
+
<th style="width:12%" title="HGNC symbols">Gene</th>
|
62
|
+
<th style="width:6%" title="Pop Freq">Pop Freq</th>
|
63
|
+
<th style="width:10%" title="Observed database matches">Observed</th>
|
64
64
|
<th style="width:5%" title="CADD score">CADD</th>
|
65
|
-
<th style="width:
|
66
|
-
<th style="width:
|
67
|
-
<th style="width:
|
68
|
-
<th style="width:8%" title="Overlapping">Overlapping</th>
|
65
|
+
<th style="width:18%" title="Functional annotation">Function</th>
|
66
|
+
<th style="width:14%" title="Inheritance models">Inheritance model</th>
|
67
|
+
<th style="width:14%" title="Overlapping">Overlap</th>
|
69
68
|
</tr>
|
70
69
|
</thead>
|
71
70
|
<tbody>
|
@@ -86,26 +85,19 @@
|
|
86
85
|
{{ mark_heteroplasmic_mt(case.individuals, variant.samples) }}
|
87
86
|
{% endif %}
|
88
87
|
</td>
|
89
|
-
<td>{{ gene_cell(variant) }}</td>
|
88
|
+
<td>{{ gene_cell(variant, inherit_palette) }}</td>
|
90
89
|
<td class="text-start">{{ frequency_cell_general(variant) }}</td>
|
91
90
|
<td class="text-start">{{ observed_cell_general(variant) }}</td>
|
92
91
|
<td class="text-end">{{ cell_cadd(variant) }}</td>
|
93
92
|
<td>
|
94
|
-
{
|
95
|
-
<div>{{ annotation }}</div>
|
96
|
-
{% endfor %}
|
97
|
-
</td>
|
98
|
-
<td>
|
99
|
-
{% for annotation in variant.functional_annotations %}
|
100
|
-
<div>{{ annotation }}</div>
|
101
|
-
{% endfor %}
|
93
|
+
{{ functional_annotation_cell(variant) }}
|
102
94
|
</td>
|
103
95
|
<td>{{ cell_models(variant) }}</td>
|
104
96
|
<td>{{ overlapping_cell(variant) }}</td>
|
105
97
|
</tr>
|
106
98
|
{% else %}
|
107
99
|
<tr>
|
108
|
-
<td colspan="
|
100
|
+
<td colspan="9">
|
109
101
|
No matching variants
|
110
102
|
</td>
|
111
103
|
</tr>
|
@@ -121,6 +113,19 @@
|
|
121
113
|
</div>
|
122
114
|
{% endblock %}
|
123
115
|
|
116
|
+
{% macro functional_annotation_cell(variant) %}
|
117
|
+
<div data-bs-toggle="tooltip" data-bs-html="true" title="
|
118
|
+
<div>
|
119
|
+
{% for annotation in variant.region_annotations %}
|
120
|
+
{{ annotation }}</br>
|
121
|
+
{% endfor %}
|
122
|
+
</div>">
|
123
|
+
{% for annotation in variant.functional_annotations %}
|
124
|
+
<div>{{ annotation }}</div>
|
125
|
+
{% endfor %}
|
126
|
+
</div>
|
127
|
+
{% endmacro %}
|
128
|
+
|
124
129
|
{% macro cell_cadd(variant) %}
|
125
130
|
<div data-bs-toggle="tooltip" data-bs-placement="left" data-bs-html="true" title="
|
126
131
|
<div class='text-start'>
|
@@ -13,6 +13,7 @@ from scout.constants import (
|
|
13
13
|
CANCER_TIER_OPTIONS,
|
14
14
|
DISMISS_VARIANT_OPTIONS,
|
15
15
|
GENETIC_MODELS_PALETTE,
|
16
|
+
INHERITANCE_PALETTE,
|
16
17
|
MANUAL_RANK_OPTIONS,
|
17
18
|
SEVERE_SO_TERMS,
|
18
19
|
SEVERE_SO_TERMS_SV,
|
@@ -163,6 +164,7 @@ def variants(institute_id, case_name):
|
|
163
164
|
filters=available_filters,
|
164
165
|
form=form,
|
165
166
|
genetic_models_palette=GENETIC_MODELS_PALETTE,
|
167
|
+
inherit_palette=INHERITANCE_PALETTE,
|
166
168
|
institute=institute_obj,
|
167
169
|
manual_rank_options=MANUAL_RANK_OPTIONS,
|
168
170
|
page=page,
|
@@ -254,6 +256,7 @@ def str_variants(institute_id, case_name):
|
|
254
256
|
expand_search=controllers.get_expand_search(request.form),
|
255
257
|
filters=available_filters,
|
256
258
|
form=form,
|
259
|
+
inherit_palette=INHERITANCE_PALETTE,
|
257
260
|
institute=institute_obj,
|
258
261
|
manual_rank_options=MANUAL_RANK_OPTIONS,
|
259
262
|
page=page,
|
@@ -333,6 +336,7 @@ def sv_variants(institute_id, case_name):
|
|
333
336
|
expand_search=controllers.get_expand_search(request.form),
|
334
337
|
filters=available_filters,
|
335
338
|
form=form,
|
339
|
+
inherit_palette=INHERITANCE_PALETTE,
|
336
340
|
institute=institute_obj,
|
337
341
|
manual_rank_options=MANUAL_RANK_OPTIONS,
|
338
342
|
page=page,
|
@@ -429,6 +433,7 @@ def mei_variants(institute_id, case_name):
|
|
429
433
|
expand_search=controllers.get_expand_search(request.form),
|
430
434
|
filters=available_filters,
|
431
435
|
form=form,
|
436
|
+
inherit_palette=INHERITANCE_PALETTE,
|
432
437
|
institute=institute_obj,
|
433
438
|
manual_rank_options=MANUAL_RANK_OPTIONS,
|
434
439
|
page=page,
|
@@ -627,6 +632,7 @@ def cancer_sv_variants(institute_id, case_name):
|
|
627
632
|
expand_search=controllers.get_expand_search(request.form),
|
628
633
|
filters=available_filters,
|
629
634
|
form=form,
|
635
|
+
inherit_palette=INHERITANCE_PALETTE,
|
630
636
|
institute=institute_obj,
|
631
637
|
manual_rank_options=MANUAL_RANK_OPTIONS,
|
632
638
|
page=page,
|
scout/utils/acmg.py
CHANGED
@@ -1,4 +1,12 @@
|
|
1
1
|
# coding=UTF-8
|
2
|
+
|
3
|
+
|
4
|
+
from typing import Optional
|
5
|
+
|
6
|
+
from scout.constants import ACMG_COMPLETE_MAP
|
7
|
+
from scout.constants.acmg import ACMG_POTENTIAL_CONFLICTS
|
8
|
+
|
9
|
+
|
2
10
|
def is_pathogenic(pvs, ps_terms, pm_terms, pp_terms):
|
3
11
|
"""Check if the criterias for Pathogenic is fullfilled
|
4
12
|
|
@@ -157,38 +165,31 @@ def is_likely_benign(bs_terms, bp_terms):
|
|
157
165
|
return False
|
158
166
|
|
159
167
|
|
160
|
-
def
|
161
|
-
"""Use the algorithm described in ACMG paper to get a ACMG calssification
|
162
|
-
|
163
|
-
Modifying strength of a term is possible by adding a string describing its new level: "PP1_Strong" or
|
164
|
-
"PVS1_Moderate".
|
165
|
-
|
166
|
-
If no terms return None
|
167
|
-
|
168
|
-
Args:
|
169
|
-
acmg_terms(set(str)): A collection of prediction terms
|
170
|
-
|
171
|
-
Returns:
|
172
|
-
prediction(str): in ['uncertain_significance','benign','likely_benign',
|
173
|
-
'likely_pathogenic','pathogenic']
|
174
|
-
|
168
|
+
def get_acmg_criteria(acmg_terms: set) -> tuple:
|
175
169
|
"""
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
170
|
+
Given a set of ACMG evidence criteria terms, that may be strength modified with suffixes.
|
171
|
+
For each term,
|
172
|
+
first, Strength modified criteria suffixes should count towards their modified score.
|
173
|
+
then, we need to see if we match any of the two stand-alone terms. If so, set their respective booleans.
|
174
|
+
finally, check remaining prefixes if no suffix match or stand-alone criteria match
|
175
|
+
|
176
|
+
Return a tuple with
|
177
|
+
pvs: This variable indicates if Pathogenicity Very Strong exists
|
178
|
+
ps_terms: Collection of terms with Pathogenicity Strong
|
179
|
+
pm_terms: Collection of terms with Pathogenicity moderate
|
180
|
+
pp_terms: Collection of terms with Pathogenicity supporting
|
181
|
+
ba: This variable indicates if Benign impact stand-alone exists
|
182
|
+
bs_terms: Collection of terms with Benign evidence Strong
|
183
|
+
bp_terms: Collection of terms with supporting Benign evidence
|
184
|
+
"""
|
185
|
+
|
180
186
|
pvs = False
|
181
|
-
# Collection of terms with Pathogenecity Strong
|
182
187
|
ps_terms = []
|
183
|
-
# Collection of terms with Pathogenecity moderate
|
184
188
|
pm_terms = []
|
185
|
-
# Collection of terms with Pathogenecity supporting
|
186
189
|
pp_terms = []
|
187
|
-
|
190
|
+
|
188
191
|
ba = False
|
189
|
-
# Collection of terms with Benign evidence Strong
|
190
192
|
bs_terms = []
|
191
|
-
# Collection of terms with supporting Benign evidence
|
192
193
|
bp_terms = []
|
193
194
|
|
194
195
|
suffix_map = {
|
@@ -212,20 +213,51 @@ def get_acmg(acmg_terms):
|
|
212
213
|
if term.startswith(prefix):
|
213
214
|
term_list.append(term)
|
214
215
|
break
|
216
|
+
else:
|
217
|
+
continue
|
215
218
|
break
|
216
219
|
else:
|
217
|
-
# Do we match any of the two standalone terms
|
218
220
|
if term.startswith("PVS"):
|
219
221
|
pvs = True
|
220
222
|
elif term.startswith("BA"):
|
221
223
|
ba = True
|
222
|
-
else:
|
224
|
+
else:
|
223
225
|
for prefix, term_list in prefix_map.items():
|
224
226
|
if term.startswith(prefix):
|
225
227
|
term_list.append(term)
|
226
228
|
break
|
227
229
|
|
228
|
-
|
230
|
+
return (pvs, ps_terms, pm_terms, pp_terms, ba, bs_terms, bp_terms)
|
231
|
+
|
232
|
+
|
233
|
+
def get_acmg(acmg_terms: set) -> Optional[str]:
|
234
|
+
"""Use the algorithm described in ACMG paper (Richards 2015) to get a ACMG classification
|
235
|
+
|
236
|
+
Modifying strength of a term is possible by adding a string describing its new level: "PP1_Strong" or
|
237
|
+
"PVS1_Moderate".
|
238
|
+
|
239
|
+
BA is considered fully Stand Alone.
|
240
|
+
|
241
|
+
If no terms return None
|
242
|
+
|
243
|
+
Args:
|
244
|
+
acmg_terms(set(str)): A collection of prediction terms
|
245
|
+
|
246
|
+
Returns:
|
247
|
+
prediction(str): in ['uncertain_significance','benign','likely_benign',
|
248
|
+
'likely_pathogenic','pathogenic']
|
249
|
+
|
250
|
+
"""
|
251
|
+
if not acmg_terms:
|
252
|
+
return None
|
253
|
+
|
254
|
+
(pvs, ps_terms, pm_terms, pp_terms, ba, bs_terms, bp_terms) = get_acmg_criteria(acmg_terms)
|
255
|
+
|
256
|
+
if ba:
|
257
|
+
return "benign"
|
258
|
+
|
259
|
+
prediction = "uncertain_significance"
|
260
|
+
|
229
261
|
pathogenic = is_pathogenic(pvs, ps_terms, pm_terms, pp_terms)
|
230
262
|
likely_pathogenic = is_likely_pathogenic(pvs, ps_terms, pm_terms, pp_terms)
|
231
263
|
benign = is_benign(ba, bs_terms)
|
@@ -245,3 +277,98 @@ def get_acmg(acmg_terms):
|
|
245
277
|
prediction = "likely_benign"
|
246
278
|
|
247
279
|
return prediction
|
280
|
+
|
281
|
+
|
282
|
+
def get_acmg_temperature(acmg_terms: set) -> Optional[dict]:
|
283
|
+
"""
|
284
|
+
Use the algorithm described in Tavtigian 2020 to classifiy variants.
|
285
|
+
|
286
|
+
PVS 8 points, S 4, M 2, P 1.
|
287
|
+
This gives:
|
288
|
+
|
289
|
+
P > 10
|
290
|
+
LP 6 < p < 9
|
291
|
+
VUS 0 < p < 5
|
292
|
+
LB -1 < p < -6
|
293
|
+
B < -7
|
294
|
+
|
295
|
+
If no terms return None
|
296
|
+
|
297
|
+
Args:
|
298
|
+
acmg_terms(set(str)): A collection of prediction terms
|
299
|
+
|
300
|
+
Returns:
|
301
|
+
dict:
|
302
|
+
temperature:
|
303
|
+
(points, temperature, point_classification)
|
304
|
+
|
305
|
+
"""
|
306
|
+
TEMPERATURE_STRINGS = {
|
307
|
+
-1: {"label": "B/LB", "color": "success", "icon": "fa-times"},
|
308
|
+
0: {"label": "Ice cold", "color": "info", "icon": "fa-icicles"},
|
309
|
+
1: {"label": "Cold", "color": "info", "icon": "fa-snowman"},
|
310
|
+
2: {"label": "Cold", "color": "info", "icon": "fa-snowflake"},
|
311
|
+
3: {"label": "Tepid", "color": "yellow", "icon": "fa-temperature-half"},
|
312
|
+
4: {"label": "Warm", "color": "orange", "icon": "fa-mug-hot"},
|
313
|
+
5: {"label": "Hot", "color": "red", "icon": "fa-pepper-hot"},
|
314
|
+
6: {"label": "LP/P", "color": "danger", "icon": "fa-stethoscope"},
|
315
|
+
}
|
316
|
+
|
317
|
+
if not acmg_terms:
|
318
|
+
return {}
|
319
|
+
|
320
|
+
(pvs, ps_terms, pm_terms, pp_terms, ba, bs_terms, bp_terms) = get_acmg_criteria(acmg_terms)
|
321
|
+
|
322
|
+
if ba:
|
323
|
+
points = -8
|
324
|
+
else:
|
325
|
+
points = (
|
326
|
+
8 * pvs
|
327
|
+
+ 4 * len(ps_terms)
|
328
|
+
+ 2 * len(pm_terms)
|
329
|
+
+ len(pp_terms)
|
330
|
+
- 4 * len(bs_terms)
|
331
|
+
- len(bp_terms)
|
332
|
+
)
|
333
|
+
|
334
|
+
if points <= -7:
|
335
|
+
point_classification = "benign"
|
336
|
+
temperature_icon = TEMPERATURE_STRINGS[-1].get("icon")
|
337
|
+
elif points <= -1:
|
338
|
+
point_classification = "likely_benign"
|
339
|
+
temperature_icon = TEMPERATURE_STRINGS[-1].get("icon")
|
340
|
+
elif points <= 5:
|
341
|
+
point_classification = "uncertain_significance"
|
342
|
+
elif points <= 9:
|
343
|
+
point_classification = "likely_pathogenic"
|
344
|
+
temperature_icon = TEMPERATURE_STRINGS[6].get("icon")
|
345
|
+
elif points >= 10:
|
346
|
+
point_classification = "pathogenic"
|
347
|
+
temperature_icon = TEMPERATURE_STRINGS[6].get("icon")
|
348
|
+
|
349
|
+
temperature_class = ACMG_COMPLETE_MAP[point_classification].get("color")
|
350
|
+
temperature = ACMG_COMPLETE_MAP[point_classification].get("label")
|
351
|
+
|
352
|
+
if point_classification == "uncertain_significance":
|
353
|
+
temperature_class = TEMPERATURE_STRINGS[points].get("color")
|
354
|
+
temperature = TEMPERATURE_STRINGS[points].get("label")
|
355
|
+
temperature_icon = TEMPERATURE_STRINGS[points].get("icon")
|
356
|
+
|
357
|
+
return {
|
358
|
+
"points": points,
|
359
|
+
"temperature": temperature,
|
360
|
+
"temperature_class": temperature_class,
|
361
|
+
"temperature_icon": temperature_icon,
|
362
|
+
"point_classification": ACMG_COMPLETE_MAP[point_classification].get("short"),
|
363
|
+
}
|
364
|
+
|
365
|
+
|
366
|
+
def get_acmg_conflicts(acmg_terms: set) -> list:
|
367
|
+
"""Check potential conflict paris, return list of reference strings."""
|
368
|
+
|
369
|
+
conflicts = []
|
370
|
+
for t1, t2, reference in ACMG_POTENTIAL_CONFLICTS:
|
371
|
+
if t1 in acmg_terms and t2 in acmg_terms:
|
372
|
+
conflicts.append(reference)
|
373
|
+
|
374
|
+
return conflicts
|
scout/utils/scout_requests.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
import logging
|
4
4
|
import urllib.request
|
5
5
|
import zlib
|
6
|
-
from typing import Dict
|
6
|
+
from typing import Dict, List
|
7
7
|
from urllib.error import HTTPError
|
8
8
|
|
9
9
|
import requests
|
@@ -134,7 +134,7 @@ def fetch_resource(url, json=False):
|
|
134
134
|
"""
|
135
135
|
if url.startswith("ftp"):
|
136
136
|
# requests do not handle ftp
|
137
|
-
response = urllib.request.urlopen(url, timeout=TIMEOUT)
|
137
|
+
response = urllib.request.urlopen(url, timeout=TIMEOUT) # nosec
|
138
138
|
if isinstance(response, Exception):
|
139
139
|
raise response
|
140
140
|
data = response.read().decode("utf-8")
|
@@ -307,20 +307,15 @@ def fetch_orpha_files() -> Dict:
|
|
307
307
|
return orpha_files
|
308
308
|
|
309
309
|
|
310
|
-
def fetch_hgnc():
|
311
|
-
"""Fetch the hgnc genes file from
|
312
|
-
|
313
|
-
|
314
|
-
Returns:
|
315
|
-
hgnc_gene_lines(list(str))
|
310
|
+
def fetch_hgnc() -> List[str]:
|
311
|
+
"""Fetch the hgnc genes names file from
|
312
|
+
https://storage.googleapis.com/public-download-files/hgnc/tsv/tsv/hgnc_complete_set.txt
|
316
313
|
"""
|
317
|
-
file_name = "hgnc_complete_set.txt"
|
318
|
-
url = "ftp://ftp.ebi.ac.uk/pub/databases/genenames/new/tsv/{0}".format(file_name)
|
319
|
-
LOG.info("Fetching HGNC genes from %s", url)
|
320
314
|
|
321
|
-
|
315
|
+
url = "https://storage.googleapis.com/public-download-files/hgnc/tsv/tsv/hgnc_complete_set.txt"
|
316
|
+
LOG.info("Fetching HGNC genes from %s", url)
|
322
317
|
|
323
|
-
return
|
318
|
+
return fetch_resource(url)
|
324
319
|
|
325
320
|
|
326
321
|
def fetch_constraint():
|