scout-browser 4.79.1__py3-none-any.whl → 4.81__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/variant.py +2 -2
- scout/constants/__init__.py +3 -0
- scout/constants/clinvar.py +3 -0
- scout/constants/indexes.py +14 -12
- scout/constants/variants_export.py +11 -0
- scout/models/case/case_loading_models.py +45 -23
- scout/models/clinvar.py +1 -0
- scout/parse/variant/variant.py +27 -23
- scout/server/blueprints/api/views.py +12 -0
- scout/server/blueprints/cases/controllers.py +72 -6
- scout/server/blueprints/cases/templates/cases/case.html +1 -22
- scout/server/blueprints/cases/templates/cases/case_bionano.html +2 -0
- scout/server/blueprints/cases/templates/cases/case_report.html +135 -129
- scout/server/blueprints/cases/templates/cases/case_sma.html +2 -0
- scout/server/blueprints/cases/templates/cases/collapsible_actionbar.html +12 -2
- scout/server/blueprints/cases/templates/cases/gene_panel.html +45 -22
- scout/server/blueprints/cases/templates/cases/utils.html +52 -14
- scout/server/blueprints/cases/views.py +22 -0
- scout/server/blueprints/clinvar/controllers.py +2 -0
- scout/server/blueprints/clinvar/form.py +5 -0
- scout/server/blueprints/clinvar/templates/clinvar/multistep_add_variant.html +30 -5
- scout/server/blueprints/diagnoses/templates/diagnoses/diagnoses.html +1 -1
- scout/server/blueprints/institutes/static/select2_darktheme.css +62 -0
- scout/server/blueprints/institutes/templates/overview/institute_settings.html +1 -1
- scout/server/blueprints/panels/templates/panels/panel.html +15 -1
- scout/server/blueprints/panels/templates/panels/panel_pdf_case_hits.html +2 -2
- scout/server/blueprints/panels/templates/panels/panel_pdf_simple.html +3 -3
- scout/server/blueprints/panels/views.py +5 -1
- scout/server/blueprints/variant/controllers.py +5 -2
- scout/server/blueprints/variant/templates/variant/variant_details.html +32 -20
- scout/server/blueprints/variants/controllers.py +179 -93
- scout/server/blueprints/variants/templates/variants/components.html +5 -4
- scout/server/blueprints/variants/templates/variants/fusion-variants.html +1 -1
- scout/server/blueprints/variants/views.py +30 -15
- scout/server/config.py +3 -0
- scout/server/templates/report_base.html +3 -3
- scout/server/templates/utils.html +68 -38
- scout/server/utils.py +25 -3
- {scout_browser-4.79.1.dist-info → scout_browser-4.81.dist-info}/METADATA +1 -1
- {scout_browser-4.79.1.dist-info → scout_browser-4.81.dist-info}/RECORD +45 -45
- scout/server/blueprints/cases/templates/cases/clinvar.html +0 -48
- {scout_browser-4.79.1.dist-info → scout_browser-4.81.dist-info}/LICENSE +0 -0
- {scout_browser-4.79.1.dist-info → scout_browser-4.81.dist-info}/WHEEL +0 -0
- {scout_browser-4.79.1.dist-info → scout_browser-4.81.dist-info}/entry_points.txt +0 -0
- {scout_browser-4.79.1.dist-info → scout_browser-4.81.dist-info}/top_level.txt +0 -0
@@ -83,8 +83,18 @@
|
|
83
83
|
</div>
|
84
84
|
</div>
|
85
85
|
|
86
|
-
<!-- If connected to a chanjo instance, display coverage report -->
|
87
|
-
{% if
|
86
|
+
<!-- If connected to a chanjo or chanjo2 instance, display coverage report -->
|
87
|
+
{% if case.chanjo2_coverage %}
|
88
|
+
<div href="#" class="bg-dark list-group-item text-white">
|
89
|
+
<div class="d-flex flex-row flex-fill bd-highlight">
|
90
|
+
<span class="menu-collapsed">Coverage (chanjo2)</span>
|
91
|
+
<a href="{{ url_for('cases.chanjo2_coverage_report', institute_id=institute._id, case_name=case.display_name, panel_name=case.panel_names|join(', '), report_type='report') }}" target="_blank" rel="noopener">
|
92
|
+
<span class="fa fa-link"></span>
|
93
|
+
</a>
|
94
|
+
</div>
|
95
|
+
</div>
|
96
|
+
{% endif %}
|
97
|
+
{% if case.chanjo_coverage %}
|
88
98
|
<div href="#" class="bg-dark list-group-item text-white">
|
89
99
|
<div class="d-flex flex-row flex-fill bd-highlight">
|
90
100
|
<span class="menu-collapsed">Coverage</span>
|
@@ -7,6 +7,7 @@
|
|
7
7
|
<thead class="table-light thead">
|
8
8
|
<tr style="cursor: pointer; white-space: nowrap">
|
9
9
|
<th>Panel <i class="fas fa-sort" data-bs-toggle="tooltip" title="Sort by gene panel name"></i></th>
|
10
|
+
<th >Default <i class="fas fa-sort" data-bs-toggle="tooltip" title="Sort by default panel"></i></th>
|
10
11
|
<th>Version <i class="fas fa-sort" data-bs-toggle="tooltip" title="Sort by panel version"></i></th>
|
11
12
|
<th>Genes <i class="fas fa-sort" data-bs-toggle="tooltip" title="Sort by number of genes"></i></th>
|
12
13
|
</tr>
|
@@ -21,8 +22,10 @@
|
|
21
22
|
<span class="badge bg-danger">Removed</span>
|
22
23
|
{% endif %}
|
23
24
|
</a>
|
25
|
+
</td>
|
26
|
+
<td >
|
24
27
|
{% if panel.is_default %}
|
25
|
-
<span class="badge bg-dark
|
28
|
+
<span class="badge bg-dark">Default</span>
|
26
29
|
{% endif %}
|
27
30
|
</td>
|
28
31
|
<td>{{ panel.version }} <small class="text">({{ panel.updated_at.date() }})</small></td>
|
@@ -91,21 +94,6 @@
|
|
91
94
|
{% endif %}
|
92
95
|
)
|
93
96
|
{% if case.dynamic_gene_list_edited %} <span class="text-danger ml-3"> (edited) </span> {% endif %}
|
94
|
-
{% if case.track != 'cancer' and config.SQLALCHEMY_DATABASE_URI and case.dynamic_gene_list|length > 0 %}
|
95
|
-
<span class="pull-right">
|
96
|
-
<a href="#" onclick="document.getElementById('hpo-report-form').submit();">Coverage report</a>
|
97
|
-
<form id="hpo-report-form" action="{{ url_for('report.report', sample_id=case.individuals|map(attribute='individual_id')|list, panel_name="HPO panel", level=institute.coverage_cutoff) }}" method="POST" target="_blank">
|
98
|
-
<input type="hidden" name="gene_ids" value="{{ case.dynamic_gene_list|map(attribute='hgnc_id')|join(',') }}">
|
99
|
-
</form>
|
100
|
-
</span>
|
101
|
-
<span class="pull-right"> </span>
|
102
|
-
<span class="pull-right">
|
103
|
-
<a href="#" onclick="document.getElementById('hpo-overview-form').submit();">Coverage overview</a>
|
104
|
-
<form id="hpo-overview-form" action="{{ url_for('report.genes', sample_id=case.individuals|map(attribute='individual_id')|list, panel_name="HPO panel", level=institute.coverage_cutoff) }}" method="POST" target="_blank">
|
105
|
-
<input type="hidden" name="gene_ids" value="{{ case.dynamic_gene_list|map(attribute='hgnc_id')|join(',') }}">
|
106
|
-
</form>
|
107
|
-
</span>
|
108
|
-
{% endif %}
|
109
97
|
</h6>
|
110
98
|
</div>
|
111
99
|
|
@@ -142,8 +130,8 @@
|
|
142
130
|
</div>
|
143
131
|
</div>
|
144
132
|
|
145
|
-
<div
|
146
|
-
<div class="row">
|
133
|
+
<div>
|
134
|
+
<div class="row"> <!-- Show variants in dynamic gene list -->
|
147
135
|
<form action="{{ url_for('cases.update_clinical_filter_hpo', institute_id=institute._id, case_name=case.display_name)+'#hpo_clinical_filter' }}" method="POST">
|
148
136
|
<div class="form-check form-switch">
|
149
137
|
<input type="checkbox" class="form-check-input" id="hpo_clinical_filter" onChange="this.form.submit()" name="hpo_clinical_filter"{% if case.hpo_clinical_filter %}checked{% endif %}>
|
@@ -207,11 +195,46 @@
|
|
207
195
|
{% endif %}
|
208
196
|
</div>
|
209
197
|
</div>
|
210
|
-
|
198
|
+
{% if case.chanjo_coverage or case.chanjo2_coverage and case.dynamic_gene_list|length > 0 %}
|
199
|
+
<div class="row mt-1">
|
200
|
+
<div class="btn-group btn-group-sm">
|
201
|
+
{% if case.chanjo_coverage %}
|
202
|
+
<a class="btn btn-secondary btn-sm text-white" href="#section" onClick="document.getElementById('hpo-report-form').submit();" >Coverage report</a>
|
203
|
+
<form id="hpo-report-form" action="{{ url_for('report.report', sample_id=case.individuals|map(attribute='individual_id')|list, panel_name='HPO panel', level=institute.coverage_cutoff) }}" method="POST" target="_blank">
|
204
|
+
<input type="hidden" name="gene_ids" value="{{ case.dynamic_gene_list|map(attribute='hgnc_id')|join(',') }}">
|
205
|
+
</form>
|
206
|
+
|
207
|
+
<a class="btn btn-secondary btn-sm text-white" href="#section" onClick="document.getElementById('hpo-overview-form').submit();" >Coverage overview</a>
|
208
|
+
<form id="hpo-overview-form" action="{{ url_for('report.genes', sample_id=case.individuals|map(attribute='individual_id')|list, panel_name='HPO panel', level=institute.coverage_cutoff) }}" method="POST" target="_blank">
|
209
|
+
<input type="hidden" name="gene_ids" value="{{ case.dynamic_gene_list|map(attribute='hgnc_id')|join(',') }}">
|
210
|
+
</form>
|
211
|
+
{% endif %}
|
212
|
+
|
213
|
+
{% if case.chanjo2_coverage %}
|
214
|
+
<a class="btn btn-secondary btn-sm text-white"
|
215
|
+
href="{{ url_for('cases.chanjo2_coverage_report', institute_id=institute._id,
|
216
|
+
case_name=case.display_name, panel_name='HPO Panel', report_type='report') }}" target="_blank" rel="noopener">
|
217
|
+
Coverage report (Chanjo2)
|
218
|
+
</a>
|
219
|
+
|
220
|
+
<a class="btn btn-secondary btn-sm text-white"
|
221
|
+
href="{{ url_for('cases.chanjo2_coverage_report', institute_id=institute._id,
|
222
|
+
case_name=case.display_name, panel_name='HPO Panel', report_type='overview') }}" target="_blank" rel="noopener">
|
223
|
+
Coverage overview (Chanjo2)
|
224
|
+
</a>
|
225
|
+
{% endif %}
|
226
|
+
|
227
|
+
</div>
|
228
|
+
</div>
|
229
|
+
{% endif %} <!-- End of if case.chanjo_coverage or case.chanjo2_coverage -->
|
230
|
+
|
231
|
+
<div class="row mt-1">
|
232
|
+
<div class="btn-group btn-group-sm"> <!-- Download genes in HPO gene panel -->
|
233
|
+
<a class="btn btn-sm btn-primary text-white" href="{{ url_for('cases.download_hpo_genes', institute_id=institute._id, case_name=case.display_name, category="clinical") }}" download><span class="fa fa-download text-white" aria-hidden="true"></span> Clinical HPO gene panel</a>
|
234
|
+
<a class="btn btn-sm btn-primary text-white" href="{{ url_for('cases.download_hpo_genes', institute_id=institute._id, case_name=case.display_name, category="research") }}" download><span class="fa fa-download text-white" aria-hidden="true"></span> Research HPO gene panel</a>
|
235
|
+
</div>
|
236
|
+
</div>
|
211
237
|
|
212
|
-
<div class="btn-group d-flex justify-content-center mt-2"> <!-- Download genes in HPO gene panel -->
|
213
|
-
<a class="btn btn-sm btn-primary mt-1 text-white" href="{{ url_for('cases.download_hpo_genes', institute_id=institute._id, case_name=case.display_name, category="clinical") }}" download><span class="fa fa-download text-white" aria-hidden="true"></span> Clinical HPO gene panel</a>
|
214
|
-
<a class="btn btn-sm btn-primary mt-1 text-white" href="{{ url_for('cases.download_hpo_genes', institute_id=institute._id, case_name=case.display_name, category="research") }}" download><span class="fa fa-download text-white" aria-hidden="true"></span> Research HPO gene panel</a>
|
215
238
|
</div>
|
216
239
|
|
217
240
|
{% endif %}
|
@@ -1,4 +1,5 @@
|
|
1
1
|
{% from "variants/indicators.html" import clinical_assessments_badge, research_assessments_badge %}
|
2
|
+
{% from "clinvar/clinvar_howto.html" import clinvar_howto_modal %}
|
2
3
|
|
3
4
|
{% macro matchmaker_modal(institute, case, suspects, mme_nodes ) %}
|
4
5
|
<div class="modal fade" id="matchmaker_modal" tabindex="-1" role="dialog" aria-hidden="true">
|
@@ -379,20 +380,21 @@
|
|
379
380
|
{% endif %}
|
380
381
|
</div>
|
381
382
|
</div>
|
382
|
-
<div style="max-height:300px; overflow-y: scroll;">
|
383
|
+
<div class="mb-3" style="max-height:300px; overflow-y: scroll;">
|
383
384
|
<ul class="list-group">
|
384
385
|
{% for variant in causatives %}
|
385
386
|
<li class="list-group-item list-group-item-action">
|
386
387
|
{% if variant._id %}
|
387
388
|
{% do already_displayed_variant_ids.append( variant._id ) %}
|
388
389
|
<div class="row">
|
389
|
-
<div class="col
|
390
|
+
<div class="col">
|
391
|
+
<i class="far fa-check-circle"></i>
|
390
392
|
{{ pretty_link_variant(variant, case) }}
|
391
393
|
{{ variant_validation_badge(variant) }}
|
392
394
|
{{ clinical_assessments_badge(variant) }}
|
393
395
|
{{ tumor_allele_freq(variant) }}
|
394
396
|
</div>
|
395
|
-
<div class="col-
|
397
|
+
<div class="col-auto" style="width:fit-content;">
|
396
398
|
{{ remove_form(url_for('cases.mark_causative',
|
397
399
|
institute_id=institute._id,
|
398
400
|
case_name=case.display_name,
|
@@ -415,7 +417,7 @@
|
|
415
417
|
{% if variant._id %}
|
416
418
|
{% do already_displayed_variant_ids.append(variant._id) %}
|
417
419
|
<div class="row">
|
418
|
-
<div class="col
|
420
|
+
<div class="col">
|
419
421
|
<i class="far fa-check-circle"></i>
|
420
422
|
{% if variant.category == "snv" %}
|
421
423
|
<a href="{{ url_for('variant.variant',
|
@@ -433,7 +435,7 @@
|
|
433
435
|
{% endif %}
|
434
436
|
</a>
|
435
437
|
</div>
|
436
|
-
<div class="col-2">
|
438
|
+
<div class="col-2" style="width:fit-content;">
|
437
439
|
{{ remove_form(url_for('cases.mark_causative',
|
438
440
|
institute_id=institute._id,
|
439
441
|
case_name=case.display_name,
|
@@ -444,6 +446,7 @@
|
|
444
446
|
</div>
|
445
447
|
<div class="row">
|
446
448
|
<div class="col-4">
|
449
|
+
<i class="far fa-check-circle" style="color:transparent; background-color:transparent"></i>
|
447
450
|
Diagnoses
|
448
451
|
</div>
|
449
452
|
<div class="col-8">
|
@@ -464,6 +467,7 @@
|
|
464
467
|
</div>
|
465
468
|
<div class="row">
|
466
469
|
<div class="col-4">
|
470
|
+
<i class="far fa-check-circle" style="color:transparent; background-color:transparent"></i>
|
467
471
|
HPO terms
|
468
472
|
</div>
|
469
473
|
<div class="col-8">
|
@@ -531,18 +535,18 @@
|
|
531
535
|
{% endmacro %}
|
532
536
|
|
533
537
|
{% macro suspects_list(suspects, institute, case, manual_rank_options, cancer_tier_options) %}
|
538
|
+
{{ clinvar_howto_modal() }}
|
534
539
|
<div class="card mt-3">
|
535
|
-
<div class="d-flex align-items-center" data-bs-toggle='tooltip' title="Displays all variants that
|
536
|
-
<h6><span class="fa fa-map-pin ms-3 mt-2"></span>
|
537
|
-
|
540
|
+
<div class="d-flex align-items-center" data-bs-toggle='tooltip' title="Displays all variants that have been pinned or included in a ClinVar submission for this case">
|
541
|
+
<h6><span class="fa fa-map-pin ms-3 mt-2"></span> Variants pinned ({{suspects|length}}) or included in a ClinVar submission({{ case.clinvar_variants.items()|length }}) <a data-bs-target="#howto" href="#" data-bs-toggle="modal">?</a></h6>
|
542
|
+
</div>
|
543
|
+
<div class="mb-3" style="max-height:300px; overflow-y: scroll;">
|
544
|
+
<ul class="list-group">
|
538
545
|
{% if not suspects|length %}
|
539
546
|
<span class="text-muted ms-3 mt-2">
|
540
547
|
<h6>No pinned variants</h6>
|
541
548
|
</span>
|
542
549
|
{% endif %}
|
543
|
-
</div>
|
544
|
-
<div style="max-height:300px; overflow-y: scroll;">
|
545
|
-
<ul class="list-group">
|
546
550
|
{% for variant in suspects %}
|
547
551
|
<li class="list-group-item">
|
548
552
|
{% if variant._id %}
|
@@ -560,7 +564,7 @@
|
|
560
564
|
</div>
|
561
565
|
</div>
|
562
566
|
</div>
|
563
|
-
<div class="col-
|
567
|
+
<div class="col-auto">
|
564
568
|
<form action="{{ url_for('cases.mark_validation',
|
565
569
|
institute_id=variant.institute,
|
566
570
|
case_name=case.display_name,
|
@@ -573,7 +577,8 @@
|
|
573
577
|
</select>
|
574
578
|
</form>
|
575
579
|
</div>
|
576
|
-
|
580
|
+
<div class="col">{{ clinvar_var_status(variant, case, institute) }}</div>
|
581
|
+
<div class="col-auto" style="width: fit-content;">
|
577
582
|
{{ remove_form(url_for('cases.pin_variant',
|
578
583
|
institute_id=institute._id,
|
579
584
|
case_name=case.display_name,
|
@@ -587,10 +592,43 @@
|
|
587
592
|
</li>
|
588
593
|
{% endfor %}
|
589
594
|
</ul>
|
590
|
-
|
595
|
+
{{ clinvar_vars_summary(suspects, case, institute) }}
|
596
|
+
</div>
|
591
597
|
</div>
|
592
598
|
{% endmacro %}
|
593
599
|
|
600
|
+
{% macro clinvar_var_status(variant, case, institute) %}
|
601
|
+
{% if variant._id and variant.category != 'str' %}
|
602
|
+
<form id="clinvar_submit" class="d-flex justify-content-center" action="{{ url_for('clinvar.clinvar_add_variant', institute_id=institute._id, case_name=case.display_name) }}" method="POST">
|
603
|
+
{% if case.clinvar_variants and variant._id in case.clinvar_variants.keys() %}
|
604
|
+
(included in ClinVar submission)
|
605
|
+
{% else %}
|
606
|
+
<button type="submit" name="var_id" value="{{variant._id}}" class="btn btn-secondary btn-sm" style="float: right;">Add to ClinVar submission</button>
|
607
|
+
{% endif %}
|
608
|
+
</form>
|
609
|
+
{% endif %}
|
610
|
+
{% endmacro %}
|
611
|
+
|
612
|
+
{% macro clinvar_vars_summary(suspects, case, institute) %}
|
613
|
+
{% if case.clinvar_variants %}
|
614
|
+
{% if case.clinvar_variants_not_in_suspects | length >0 %}
|
615
|
+
<div class="d-flex align-content-center flex-wrap">
|
616
|
+
<div class="col-auto d-flex align-items-center wrap">
|
617
|
+
<h6 class="m-2"> Variants present in a ClinVar submission, no longer pinned:</h6>
|
618
|
+
</div>
|
619
|
+
{% for entry in case.clinvar_variants_not_in_suspects %}
|
620
|
+
<div class="m-2">{{ pretty_link_variant(entry, case) }}</div>
|
621
|
+
{% endfor %}
|
622
|
+
</div>
|
623
|
+
{% endif %}
|
624
|
+
<div class="card-footer d-flex justify-content-center pb-0" style="background-color:inherit;">
|
625
|
+
<a href="{{url_for('clinvar.clinvar_submissions', institute_id=institute._id)}}"
|
626
|
+
class="btn btn-secondary btn-sm text-white mx-3" target="_blank" rel="noopener noreferrer">View ClinVar
|
627
|
+
submissions <i class="fas fa-arrow-circle-right"></i></a>
|
628
|
+
</div>
|
629
|
+
{% endif %}
|
630
|
+
{% endmacro %}
|
631
|
+
|
594
632
|
{% macro matching_causatives(other_causatives, institute, case, default=False) %}
|
595
633
|
<div data-bs-toggle='tooltip' class="panel-heading" title="If there are any variants in this case
|
596
634
|
that have been marked as causative in another case for this insitute. {% if default %}Variants in default panels for the case only.{% endif %}">
|
@@ -313,6 +313,28 @@ def pdf_case_report(institute_id, case_name):
|
|
313
313
|
)
|
314
314
|
|
315
315
|
|
316
|
+
@cases_bp.route("/<institute_id>/<case_name>/chanjo2_report/<report_type>", methods=["GET"])
|
317
|
+
def chanjo2_coverage_report(institute_id: str, case_name: str, report_type: str):
|
318
|
+
"""Return the HTML coverage report or coverage overview created by chanjo2."""
|
319
|
+
|
320
|
+
REPORT_TYPES = ["report", "overview"]
|
321
|
+
if report_type not in REPORT_TYPES:
|
322
|
+
flash(f"Wrong value for report_type parameter. Accepted values: {REPORT_TYPES}", "warning")
|
323
|
+
return redirect(request.referrer)
|
324
|
+
|
325
|
+
institute_obj, case_obj = institute_and_case(store, institute_id, case_name)
|
326
|
+
report_html_content: str = controllers.chanjo2_coverage_report_contents(
|
327
|
+
institute_obj=institute_obj,
|
328
|
+
case_obj=case_obj,
|
329
|
+
panel_name=request.args.get("panel_name"),
|
330
|
+
panel_id=request.args.get("panel_id"),
|
331
|
+
report_type=report_type,
|
332
|
+
)
|
333
|
+
if report_html_content is None:
|
334
|
+
return redirect(request.referrer)
|
335
|
+
return report_html_content
|
336
|
+
|
337
|
+
|
316
338
|
@cases_bp.route("/<institute_id>/<case_name>/mt_report", methods=["GET"])
|
317
339
|
def mt_report(institute_id, case_name):
|
318
340
|
institute_obj, case_obj = institute_and_case(store, institute_id, case_name)
|
@@ -245,6 +245,8 @@ def _set_conditions(clinvar_var: dict, form: ImmutableMultiDict):
|
|
245
245
|
clinvar_var["condition_id_value"] = ";".join(
|
246
246
|
[f"{condition_prefix}{condition_id}" for condition_id in form.getlist("conditions")]
|
247
247
|
)
|
248
|
+
if bool(form.get("multiple_condition_explanation")):
|
249
|
+
clinvar_var["explanation_for_multiple_conditions"] = form["multiple_condition_explanation"]
|
248
250
|
|
249
251
|
|
250
252
|
def parse_variant_form_fields(form):
|
@@ -26,6 +26,7 @@ from scout.constants import (
|
|
26
26
|
COLLECTION_METHOD,
|
27
27
|
CONDITION_PREFIX,
|
28
28
|
GERMLINE_CLASSIF_TERMS,
|
29
|
+
MULTIPLE_CONDITION_EXPLANATION,
|
29
30
|
)
|
30
31
|
|
31
32
|
LOG = logging.getLogger(__name__)
|
@@ -65,6 +66,10 @@ class ClinVarVariantForm(FlaskForm):
|
|
65
66
|
"Condition ID type", choices=[(key, key) for key, value in CONDITION_PREFIX.items()]
|
66
67
|
)
|
67
68
|
conditions = SelectMultipleField("Condition ID value, without prefix")
|
69
|
+
multiple_condition_explanation = SelectField(
|
70
|
+
"Explanation for multiple conditions",
|
71
|
+
choices=[(item, item) for item in MULTIPLE_CONDITION_EXPLANATION],
|
72
|
+
)
|
68
73
|
|
69
74
|
# Extra fields:
|
70
75
|
assertion_method = StringField("Assertion method", default=ASSERTION_METHOD)
|
@@ -232,7 +232,7 @@
|
|
232
232
|
|
233
233
|
<fieldset data-step="6">
|
234
234
|
<legend>Associated Conditions</legend>
|
235
|
-
<h3 class="fs-subtitle">The condition for which the variant is interpreted. Examples available at <a href="https://www.ncbi.nlm.nih.gov/clinvar/docs/spreadsheet/#condition" target="_blank" rel="noopener">ClinVar</a
|
235
|
+
<h3 class="fs-subtitle">The condition for which the variant is interpreted. Examples available at <a href="https://www.ncbi.nlm.nih.gov/clinvar/docs/spreadsheet/#condition" target="_blank" rel="noopener">ClinVar</a></h3>
|
236
236
|
|
237
237
|
<div class="row">
|
238
238
|
<div class="col-6" id="clinvar_condition_container">
|
@@ -249,7 +249,7 @@
|
|
249
249
|
{% endfor %}
|
250
250
|
</select>
|
251
251
|
<br><br>
|
252
|
-
{{variant_data.var_form.conditions.label(class="fw-bold, text-dark")}} <span class="text-danger" data-bs-toggle='tooltip' title="Required field. Include data from ONE DATABASE TYPE ONLY (i.e. only OMIM terms, only HPO terms etc)"><strong>*?</strong></span>
|
252
|
+
{{variant_data.var_form.conditions.label(class="fw-bold, text-dark")}} <span class="text-danger" data-bs-toggle='tooltip' title="Required field. Include data from ONE DATABASE TYPE ONLY (i.e. only OMIM terms, only HPO terms etc). If multiple conditions are submitted for a variant, this indicates that the variant was interpreted for the combination of conditions in the same individual(s). i.e. this variant causes both condition A and condition B in the same individual. This scenario is most common for a new disease or syndrome that does not yet have a name and is described by several clinical features. If you want to indicate that the variant has been interpreted for more than one condition, please submit these as separate records."><strong>*?</strong></span>
|
253
253
|
<select class="select2" id="condition_tags" name="conditions" multiple="true" style="width:100%;">
|
254
254
|
{% if variant_data.var_form.omim_terms.choices %}
|
255
255
|
{% for term, _ in variant_data.var_form.omim_terms.choices %}
|
@@ -265,6 +265,18 @@
|
|
265
265
|
{% endfor %}
|
266
266
|
{% endif %}
|
267
267
|
</select>
|
268
|
+
|
269
|
+
<div class="mt-3">
|
270
|
+
{{variant_data.var_form.multiple_condition_explanation.label(class="fw-bold, text-dark")}} <span class="text-danger" data-bs-toggle='tooltip' title="Required if you provide more than one condition ID."><strong>?</strong></span>
|
271
|
+
<select name="multiple_condition_explanation" id="multiple_condition_explanation" class="form-control, btn-secondary">
|
272
|
+
<option selected value>-</option>
|
273
|
+
{% for choice, _ in variant_data.var_form.multiple_condition_explanation.choices %}
|
274
|
+
<option value="{{choice}}">{{choice}}</option>
|
275
|
+
{% endfor %}
|
276
|
+
</select>
|
277
|
+
</div>
|
278
|
+
|
279
|
+
|
268
280
|
</div>
|
269
281
|
<div class="col-6">
|
270
282
|
{{ variant_data.var_form.omim_terms.label(class="fw-bold, text-dark" )}}<br>
|
@@ -360,7 +372,22 @@ var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
|
360
372
|
|
361
373
|
// Validates fields for conditions associated to a variant
|
362
374
|
function validateConditions(){
|
363
|
-
|
375
|
+
if ($("#condition_tags option:selected").length == 0) {
|
376
|
+
alert("Please provide at least one condition ID");
|
377
|
+
return false;
|
378
|
+
}
|
379
|
+
|
380
|
+
if ($("#condition_tags option:selected").length > 1 && $("#multiple_condition_explanation option:selected").text() === "-") {
|
381
|
+
alert("When multiple condition IDs are provided then an option for 'Explanation for multiple conditions' must be provided");
|
382
|
+
return false;
|
383
|
+
}
|
384
|
+
|
385
|
+
if ($("#condition_tags option:selected").length == 1 && $("#multiple_condition_explanation option:selected").text() !== "-") {
|
386
|
+
alert("Please deselect the selected option in 'Explanation for multiple conditions' since only one condition ID was provided.");
|
387
|
+
return false;
|
388
|
+
}
|
389
|
+
|
390
|
+
return true
|
364
391
|
}
|
365
392
|
|
366
393
|
var current_fs, next_fs, previous_fs; //fieldsets
|
@@ -383,12 +410,10 @@ $(".next").click(function(){
|
|
383
410
|
// check to see if the validator for the specific step we are on passed or not.
|
384
411
|
if(validationPassed == false){
|
385
412
|
// do not proceed
|
386
|
-
alert("Please fill in required field");
|
387
413
|
animating = false;
|
388
414
|
return;
|
389
415
|
}
|
390
416
|
|
391
|
-
|
392
417
|
next_fs = $(this).parent().next();
|
393
418
|
|
394
419
|
//activate next step on progressbar using the index of next_fs
|
@@ -83,7 +83,7 @@
|
|
83
83
|
<table id="super_secret_table_template" style="position: absolute; width: 1px; height: 1px; margin: -1px; border: 0; padding: 0; white-space: nowrap; clip-path: inset(100%); clip: rect(0 0 0 0); overflow: hidden;">
|
84
84
|
<tr id="diagnosis-row">
|
85
85
|
<td><a id="external-link" href="http://omim.org/entry/" target="_blank" rel=noopener ></a></td>
|
86
|
-
<td><a id="internal-link" href="{{ url_for('diagnoses.diagnosis',disease_id='')}}"><span class="fa fa-link"></span></a></td>
|
86
|
+
<td><a id="internal-link" href="{{ url_for('diagnoses.diagnosis',disease_id='')}}" target="_blank"><span class="fa fa-link"></span></a></td>
|
87
87
|
<td><span id="description" class="text-body"></span></td>
|
88
88
|
<td id="inheritance-container"><!-- inheritance-->
|
89
89
|
<span id="inheritance" class="badge bg-info m-1"></span>
|
@@ -0,0 +1,62 @@
|
|
1
|
+
/* Dark Theme compatibility for select2 multiselects*/
|
2
|
+
@media (prefers-color-scheme: dark) {
|
3
|
+
|
4
|
+
.select2-dropdown,
|
5
|
+
.select2-selection {
|
6
|
+
color: #b1b1b1 !important;
|
7
|
+
background-color: #222 !important;
|
8
|
+
border: 1px solid #515151 !important;
|
9
|
+
}
|
10
|
+
|
11
|
+
.select2-results__option {
|
12
|
+
display: flex;
|
13
|
+
gap: 0.5rem;
|
14
|
+
color: #b1b1b1 !important;
|
15
|
+
background-color: #222 !important;
|
16
|
+
}
|
17
|
+
|
18
|
+
.select2-results__option:hover,
|
19
|
+
.select2-results__option[aria-selected=true]:hover {
|
20
|
+
color: #dfe0e1 !important;
|
21
|
+
background-color: #343a40 !important;
|
22
|
+
}
|
23
|
+
|
24
|
+
.select2-selection__choice:has(> span:hover) {
|
25
|
+
opacity: 0.5;
|
26
|
+
}
|
27
|
+
|
28
|
+
/* Filters adjusts color of svg used as remove-button for selected options */
|
29
|
+
.select2-selection__choice__remove:first-child {
|
30
|
+
background-color: transparent !important;
|
31
|
+
filter: brightness(70) saturate(0%);
|
32
|
+
}
|
33
|
+
|
34
|
+
.select2-selection__choice__remove:hover {
|
35
|
+
filter: invert(1)
|
36
|
+
}
|
37
|
+
|
38
|
+
.select2-results__option[aria-selected=true],
|
39
|
+
.select2-result__option,
|
40
|
+
.select2-selection__choice,
|
41
|
+
.select2-selection__choice__remove {
|
42
|
+
color: #fafafa !important;
|
43
|
+
background-color: #626262 !important;
|
44
|
+
border-color: #626262 !important;
|
45
|
+
}
|
46
|
+
|
47
|
+
/* This is a check mark displayed for the selected options */
|
48
|
+
.select2-results__option[aria-selected=true]::after {
|
49
|
+
content: '';
|
50
|
+
display: block;
|
51
|
+
width: 0.5em;
|
52
|
+
height: 1em;
|
53
|
+
border-style: solid;
|
54
|
+
border-width: 0 0.26em 0.26em 0;
|
55
|
+
-webkit-transform-style: preserve-3d;
|
56
|
+
transform-style: preserve-3d;
|
57
|
+
-webkit-transform: rotate(45deg);
|
58
|
+
-ms-transform: rotate(45deg);
|
59
|
+
-o-transform: rotate(45deg);
|
60
|
+
transform: rotate(45deg);
|
61
|
+
}
|
62
|
+
}
|
@@ -11,6 +11,7 @@
|
|
11
11
|
<link href="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/css/select2.min.css" rel="stylesheet" integrity="sha512-nMNlpuaDPrqlEls3IX/Q56H36qvBASwb3ipuo3MxeWbsQB1881ox0cRv7UPTgBlriqoynt35KjEwgGUeUXIPnw==" crossorigin="anonymous" referrerpolicy="no-referrer"/>
|
12
12
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.14.0-beta3/css/bootstrap-select.min.css" integrity="sha512-g2SduJKxa4Lbn3GW+Q7rNz+pKP9AWMR++Ta8fgwsZRCUsawjPvF/BxSMkGS61VsR9yinGoEgrHPGPn2mrj8+4w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
13
13
|
<link href="https://cdn.jsdelivr.net/npm/select2-bootstrap-5-theme@1.2.0/dist/select2-bootstrap-5-theme.min.css" rel="stylesheet" />
|
14
|
+
<link rel="stylesheet" href="{{ url_for('overview.static', filename='select2_darktheme.css') }}"/>
|
14
15
|
{% endblock %}
|
15
16
|
|
16
17
|
{% block top_nav %}
|
@@ -124,5 +125,4 @@
|
|
124
125
|
});
|
125
126
|
});
|
126
127
|
</script>
|
127
|
-
|
128
128
|
{% endblock %}
|
@@ -81,7 +81,7 @@
|
|
81
81
|
<label for="mainainer">Maintainers</label>
|
82
82
|
<span class="float-end" id="maintainer"> {{ panel.maintainer_names|join(", ") }}</span>
|
83
83
|
</li>
|
84
|
-
{% if
|
84
|
+
{% if case and case.chanjo_coverage %}
|
85
85
|
<li class="list-group-item">
|
86
86
|
<label for="coverage_report">Coverage report</label>
|
87
87
|
<a class="float-end" id="coverage_report" href="#" onclick="document.getElementById('report-form').submit();">
|
@@ -103,6 +103,20 @@
|
|
103
103
|
</span>
|
104
104
|
</li>
|
105
105
|
{% endif %}
|
106
|
+
{% if case and case.chanjo2_coverage %}
|
107
|
+
<li class="list-group-item">
|
108
|
+
<label for="coverage_report">Coverage report (chanjo2)</label>
|
109
|
+
<a class="float-end" href="{{ url_for('cases.chanjo2_coverage_report', institute_id=institute._id, case_name=case.display_name, panel_name=panel.name_and_version, panel_id=panel._id, report_type='report') }}" target="_blank" rel="noopener">
|
110
|
+
{{ case.display_name }}
|
111
|
+
</a>
|
112
|
+
</li>
|
113
|
+
<li class="list-group-item">
|
114
|
+
<label for="coverage_report">Coverage overview (chanjo2)</label>
|
115
|
+
<a class="float-end" href="{{ url_for('cases.chanjo2_coverage_report', institute_id=institute._id, case_name=case.display_name, panel_name=panel.name_and_version, panel_id=panel._id, report_type='overview') }}" target="_blank" rel="noopener">
|
116
|
+
{{ case.display_name }}
|
117
|
+
</a>
|
118
|
+
</li>
|
119
|
+
{% endif %}
|
106
120
|
<li class="list-group-item">
|
107
121
|
<div class="d-flex justify-content-between">
|
108
122
|
<a href="{{ url_for('panels.panel_export_pdf', panel_id=panel._id) }}" class="btn btn-secondary btn-sm" download>Export to PDF</a>
|
@@ -6,7 +6,7 @@
|
|
6
6
|
<h4>Scout - Institute {{institute.display_name}} - case {{case.display_name}} - {{panel.name_and_version}}: panel extent report</h4> - created on: <strong>{{report_created_at}}</strong><br><br>
|
7
7
|
{{ hits_panel() }}
|
8
8
|
<br>[END OF REPORT]<br><br>
|
9
|
-
<a href="https://clinical-genomics.github.io/scout" target="_blank" rel="noopener">clinical-genomics.github.io/scout</a>
|
9
|
+
<a style="text-decoration:none;" href="https://clinical-genomics.github.io/scout" target="_blank" rel="noopener">clinical-genomics.github.io/scout</a>
|
10
10
|
</div>
|
11
11
|
{% endblock %}
|
12
12
|
|
@@ -21,7 +21,7 @@
|
|
21
21
|
Gene panel: <strong>{{panel.name_and_version}}</strong><br>
|
22
22
|
Last updated: <strong>{{ panel.date.strftime('%Y-%m-%d') }}</strong>
|
23
23
|
{% if case.outdated_panels and panel.panel_name in case.outdated_panels %}
|
24
|
-
<a><span class="badge rounded-pill
|
24
|
+
<a><span class="badge rounded-pill py-1 bg-warning" data-bs-toggle="popover" data-bs-placement="left" data-bs-html="true" data-bs-content="Panel version used in the analysis ({{panel.version}}) is outdated. Latest panel version is used in variants filtering.<br /><strong>Genes present in case panel and not in latest version</strong>: {{case.outdated_panels[panel.panel_name]['extra_genes']|join(', ') or '-'}}.<br /><strong>Genes present only in latest version</strong>: {{case.outdated_panels[panel.panel_name]['missing_genes']|join(', ') or '-'}}.">!</span></a>
|
25
25
|
{% endif %}<br>
|
26
26
|
Panel ID: {{ panel.panel_name }}<br>
|
27
27
|
Description: {{ panel.description }}<br>
|
@@ -6,14 +6,14 @@
|
|
6
6
|
<h4>Scout - Gene panel report</h4> - created on: <strong>{{report_created_at}}</strong><br><br>
|
7
7
|
{{ genes_panel() }}
|
8
8
|
[END OF REPORT]<br><br>
|
9
|
-
<a href="https://clinical-genomics.github.io/scout" target="_blank">clinical-genomics.github.io/scout</a>
|
9
|
+
<a style="text-decoration:none;" href="https://clinical-genomics.github.io/scout" target="_blank">clinical-genomics.github.io/scout</a>
|
10
10
|
</div>
|
11
11
|
{% endblock %}
|
12
12
|
|
13
13
|
{% macro genes_panel() %}
|
14
14
|
<div class="card border-dark mb-3">
|
15
15
|
<div class="card-header">
|
16
|
-
Panel: <a href="{{ url_for('panels.panel', panel_id=panel._id) }}">{{panel.name_and_version}}</a>
|
16
|
+
Panel: <a style="text-decoration:none;" href="{{ url_for('panels.panel', panel_id=panel._id) }}">{{panel.name_and_version}}</a>
|
17
17
|
</div>
|
18
18
|
<div class="card-body">
|
19
19
|
<table class="table table-sm">
|
@@ -58,7 +58,7 @@
|
|
58
58
|
<tr>
|
59
59
|
<td>{{loop.index}}</td>
|
60
60
|
<td>
|
61
|
-
<a href="https://www.genenames.org/cgi-bin/gene_symbol_report?hgnc_id={{gene.hgnc_id}}" target="_blank">{{gene.hgnc_id}}</a>
|
61
|
+
<a style="text-decoration:none;" href="https://www.genenames.org/cgi-bin/gene_symbol_report?hgnc_id={{gene.hgnc_id}}" target="_blank">{{gene.hgnc_id}}</a>
|
62
62
|
</td>
|
63
63
|
<td>{{ gene.symbol }}</td>
|
64
64
|
<td>{{ gene.disease_associated_transcripts|join(', ') }}</td>
|
@@ -21,6 +21,8 @@ from scout.export.panel import export_gene_panels
|
|
21
21
|
from scout.server.blueprints.cases.controllers import check_outdated_gene_panel
|
22
22
|
from scout.server.extensions import store
|
23
23
|
from scout.server.utils import (
|
24
|
+
case_has_chanjo2_coverage,
|
25
|
+
case_has_chanjo_coverage,
|
24
26
|
html_to_pdf_file,
|
25
27
|
institute_and_case,
|
26
28
|
jsonconverter,
|
@@ -140,7 +142,6 @@ def panel(panel_id):
|
|
140
142
|
raw_hgnc_id = request.form["hgnc_id"]
|
141
143
|
if "|" in raw_hgnc_id:
|
142
144
|
raw_hgnc_id = raw_hgnc_id.split(" | ", 1)[0]
|
143
|
-
hgnc_id = 0
|
144
145
|
try:
|
145
146
|
hgnc_id = int(raw_hgnc_id)
|
146
147
|
except ValueError:
|
@@ -168,6 +169,9 @@ def panel(panel_id):
|
|
168
169
|
if request.args.get("case_id"):
|
169
170
|
case_obj = store.case(request.args["case_id"])
|
170
171
|
|
172
|
+
case_has_chanjo_coverage(case_obj)
|
173
|
+
case_has_chanjo2_coverage(case_obj)
|
174
|
+
|
171
175
|
case_obj["outdated_panels"] = {}
|
172
176
|
panel_name = panel_obj["panel_name"]
|
173
177
|
latest_panel = store.gene_panel(panel_name)
|
@@ -505,8 +505,11 @@ def observations(store: MongoAdapter, loqusdb: LoqusDB, variant_obj: dict) -> Di
|
|
505
505
|
if obs_data[loqus_id].get("total"):
|
506
506
|
obs_data[loqus_id]["observations"] = 0
|
507
507
|
continue
|
508
|
-
|
509
|
-
|
508
|
+
# Check if the current case is represented in the loqusdb instance
|
509
|
+
obs_data[loqus_id]["case_match"] = variant_obj["case_id"] in obs_data[loqus_id].get(
|
510
|
+
"families", []
|
511
|
+
)
|
512
|
+
# collect other cases where observations occurred
|
510
513
|
obs_data[loqus_id]["cases"] = get_loqusdb_obs_cases(
|
511
514
|
store, variant_obj, category, obs_data[loqus_id].get("families", [])
|
512
515
|
)
|