scout-browser 4.98.0__py3-none-any.whl → 4.100.0__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/adapter/mongo/case.py +30 -15
- scout/adapter/mongo/clinvar.py +23 -31
- scout/adapter/mongo/event.py +14 -4
- scout/adapter/mongo/institute.py +42 -55
- scout/adapter/mongo/omics_variant.py +14 -1
- scout/adapter/mongo/query.py +24 -1
- scout/adapter/mongo/variant.py +44 -22
- scout/adapter/mongo/variant_loader.py +169 -186
- scout/build/individual.py +5 -1
- scout/build/variant/variant.py +8 -0
- scout/commands/download/ensembl.py +18 -3
- scout/commands/load/research.py +2 -3
- scout/commands/update/individual.py +3 -0
- scout/commands/update/panelapp.py +15 -2
- scout/constants/__init__.py +6 -2
- scout/constants/clnsig.py +2 -0
- scout/constants/file_types.py +12 -0
- scout/constants/igv_tracks.py +9 -6
- scout/constants/indexes.py +5 -4
- scout/constants/panels.py +3 -0
- scout/constants/query_terms.py +1 -0
- scout/constants/variant_tags.py +6 -6
- scout/demo/643594.config.yaml +1 -0
- scout/load/panelapp.py +11 -5
- scout/models/case/case.py +1 -0
- scout/models/case/case_loading_models.py +7 -1
- scout/parse/ensembl.py +8 -3
- scout/parse/variant/clnsig.py +38 -0
- scout/parse/variant/genotype.py +4 -10
- scout/parse/variant/models.py +5 -11
- scout/parse/variant/rank_score.py +5 -13
- scout/parse/variant/variant.py +90 -111
- scout/server/app.py +39 -22
- scout/server/blueprints/alignviewers/controllers.py +29 -10
- scout/server/blueprints/alignviewers/templates/alignviewers/igv_viewer.html +51 -11
- scout/server/blueprints/cases/controllers.py +9 -3
- scout/server/blueprints/cases/templates/cases/case_report.html +25 -13
- scout/server/blueprints/cases/templates/cases/chanjo2_form.html +1 -1
- scout/server/blueprints/cases/templates/cases/collapsible_actionbar.html +1 -1
- scout/server/blueprints/cases/templates/cases/gene_panel.html +1 -1
- scout/server/blueprints/cases/templates/cases/utils.html +25 -6
- scout/server/blueprints/clinvar/controllers.py +34 -15
- scout/server/blueprints/clinvar/templates/clinvar/clinvar_submissions.html +34 -12
- scout/server/blueprints/clinvar/templates/clinvar/multistep_add_variant.html +14 -5
- scout/server/blueprints/clinvar/views.py +14 -2
- scout/server/blueprints/diagnoses/static/diagnoses.js +8 -1
- scout/server/blueprints/institutes/controllers.py +10 -2
- scout/server/blueprints/institutes/static/variants_list_scripts.js +9 -1
- scout/server/blueprints/institutes/templates/overview/institute_sidebar.html +9 -1
- scout/server/blueprints/login/controllers.py +112 -12
- scout/server/blueprints/login/views.py +38 -60
- scout/server/blueprints/mme/__init__.py +1 -0
- scout/server/blueprints/mme/controllers.py +18 -0
- scout/server/blueprints/mme/templates/mme/mme_submissions.html +153 -0
- scout/server/blueprints/mme/views.py +34 -0
- scout/server/blueprints/panels/templates/panels/panel.html +19 -6
- scout/server/blueprints/phenotypes/templates/phenotypes/hpo_terms.html +8 -1
- scout/server/blueprints/public/templates/public/index.html +5 -1
- scout/server/blueprints/variant/controllers.py +19 -10
- scout/server/blueprints/variant/templates/variant/acmg.html +15 -2
- scout/server/blueprints/variant/templates/variant/cancer-variant.html +1 -1
- scout/server/blueprints/variant/templates/variant/components.html +38 -16
- scout/server/blueprints/variant/templates/variant/sv-variant.html +2 -2
- scout/server/blueprints/variant/templates/variant/utils.html +23 -11
- scout/server/blueprints/variant/templates/variant/variant.html +42 -1
- scout/server/blueprints/variant/views.py +12 -0
- scout/server/blueprints/variants/controllers.py +20 -3
- scout/server/blueprints/variants/forms.py +8 -3
- scout/server/blueprints/variants/templates/variants/components.html +34 -0
- scout/server/blueprints/variants/templates/variants/indicators.html +11 -13
- scout/server/blueprints/variants/templates/variants/mei-variants.html +8 -6
- scout/server/blueprints/variants/templates/variants/sv-variants.html +9 -7
- scout/server/blueprints/variants/templates/variants/utils.html +35 -34
- scout/server/blueprints/variants/templates/variants/variants.html +4 -25
- scout/server/config.py +8 -0
- scout/server/extensions/bionano_extension.py +0 -1
- scout/server/extensions/chanjo2_extension.py +54 -13
- scout/server/links.py +15 -0
- scout/server/static/bs_styles.css +34 -6
- scout/server/templates/utils.html +9 -10
- scout/server/utils.py +40 -5
- scout/utils/acmg.py +25 -26
- scout/utils/ensembl_biomart_clients.py +2 -1
- scout/utils/ensembl_rest_clients.py +25 -32
- scout/utils/hgvs.py +1 -1
- scout/utils/scout_requests.py +1 -3
- {scout_browser-4.98.0.dist-info → scout_browser-4.100.0.dist-info}/METADATA +10 -14
- {scout_browser-4.98.0.dist-info → scout_browser-4.100.0.dist-info}/RECORD +91 -87
- {scout_browser-4.98.0.dist-info → scout_browser-4.100.0.dist-info}/WHEEL +0 -0
- {scout_browser-4.98.0.dist-info → scout_browser-4.100.0.dist-info}/entry_points.txt +0 -0
- {scout_browser-4.98.0.dist-info → scout_browser-4.100.0.dist-info}/licenses/LICENSE +0 -0
@@ -104,7 +104,7 @@
|
|
104
104
|
</div>
|
105
105
|
|
106
106
|
<div class="row">
|
107
|
-
<div class="col-12">{{ overlapping_panel(variant, overlapping_vars, case, institute) }}</div>
|
107
|
+
<div class="col-12">{{ overlapping_panel(variant, overlapping_vars, overlapping_outliers, case, institute) }}</div>
|
108
108
|
{% if rank_score_results %}
|
109
109
|
<div class="col-12">{{ rankscore_panel(rank_score_results) }}</div>
|
110
110
|
{% endif %}
|
@@ -32,6 +32,25 @@
|
|
32
32
|
</tbody>
|
33
33
|
</table>
|
34
34
|
{% endif %}
|
35
|
+
|
36
|
+
{% if variant.clnsig_onc %}
|
37
|
+
<table id='clinsig_table' class="table table-bordered table-sm">
|
38
|
+
<thead>
|
39
|
+
<th>Oncogenicity</th>
|
40
|
+
<th>Disease name</th>
|
41
|
+
<th>Revstat</th>
|
42
|
+
</thead>
|
43
|
+
<tbody>
|
44
|
+
{% for classif in variant.clnsig_onc %}
|
45
|
+
<tr>
|
46
|
+
<td>{{ classif.value|capitalize }}</td>
|
47
|
+
<td>{{ classif.dn|replace("_", " ")|replace(",", ", ") }}</td>
|
48
|
+
<td>{{ classif.revstat }}</td>
|
49
|
+
</tr>
|
50
|
+
{% endfor %}
|
51
|
+
</tbody>
|
52
|
+
</table>
|
53
|
+
{% endif %}
|
35
54
|
{% endmacro %}
|
36
55
|
|
37
56
|
{% macro acmg_classification_item(variant, data) %}
|
@@ -113,27 +132,31 @@
|
|
113
132
|
</div>
|
114
133
|
{% endif %}
|
115
134
|
{% for gene in variant.genes %}
|
116
|
-
<div class="
|
135
|
+
<div class="ms-1">
|
117
136
|
{% if gene.alamut_link %}
|
118
137
|
<a href="{{ gene.alamut_link }}" class="btn btn-sm btn-secondary text-white" rel="noopener" referrerpolicy="no-referrer" target="_blank" data-bs-toggle="tooltip" title="Alamut Visual (Plus) - Open variant - with gene transcript c. coordinate">Alamut {{ gene.common.hgnc_symbol if gene.common else gene.hgnc_id }} c.</a>
|
119
138
|
{% endif %}
|
120
139
|
</div>
|
121
140
|
{% endfor %}
|
122
|
-
{{ gene_coverage(institute, variant, case, config) }}
|
123
141
|
</li>
|
124
142
|
<li class="list-group-item">
|
125
143
|
<div>
|
126
144
|
{{ igv_track_selection(igv_tracks, current_user) }}
|
127
145
|
</div>
|
128
146
|
</li>
|
147
|
+
{% if (case.chanjo_coverage and config.chanjo_report) or case.chanjo2_coverage %}
|
148
|
+
<li class="list-group-item d-flex justify-content-between">
|
149
|
+
{{ gene_coverage(institute, variant, case, config) }}
|
150
|
+
</li>
|
151
|
+
{% endif %}
|
129
152
|
</ul>
|
130
153
|
{% endmacro %}
|
131
154
|
|
132
155
|
{% macro gene_coverage(institute, variant, case, config) %}
|
133
156
|
{% if case.chanjo_coverage and config.chanjo_report %}
|
134
|
-
<div class="d-flex flex-wrap ms-1">
|
157
|
+
<div class="d-flex flex-wrap ms-1" data-bs-toggle="tooltip" title="Chanjo coverage reports">
|
135
158
|
{% for gene in variant.genes %}
|
136
|
-
<a class="btn btn-sm btn-secondary text-white" rel="noopener noreferrer" target="_blank" href="{{ url_for('report.gene', gene_id=gene.hgnc_id, sample_id=variant.samples|map(attribute='sample_id')|list) }}"
|
159
|
+
<a class="btn btn-sm btn-secondary text-white" rel="noopener noreferrer" target="_blank" href="{{ url_for('report.gene', gene_id=gene.hgnc_id, sample_id=variant.samples|map(attribute='sample_id')|list) }}">
|
137
160
|
Gene coverage: {{ gene.common.hgnc_symbol if gene.common else gene.hgnc_id }}
|
138
161
|
</a>
|
139
162
|
{% endfor %}
|
@@ -141,14 +164,12 @@
|
|
141
164
|
{% endif %}
|
142
165
|
{% if case.chanjo2_coverage %}
|
143
166
|
<div class="d-flex flex-wrap ms-1" data-bs-toggle="tooltip" title="Chanjo2 coverage reports">
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
<span class="
|
148
|
-
|
149
|
-
|
150
|
-
{% endif %}
|
151
|
-
{% endfor %}
|
167
|
+
{% for gene in variant.genes %}
|
168
|
+
<div class="btn-group" style="display:flex">
|
169
|
+
{{ chanjo2_report_form(institute, case, gene.hgnc_symbol if gene.hgnc_symbol else gene.hgnc_id, 'overview', gene.hgnc_id, "Gene coverage " ~ (gene.hgnc_symbol if gene.hgnc_symbol else gene.hgnc_id), "btn btn-sm btn-secondary text-white") }} <!--chanjo2 genes overview -->
|
170
|
+
<span class="btn complete-coverage-indicator align-items-center btn-info text-white btn-sm" style="display:flex" id="coverage-indicator-{{gene.hgnc_id}}-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-loading-text="Checking completeness..." title="Checking completeness..."><span style="display:flex" id="coverage-indicator-{{gene.hgnc_id}}-icon" class='align-self-center blink_me fa-solid fa-circle-question'></span><span style="display:flex" id="coverage-indicator-{{gene.hgnc_id}}-text" class='align-self-center'>Checking</span></span>
|
171
|
+
</div>
|
172
|
+
{% endfor %}
|
152
173
|
</div>
|
153
174
|
{% endif %}
|
154
175
|
{% endmacro %}
|
@@ -319,8 +340,8 @@
|
|
319
340
|
<div class="card-body mt-1 ms-3 mb-1" style="padding: 0;">
|
320
341
|
Matching manually ranked variants:
|
321
342
|
{% for manual_rank, manual_rank_info in matching_manual_ranked.items() %}
|
322
|
-
<a style="padding: 0;" class="btn btn-{{manual_rank_info.label_class}} btn-small" data-bs-toggle="collapse" href="#collapse_mr{{manual_rank}}" role="button" aria-expanded="false" aria-controls="
|
323
|
-
{{manual_rank_info.label}} ({{manual_rank_info.links|length}}x)
|
343
|
+
<a style="padding: 0;" class="btn btn-{{manual_rank_info.label_class}} btn-small" data-bs-toggle="collapse" href="#collapse_mr{{manual_rank}}" role="button" aria-expanded="false" aria-controls="#collapse_mr{{manual_rank}}">
|
344
|
+
<span class="collapse-button-icon me-1"></span>{{manual_rank_info.label}} ({{manual_rank_info.links|length}}x)
|
324
345
|
</a>
|
325
346
|
<div class="collapse" id="collapse_mr{{manual_rank}}">
|
326
347
|
<div>
|
@@ -341,8 +362,8 @@
|
|
341
362
|
<div class="card-body mt-1 ms-3 mb-1" style="padding: 0;">
|
342
363
|
Matching tiered:
|
343
364
|
{% for tier, tiered_info in matching_tiered.items() %}
|
344
|
-
<a style="padding: 0;" class="btn btn-{{tiered_info.
|
345
|
-
{{tier}} ({{tiered_info.links|length}}x)
|
365
|
+
<a style="padding: 0;" class="btn btn-{{tiered_info.label_class}} btn-xs" data-bs-toggle="collapse" href="#collapse_{{tier}}" aria-expanded="false" aria-controls="collapse_{{tier}}">
|
366
|
+
<span class="collapse-button-icon me-1"></span>{{tier}} ({{tiered_info.links|length}}x)
|
346
367
|
</a>
|
347
368
|
<div class="collapse" id="collapse_{{tier}}">
|
348
369
|
<div>
|
@@ -412,6 +433,7 @@
|
|
412
433
|
<a href="{{ gene.oncokb_link }}" class="btn btn-secondary text-white" rel="noopener" referrerpolicy="no-referrer" target="_blank">OncoKB</a>
|
413
434
|
<a href="{{ gene.civic_link }}" class="btn btn-secondary text-white" rel="noopener" referrerpolicy="no-referrer" target="_blank">CIViC</a>
|
414
435
|
<a href="{{ gene.ckb_link }}" class="btn btn-secondary text-white" rel="noopener" referrerpolicy="no-referrer" target="_blank">CKB</a>
|
436
|
+
<a href="{{ gene.cancer_hotspots_link }}" class="btn btn-secondary text-white" rel="noopener" referrerpolicy="no-referrer" target="_blank">Cancer Hotspots</a>
|
415
437
|
{% endif %}
|
416
438
|
{% if str %}
|
417
439
|
<a href="{{ gene.stripy_link }}" class="btn btn-secondary text-white" rel="noopener" referrerpolicy="no-referrer" target="_blank">STRipy</a>
|
@@ -74,7 +74,7 @@
|
|
74
74
|
{% if variant.category == "cancer_sv" %}
|
75
75
|
{{matching_variants(managed_variant, causatives, variant.matching_tiered) }}
|
76
76
|
{% else %}
|
77
|
-
{{matching_variants(managed_variant, causatives) }}
|
77
|
+
{{matching_variants(managed_variant, causatives, variant.matching_ranked) }}
|
78
78
|
{% endif %}
|
79
79
|
</div>
|
80
80
|
</div>
|
@@ -122,7 +122,7 @@
|
|
122
122
|
</div>
|
123
123
|
|
124
124
|
<div class="row">
|
125
|
-
<div class="col-12">{{ overlapping_panel(variant, overlapping_vars, case, institute) }}</div>
|
125
|
+
<div class="col-12">{{ overlapping_panel(variant, overlapping_vars, overlapping_outliers, case, institute) }}</div>
|
126
126
|
</div>
|
127
127
|
|
128
128
|
<div class="mt-3 row">
|
@@ -116,12 +116,12 @@
|
|
116
116
|
</div>
|
117
117
|
{% endmacro %}
|
118
118
|
|
119
|
-
{% macro overlapping_panel(variant, overlapping_vars, case, institute) %}
|
119
|
+
{% macro overlapping_panel(variant, overlapping_vars, overlapping_outliers, case, institute) %}
|
120
120
|
<div class="card panel-default">
|
121
|
-
{% if variant.category
|
122
|
-
<div class="panel-heading">
|
121
|
+
{% if variant.category != "snv" %}
|
122
|
+
<div class="panel-heading">Gene overlapping variants</div>
|
123
123
|
{% else %}
|
124
|
-
<div class="panel-heading">
|
124
|
+
<div class="panel-heading">Gene overlapping non-SNVs</div>
|
125
125
|
{% endif %}
|
126
126
|
<div class="card-body">
|
127
127
|
<div class="table-responsive">
|
@@ -141,27 +141,39 @@
|
|
141
141
|
</tr>
|
142
142
|
</thead>
|
143
143
|
<tbody>
|
144
|
-
{% for overlapping_variant in overlapping_vars %}
|
144
|
+
{% for overlapping_variant in overlapping_vars + overlapping_outliers %}
|
145
145
|
<tr>
|
146
146
|
<td>
|
147
147
|
{% if overlapping_variant.category in ("sv", "cancer_sv") %}
|
148
148
|
<a href="{{url_for('variant.sv_variant', institute_id=institute._id,
|
149
149
|
case_name=case.display_name, variant_id=overlapping_variant._id)}}" target="_blank">
|
150
|
-
{{ overlapping_variant.display_name|truncate(
|
150
|
+
{{ overlapping_variant.display_name|truncate(50, True) }}
|
151
151
|
</a>
|
152
|
-
{%
|
152
|
+
{% elif overlapping_variant.category == "outlier" %}
|
153
|
+
{{ overlapping_variant.display_name|truncate(50, True) }}
|
154
|
+
{% else %}
|
153
155
|
<a href="{{url_for('variant.variant', institute_id=institute._id,
|
154
156
|
case_name=case.display_name, variant_id=overlapping_variant._id)}}" target="_blank">
|
155
|
-
{{ overlapping_variant.display_name|truncate(
|
157
|
+
{{ overlapping_variant.display_name|truncate(50, True) }}
|
156
158
|
</a>
|
157
159
|
{% endif %}
|
158
160
|
</td>
|
159
161
|
<td>{{ overlapping_variant.hgnc_symbols|join(', ')|truncate(40, True) }}</td>
|
160
162
|
<td>{{ overlapping_variant.sub_category|upper }}</td>
|
161
|
-
|
162
|
-
|
163
|
+
{% if overlapping_variant.rank_score %}
|
164
|
+
<td class="text-end">{{ variant.rank_score + overlapping_variant.rank_score }}</td>
|
165
|
+
<td class="text-end">{{ overlapping_variant.rank_score }}</td>
|
166
|
+
{% else %}
|
167
|
+
<td class="text-end">-</td><td class="text-end">-</td>
|
168
|
+
{% endif %}
|
169
|
+
|
163
170
|
<td class="text-end">{{ overlapping_variant.length }}</td>
|
164
|
-
<td>
|
171
|
+
<td>
|
172
|
+
{{ overlapping_variant.region_annotations|join(', ')|truncate(40, True) }}
|
173
|
+
{% if overlapping_variant.sub_category == "splicing" %}
|
174
|
+
{{ overlapping_variant.potential_impact }} - fs {{ overlapping_variant.causes_frameshift }}
|
175
|
+
{% endif %}
|
176
|
+
</td>
|
165
177
|
<td>{{ overlapping_variant.functional_annotations|join(', ')|truncate(40, True) }}</td>
|
166
178
|
</tr>
|
167
179
|
{% else %}
|
@@ -152,7 +152,7 @@
|
|
152
152
|
{% endif %}
|
153
153
|
{{ rankscore_panel(rank_score_results) }}
|
154
154
|
<div class="row">
|
155
|
-
<div class="col-12">{{ overlapping_panel(variant, overlapping_vars, case, institute) }}</div>
|
155
|
+
<div class="col-12">{{ overlapping_panel(variant, overlapping_vars, overlapping_outliers, case, institute) }}</div>
|
156
156
|
</div>
|
157
157
|
<div class="mt-3 row">
|
158
158
|
<div class="col-12">
|
@@ -432,5 +432,46 @@
|
|
432
432
|
set_scrolly_table('proteins_panel_table')
|
433
433
|
set_scrolly_table('transcripts_panel_table')
|
434
434
|
|
435
|
+
function update_gene_has_full_coverage() {
|
436
|
+
$.getJSON('{{ url_for("variant.gene_has_full_coverage", institute_id=institute._id, case_name=case.display_name, variant_id=variant._id) }}', function (data) {
|
437
|
+
if($.isEmptyObject(data.gene_has_full_coverage)) {
|
438
|
+
const complete_coverage_indicator_elements = document.getElementsByClassName("complete-coverage-indicator");
|
439
|
+
for(let complete_coverage_indicator of complete_coverage_indicator_elements) {
|
440
|
+
complete_coverage_indicator.style.display = "none"
|
441
|
+
}
|
442
|
+
}
|
443
|
+
for (const [hgnc_id, has_complete_coverage] of Object.entries(data.gene_has_full_coverage)) {
|
444
|
+
// reset the temp color for the outer span and icon of the inner span
|
445
|
+
console.log()
|
446
|
+
var coverage_indicator_button = document.getElementById('coverage-indicator-'+hgnc_id+'-button');
|
447
|
+
var coverage_indicator_icon = document.getElementById('coverage-indicator-'+hgnc_id+'-icon');
|
448
|
+
var coverage_indicator_text = document.getElementById('coverage-indicator-'+hgnc_id+'-text');
|
449
|
+
|
450
|
+
// this is the outer, button span
|
451
|
+
coverage_indicator_button.classList.remove('btn-info');
|
452
|
+
// this is the inner, icon span
|
453
|
+
coverage_indicator_icon.classList.remove('blink_me','fa-circle-question');
|
454
|
+
|
455
|
+
if (has_complete_coverage) {
|
456
|
+
coverage_indicator_button.classList.add('btn-success');
|
457
|
+
coverage_indicator_button.setAttribute('data-bs-original-title', "Chanjo2 coverage is at 100% completeness.");
|
458
|
+
coverage_indicator_icon.classList.add('fa-circle-check');
|
459
|
+
coverage_indicator_text.textContent = "Complete"
|
460
|
+
} else {
|
461
|
+
coverage_indicator_button.classList.add('btn-warning');
|
462
|
+
coverage_indicator_button.setAttribute('data-bs-original-title', "Note that Chanjo2 coverage is below 100% completeness.");
|
463
|
+
coverage_indicator_icon.classList.add('fa-triangle-exclamation');
|
464
|
+
coverage_indicator_text.textContent = "Incomplete"
|
465
|
+
}
|
466
|
+
}
|
467
|
+
}).fail(function() {
|
468
|
+
const complete_coverage_indicator_elements = document.getElementsByClassName("complete-coverage-indicator");
|
469
|
+
for(let complete_coverage_indicator of complete_coverage_indicator_elements) {
|
470
|
+
complete_coverage_indicator.style.display = "none"
|
471
|
+
}
|
472
|
+
});
|
473
|
+
};
|
474
|
+
|
475
|
+
$( window ).on( "load", function() { update_gene_has_full_coverage(); })
|
435
476
|
</script>
|
436
477
|
{% endblock %}
|
@@ -28,6 +28,7 @@ from scout.server.blueprints.variant.controllers import (
|
|
28
28
|
)
|
29
29
|
from scout.server.blueprints.variant.controllers import evaluation as evaluation_controller
|
30
30
|
from scout.server.blueprints.variant.controllers import (
|
31
|
+
get_gene_has_full_coverage,
|
31
32
|
observations,
|
32
33
|
str_variant_reviewer,
|
33
34
|
)
|
@@ -423,6 +424,17 @@ def acmg():
|
|
423
424
|
return jsonify({"classification": classification, "conflicts": acmg_conflicts, **acmg_bayesian})
|
424
425
|
|
425
426
|
|
427
|
+
@variant_bp.route("/api/v1/gene_has_full_coverage/<institute_id>/<case_name>/<variant_id>/")
|
428
|
+
def gene_has_full_coverage(institute_id, case_name, variant_id):
|
429
|
+
"""Check if gene has full coverage using chanjo2 endpoint"""
|
430
|
+
institute_obj, case_obj = institute_and_case(store, institute_id, case_name)
|
431
|
+
variant_obj = store.variant(variant_id)
|
432
|
+
|
433
|
+
return jsonify(
|
434
|
+
{"gene_has_full_coverage": get_gene_has_full_coverage(institute_obj, case_obj, variant_obj)}
|
435
|
+
)
|
436
|
+
|
437
|
+
|
426
438
|
@variant_bp.route("/ccv_evaluations/<evaluation_id>", methods=["GET", "POST"])
|
427
439
|
@templated("variant/ccv.html")
|
428
440
|
def ccv_evaluation(evaluation_id):
|
@@ -49,7 +49,12 @@ from scout.server.utils import (
|
|
49
49
|
user_institutes,
|
50
50
|
)
|
51
51
|
|
52
|
-
from .forms import
|
52
|
+
from .forms import (
|
53
|
+
FILTERSFORMCLASS,
|
54
|
+
CancerSvFiltersForm,
|
55
|
+
FusionFiltersForm,
|
56
|
+
SvFiltersForm,
|
57
|
+
)
|
53
58
|
from .utils import update_case_panels
|
54
59
|
|
55
60
|
NUM = re.compile(r"\d+")
|
@@ -111,6 +116,13 @@ def populate_institute_soft_filters(form, institute_obj):
|
|
111
116
|
form.institute_soft_filters.data = ",".join(institute_obj["soft_filters"])
|
112
117
|
|
113
118
|
|
119
|
+
def set_overlapping_variants(variant_obj: dict):
|
120
|
+
"""Define DNA or WTS variants that are overlapping with a gene of a variant."""
|
121
|
+
overlapping_variants, overlapping_outliers = store.hgnc_overlapping(variant_obj)
|
122
|
+
variant_obj["overlapping"] = list(overlapping_variants) or None
|
123
|
+
variant_obj["overlapping_outliers"] = list(overlapping_outliers) or None
|
124
|
+
|
125
|
+
|
114
126
|
def variants(
|
115
127
|
store,
|
116
128
|
institute_obj,
|
@@ -137,8 +149,7 @@ def variants(
|
|
137
149
|
|
138
150
|
variants = []
|
139
151
|
for variant_obj in variant_res:
|
140
|
-
|
141
|
-
variant_obj["overlapping"] = overlapping_svs or None
|
152
|
+
set_overlapping_variants(variant_obj)
|
142
153
|
|
143
154
|
evaluations = []
|
144
155
|
is_research = variant_obj["variant_type"] == "research"
|
@@ -233,6 +244,8 @@ def sv_variants(store, institute_obj, case_obj, variants_query, variant_count, p
|
|
233
244
|
case_dismissed_vars = store.case_dismissed_variants(institute_obj, case_obj)
|
234
245
|
|
235
246
|
for variant_obj in variants_query.skip(skip_count).limit(per_page):
|
247
|
+
set_overlapping_variants(variant_obj)
|
248
|
+
|
236
249
|
# show previous classifications for research variants
|
237
250
|
clinical_var_obj = variant_obj
|
238
251
|
if variant_obj["variant_type"] == "research":
|
@@ -279,6 +292,8 @@ def mei_variants(
|
|
279
292
|
case_dismissed_vars = store.case_dismissed_variants(institute_obj, case_obj)
|
280
293
|
|
281
294
|
for variant_obj in variants_query.skip(skip_count).limit(per_page):
|
295
|
+
set_overlapping_variants(variant_obj)
|
296
|
+
|
282
297
|
# show previous classifications for research variants
|
283
298
|
clinical_var_obj = variant_obj
|
284
299
|
if variant_obj["variant_type"] == "research":
|
@@ -1448,6 +1463,8 @@ def cancer_variants(store, institute_id, case_name, variants_query, variant_coun
|
|
1448
1463
|
variant_obj["second_rep_gene"] = secondary_gene
|
1449
1464
|
variant_obj["clinical_assessments"] = get_manual_assessments(variant_obj)
|
1450
1465
|
|
1466
|
+
set_overlapping_variants(variant_obj)
|
1467
|
+
|
1451
1468
|
evaluations = []
|
1452
1469
|
# Get previous ClinGen-CGC-VIGG evaluations of the variant from other cases
|
1453
1470
|
for evaluation_obj in store.get_ccv_evaluations(variant_obj):
|
@@ -28,6 +28,7 @@ from scout.constants import (
|
|
28
28
|
CLINSIG_MAP,
|
29
29
|
FEATURE_TYPES,
|
30
30
|
GENETIC_MODELS,
|
31
|
+
ONC_CLNSIG,
|
31
32
|
OUTLIER_TYPES,
|
32
33
|
SO_TERMS,
|
33
34
|
SPIDEX_LEVELS,
|
@@ -38,6 +39,7 @@ from scout.constants import (
|
|
38
39
|
LOG = logging.getLogger(__name__)
|
39
40
|
|
40
41
|
CLINSIG_OPTIONS = list(CLINSIG_MAP.items())
|
42
|
+
ONC_CLNSIG_OPTIONS = [(term.lower().replace(" ", "_"), term) for term in ONC_CLNSIG]
|
41
43
|
FUNC_ANNOTATIONS = [(term, term.replace("_", " ")) for term in SO_TERMS]
|
42
44
|
REGION_ANNOTATIONS = [(term, term.replace("_", " ")) for term in FEATURE_TYPES]
|
43
45
|
SV_TYPE_CHOICES = [(term, term.replace("_", " ").upper()) for term in SV_TYPES]
|
@@ -112,8 +114,9 @@ class VariantFiltersForm(FlaskForm):
|
|
112
114
|
compound_rank_score = IntegerField("Compound rank score")
|
113
115
|
compound_follow_filter = BooleanField("Compounds follow filter")
|
114
116
|
cadd_inclusive = BooleanField("CADD inclusive")
|
115
|
-
clinsig = NonValidatingSelectMultipleField("ClinVar
|
117
|
+
clinsig = NonValidatingSelectMultipleField("ClinVar significance", choices=CLINSIG_OPTIONS)
|
116
118
|
clinsig_exclude = BooleanField("Exclude")
|
119
|
+
clinvar_tag = BooleanField("ClinVar hits only")
|
117
120
|
prioritise_clinvar = BooleanField("Prioritise ClinVar")
|
118
121
|
|
119
122
|
gnomad_frequency = BetterDecimalField("gnomadAF", validators=[validators.Optional()])
|
@@ -183,7 +186,6 @@ class FiltersForm(VariantFiltersForm):
|
|
183
186
|
spidex_human = SelectMultipleField("SPIDEX", choices=SPIDEX_CHOICES)
|
184
187
|
|
185
188
|
clinical_filter = SubmitField(label="Clinical filter")
|
186
|
-
clinvar_tag = BooleanField("ClinVar hits only")
|
187
189
|
|
188
190
|
# polymorphic constant base for clinical filter
|
189
191
|
clinical_filter_base = CLINICAL_FILTER_BASE
|
@@ -196,8 +198,11 @@ class CancerFiltersForm(VariantFiltersForm):
|
|
196
198
|
alt_count = IntegerField("Min alt count", validators=[validators.Optional()])
|
197
199
|
control_frequency = BetterDecimalField("Normal alt AF <", validators=[validators.Optional()])
|
198
200
|
tumor_frequency = BetterDecimalField("Tumor alt AF >", validators=[validators.Optional()])
|
199
|
-
clinvar_tag = BooleanField("ClinVar hits only")
|
200
201
|
cosmic_tag = BooleanField("Cosmic hits")
|
202
|
+
clinsig_onc = NonValidatingSelectMultipleField(
|
203
|
+
"ClinVar oncogenicity", choices=ONC_CLNSIG_OPTIONS
|
204
|
+
)
|
205
|
+
clinsig_onc_exclude = BooleanField("Exclude")
|
201
206
|
mvl_tag = BooleanField("Managed Variants hits")
|
202
207
|
local_obs_cancer_somatic_old = IntegerField(
|
203
208
|
"Local somatic obs. (archive)", validators=[validators.Optional()]
|
@@ -1,4 +1,5 @@
|
|
1
1
|
{% from "variant/gene_disease_relations.html" import inheritance_badge %}
|
2
|
+
{% from "variants/utils.html" import compounds_table, overlapping_tooltip_table %}
|
2
3
|
|
3
4
|
{% macro variant_gene_symbols_cell(variant, inherit_palette) %}
|
4
5
|
<div class="d-flex justify-content-between align-items-center">
|
@@ -419,3 +420,36 @@
|
|
419
420
|
<span class="text-body">N/A</span>
|
420
421
|
{% endif %}
|
421
422
|
{% endmacro %}
|
423
|
+
|
424
|
+
|
425
|
+
{% macro overlapping_cell(variant, institute, case) %}
|
426
|
+
{% if variant.compounds %}
|
427
|
+
{% set ns=namespace(show_compounds=false) %}
|
428
|
+
{% for compound in variant.compounds if not compound.is_dismissed %}
|
429
|
+
{% set ns.show_compounds = true %}
|
430
|
+
{% endfor %}
|
431
|
+
{% if ns.show_compounds %}
|
432
|
+
<a href="#" class="badge bg-primary text-white" data-bs-toggle="popover" data-bs-placement="left"
|
433
|
+
data-bs-html="true" data-bs-trigger="hover click"
|
434
|
+
data-bs-content="{{ compounds_table(institute, case, variant.compounds[:20], is_popover=true) }}">Compounds</a>
|
435
|
+
{% endif %}
|
436
|
+
{% endif %}
|
437
|
+
|
438
|
+
{% if variant.overlapping %}
|
439
|
+
<a href="#" class="badge bg-warning" data-bs-toggle="popover" data-bs-placement="left"
|
440
|
+
data-bs-html="true" data-bs-trigger="hover click"
|
441
|
+
{% if variant.category == "SNV" %}
|
442
|
+
data-bs-content="<div>Gene overlapping non-SNVs</div>
|
443
|
+
{{ overlapping_tooltip_table(institute, case, variant.overlapping[:20]) }}">Gene overlapping (DNA)</a>
|
444
|
+
{% else %}
|
445
|
+
data-bs-content="<div>Gene overlapping variants</div>
|
446
|
+
{{ overlapping_tooltip_table(institute, case, variant.overlapping[:40]) }}">Gene overlapping (DNA)</a>
|
447
|
+
{% endif %}
|
448
|
+
{% endif %}
|
449
|
+
|
450
|
+
{% if variant.overlapping_outliers %}
|
451
|
+
<a href="#" class="badge bg-success text-white" data-bs-toggle="popover" data-bs-placement="left"
|
452
|
+
data-bs-html="true" data-bs-trigger="hover click" data-bs-content="<div>Gene overlapping WTS outliers</div>
|
453
|
+
{{ overlapping_tooltip_table(institute, case, variant.overlapping_outliers[:40]) }}">Gene overlapping (WTS)</a>
|
454
|
+
{% endif %}
|
455
|
+
{% endmacro %}
|
@@ -41,25 +41,23 @@
|
|
41
41
|
|
42
42
|
{% macro other_tiered_variants(variant) %}
|
43
43
|
{% if variant.matching_tiered %}
|
44
|
-
<span class="
|
45
|
-
|
44
|
+
<span class="badge bg-dark" data-bs-toggle="popover" data-bs-html="true" data-bs-trigger="hover click"
|
45
|
+
data-bs-title="Previously <b>T</b>iered as"
|
46
|
+
data-bs-content="
|
46
47
|
{% for tier, tiered_info in variant.matching_tiered.items() %}
|
47
|
-
<span class='badge bg-{{tiered_info.
|
48
|
-
{% endfor %}
|
49
|
-
"
|
50
|
-
data-original-title="Previously tiered as">T</span>
|
48
|
+
<span class='badge bg-{{tiered_info.label_class}}'>{{tier}} ({{tiered_info.links|length}}x)</span>
|
49
|
+
{% endfor %}">T</span>
|
51
50
|
{% endif %} <!-- end of if variant.matching_tiered -->
|
52
51
|
{% endmacro %}
|
53
52
|
|
54
53
|
{% macro matching_manual_rank(variant) %}
|
55
54
|
{% if variant.matching_ranked %}
|
56
|
-
<span class="
|
57
|
-
data-bs-
|
55
|
+
<span class="badge bg-dark" data-bs-toggle="popover" data-bs-html="true" data-bs-trigger="hover click"
|
56
|
+
data-bs-title="Previously <b>M</b>anually ranked as"
|
57
|
+
data-bs-content="
|
58
58
|
{% for manual_rank, manual_rank_info in variant.matching_ranked.items() %}
|
59
|
-
<div>{{manual_rank_info.label}} - {{manual_rank_info.description}} ({{manual_rank_info.links|length}}x)</div>
|
60
|
-
{% endfor %}
|
61
|
-
"
|
62
|
-
data-original-title="Previously ranked as">M</span>
|
59
|
+
<div><span class='badge bg-{{ manual_rank_info.label_class }}'>{{manual_rank_info.label}}</span> - {{manual_rank_info.description}} ({{manual_rank_info.links|length}}x)</div>
|
60
|
+
{% endfor %}">M</span>
|
63
61
|
{% endif %}
|
64
62
|
{% endmacro %}
|
65
63
|
|
@@ -120,7 +118,7 @@
|
|
120
118
|
{% macro group_assessments_badge(variant) %}
|
121
119
|
{% if variant.group_assessments %}
|
122
120
|
{% for assessment in (variant.group_assessments or []) %}
|
123
|
-
<span class="badge bg-{{ assessment.display_class }}" data-bs-html="true" data-bs-toggle="tooltip" data-bs-placement="right"
|
121
|
+
<span class="badge bg-{{ assessment.display_class }}<b>" data-bs-html="true" data-bs-toggle="tooltip" data-bs-placement="right"
|
124
122
|
title="Cohort {{ assessment.title }}">
|
125
123
|
{{ assessment.label }}</span>
|
126
124
|
{% endfor %}
|
@@ -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, overlapping_cell, 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
|
@@ -57,16 +57,17 @@ onsubmit="return validateForm()">
|
|
57
57
|
<thead class="table-light thead">
|
58
58
|
<tr>
|
59
59
|
<th style="width:3%"></th>
|
60
|
-
<th>Rank</th>
|
61
|
-
<th>Score</th>
|
60
|
+
<th title="Rank position">Rank</th>
|
61
|
+
<th title="Rank score">Score</th>
|
62
62
|
<th>Type</th>
|
63
63
|
<th style="width:18%">Element</th>
|
64
|
-
<th>Chr</th>
|
64
|
+
<th title="Chromosome">Chr</th>
|
65
65
|
<th style="width:9%">Start loc</th>
|
66
66
|
<th>Frequency</th>
|
67
67
|
<th>Gene(s)</th>
|
68
|
-
<th>Function</th>
|
69
|
-
|
68
|
+
<th title="Functional annotation">Function</th>
|
69
|
+
<th title="Gene overlapping variants">Overlap</th>
|
70
|
+
</tr>
|
70
71
|
</thead>
|
71
72
|
<tbody>
|
72
73
|
{% for variant in variants %}
|
@@ -113,6 +114,7 @@ onsubmit="return validateForm()">
|
|
113
114
|
<td style="word-wrap:break-word;">
|
114
115
|
{{ variant_funct_anno_cell(variant) }}
|
115
116
|
</td>
|
117
|
+
<td>{{ overlapping_cell(variant, institute, case) }}</td>
|
116
118
|
</tr>
|
117
119
|
{% endmacro %}
|
118
120
|
|
@@ -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, callers_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 %}
|
3
|
+
{% from "variants/components.html" import external_scripts, external_stylesheets, frequency_cell_general, observed_cell_general, overlapping_cell, 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
|
@@ -57,18 +57,19 @@ onsubmit="return validateForm()">
|
|
57
57
|
<thead class="table-light thead">
|
58
58
|
<tr>
|
59
59
|
<th style="width:3%"></th>
|
60
|
-
<th>Rank</th>
|
61
|
-
<th>Score</th>
|
60
|
+
<th title="Rank position">Rank</th>
|
61
|
+
<th title="Rank score">Score</th>
|
62
62
|
<th>Callers</th>
|
63
63
|
<th>Type</th>
|
64
|
-
<th>Chr</th>
|
64
|
+
<th title="Chromosome">Chr</th>
|
65
65
|
<th>Start</th>
|
66
66
|
<th>End</th>
|
67
67
|
<th>Length</th>
|
68
|
-
<th>Pop Freq</th>
|
69
|
-
<th>Observed</th>
|
68
|
+
<th title="Population Frequency">Pop Freq</th>
|
69
|
+
<th title="Observed database matches">Observed</th>
|
70
70
|
<th>Gene(s)</th>
|
71
|
-
<th>Function</th>
|
71
|
+
<th title="Functional annotation">Function</th>
|
72
|
+
<th title="Gene overlapping variants">Overlap</th>
|
72
73
|
</tr>
|
73
74
|
</thead>
|
74
75
|
<tbody>
|
@@ -121,6 +122,7 @@ onsubmit="return validateForm()">
|
|
121
122
|
<td style="word-wrap:break-word;">
|
122
123
|
{{ variant_funct_anno_cell(variant) }}
|
123
124
|
</td>
|
125
|
+
<td>{{ overlapping_cell(variant, institute, case) }}</td>
|
124
126
|
</tr>
|
125
127
|
{% endmacro %}
|
126
128
|
|