scout-browser 4.89.2__py3-none-any.whl → 4.90.1__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.
Files changed (51) hide show
  1. scout/__version__.py +1 -1
  2. scout/adapter/mongo/panel.py +21 -58
  3. scout/adapter/mongo/query.py +9 -0
  4. scout/build/panel.py +36 -72
  5. scout/constants/__init__.py +28 -45
  6. scout/constants/acmg.py +76 -16
  7. scout/constants/gene_tags.py +4 -2
  8. scout/constants/panels.py +11 -0
  9. scout/constants/query_terms.py +1 -0
  10. scout/constants/variant_tags.py +58 -3
  11. scout/export/panel.py +30 -33
  12. scout/parse/matchmaker.py +18 -6
  13. scout/parse/panel.py +40 -49
  14. scout/server/blueprints/alignviewers/views.py +3 -0
  15. scout/server/blueprints/cases/controllers.py +4 -0
  16. scout/server/blueprints/cases/templates/cases/case_sma.html +14 -6
  17. scout/server/blueprints/cases/templates/cases/collapsible_actionbar.html +10 -2
  18. scout/server/blueprints/cases/templates/cases/matchmaker.html +12 -7
  19. scout/server/blueprints/institutes/controllers.py +11 -4
  20. scout/server/blueprints/institutes/templates/overview/causatives.html +1 -1
  21. scout/server/blueprints/institutes/templates/overview/gene_variants.html +3 -5
  22. scout/server/blueprints/institutes/templates/overview/utils.html +2 -2
  23. scout/server/blueprints/institutes/templates/overview/verified.html +1 -1
  24. scout/server/blueprints/institutes/views.py +22 -6
  25. scout/server/blueprints/omics_variants/templates/omics_variants/outliers.html +1 -1
  26. scout/server/blueprints/omics_variants/views.py +2 -0
  27. scout/server/blueprints/panels/controllers.py +8 -16
  28. scout/server/blueprints/panels/templates/panels/gene-edit.html +2 -2
  29. scout/server/blueprints/panels/templates/panels/panel.html +21 -13
  30. scout/server/blueprints/panels/templates/panels/panel_pdf_simple.html +25 -18
  31. scout/server/blueprints/panels/views.py +9 -6
  32. scout/server/blueprints/variant/templates/variant/acmg.html +28 -24
  33. scout/server/blueprints/variant/templates/variant/gene_disease_relations.html +1 -3
  34. scout/server/blueprints/variant/templates/variant/utils.html +1 -1
  35. scout/server/blueprints/variant/utils.py +1 -0
  36. scout/server/blueprints/variant/views.py +5 -2
  37. scout/server/blueprints/variants/templates/variants/cancer-sv-variants.html +7 -11
  38. scout/server/blueprints/variants/templates/variants/components.html +55 -38
  39. scout/server/blueprints/variants/templates/variants/mei-variants.html +2 -6
  40. scout/server/blueprints/variants/templates/variants/str-variants.html +8 -2
  41. scout/server/blueprints/variants/templates/variants/sv-variants.html +4 -8
  42. scout/server/blueprints/variants/templates/variants/variants.html +23 -18
  43. scout/server/blueprints/variants/views.py +6 -0
  44. scout/utils/acmg.py +155 -28
  45. scout/utils/scout_requests.py +8 -13
  46. {scout_browser-4.89.2.dist-info → scout_browser-4.90.1.dist-info}/METADATA +1 -1
  47. {scout_browser-4.89.2.dist-info → scout_browser-4.90.1.dist-info}/RECORD +51 -50
  48. {scout_browser-4.89.2.dist-info → scout_browser-4.90.1.dist-info}/LICENSE +0 -0
  49. {scout_browser-4.89.2.dist-info → scout_browser-4.90.1.dist-info}/WHEEL +0 -0
  50. {scout_browser-4.89.2.dist-info → scout_browser-4.90.1.dist-info}/entry_points.txt +0 -0
  51. {scout_browser-4.89.2.dist-info → scout_browser-4.90.1.dist-info}/top_level.txt +0 -0
@@ -6,7 +6,14 @@ from flask import Blueprint, flash, jsonify, redirect, render_template, request
6
6
  from flask_login import current_user
7
7
  from pymongo import DESCENDING
8
8
 
9
- from scout.constants import ACMG_COMPLETE_MAP, ACMG_MAP, CALLERS, VERBS_ICONS_MAP, VERBS_MAP
9
+ from scout.constants import (
10
+ ACMG_COMPLETE_MAP,
11
+ ACMG_MAP,
12
+ CALLERS,
13
+ INHERITANCE_PALETTE,
14
+ VERBS_ICONS_MAP,
15
+ VERBS_MAP,
16
+ )
10
17
  from scout.server.blueprints.variants.controllers import update_form_hgnc_symbols
11
18
  from scout.server.extensions import beacon, loqusdb, store
12
19
  from scout.server.utils import institute_and_case, jsonconverter, templated, user_institutes
@@ -63,11 +70,12 @@ def verified(institute_id):
63
70
  verified_vars = controllers.verified_vars(institute_id)
64
71
  verified_stats = controllers.verified_stats(institute_id, verified_vars)
65
72
  return dict(
73
+ acmg_map={key: ACMG_COMPLETE_MAP[value] for key, value in ACMG_MAP.items()},
74
+ callers=CALLERS,
75
+ inherit_palette=INHERITANCE_PALETTE,
66
76
  institute=institute_obj,
67
77
  verified=verified_vars,
68
78
  verified_stats=verified_stats,
69
- acmg_map={key: ACMG_COMPLETE_MAP[value] for key, value in ACMG_MAP.items()},
70
- callers=CALLERS,
71
79
  )
72
80
 
73
81
 
@@ -76,10 +84,11 @@ def verified(institute_id):
76
84
  def causatives(institute_id):
77
85
  institute_obj = institute_and_case(store, institute_id)
78
86
  return dict(
79
- institute=institute_obj,
80
- causatives=controllers.causatives(institute_obj, request),
81
87
  acmg_map={key: ACMG_COMPLETE_MAP[value] for key, value in ACMG_MAP.items()},
82
88
  callers=CALLERS,
89
+ causatives=controllers.causatives(institute_obj, request),
90
+ institute=institute_obj,
91
+ inherit_palette=INHERITANCE_PALETTE,
83
92
  )
84
93
 
85
94
 
@@ -168,7 +177,14 @@ def gene_variants(institute_id):
168
177
  store, results, result_size, page
169
178
  ) # decorated variant results, max 50 in a page
170
179
 
171
- return dict(institute=institute_obj, form=form, page=page, result_size=result_size, **data)
180
+ return dict(
181
+ institute=institute_obj,
182
+ form=form,
183
+ inherit_palette=INHERITANCE_PALETTE,
184
+ page=page,
185
+ result_size=result_size,
186
+ **data,
187
+ )
172
188
 
173
189
 
174
190
  # MOST OF THE CONTENT OF THIS ENDPOINT WILL BE REMOVED AND INCLUDED INTO THE BEACON EXTENSION UNDER SERVER/EXTENSIONS
@@ -72,7 +72,7 @@
72
72
  <td class="text-end">
73
73
  <div class="d-flex flex-row justify-content-between">
74
74
  {% if variant.genes %}
75
- {{ gene_cell(variant) }}
75
+ {{ gene_cell(variant, inherit_palette) }}
76
76
  {% else %}
77
77
  {{ variant.gene_name_orig }}
78
78
  {% endif %}
@@ -2,6 +2,7 @@ from flask import Blueprint, request
2
2
  from flask_login import current_user
3
3
  from markupsafe import Markup
4
4
 
5
+ from scout.constants import INHERITANCE_PALETTE
5
6
  from scout.server.blueprints.variants.controllers import (
6
7
  activate_case,
7
8
  case_default_panels,
@@ -97,6 +98,7 @@ def outliers(institute_id, case_name):
97
98
  expand_search=get_expand_search(request.form),
98
99
  filters=available_filters,
99
100
  form=form,
101
+ inherit_palette=INHERITANCE_PALETTE,
100
102
  institute=institute_obj,
101
103
  page=page,
102
104
  result_size=result_size,
@@ -2,10 +2,13 @@
2
2
  import datetime as dt
3
3
  import logging
4
4
  import re
5
+ from typing import List, Optional, Union
5
6
 
6
- from flask import flash, redirect
7
+ from flask import Response, flash, redirect
7
8
  from flask_login import current_user
9
+ from werkzeug.local import LocalProxy
8
10
 
11
+ from scout.adapter import MongoAdapter
9
12
  from scout.build.panel import build_panel
10
13
  from scout.constants import DATE_DAY_FORMATTER
11
14
  from scout.parse.panel import parse_genes
@@ -45,14 +48,8 @@ def panel_decode_lines(panel_file):
45
48
  return lines
46
49
 
47
50
 
48
- def create_new_panel(store, request, lines):
51
+ def create_new_panel(store: MongoAdapter, request: LocalProxy, lines: List[str]) -> Optional[str]:
49
52
  """Create a new gene panel with the data provided using the form
50
-
51
- Args:
52
- store(scout.adapter.MongoAdapter)
53
- request(flask.request) request sent by browser form to the /panels endpoint
54
- lines(list): list of lines containing gene data
55
-
56
53
  Returns:
57
54
  new_panel_id(str): the _id a newly created panel
58
55
  """
@@ -107,17 +104,12 @@ def update_existing_panel(store, request, lines):
107
104
  )
108
105
 
109
106
 
110
- def panel_create_or_update(store, request):
107
+ def panel_create_or_update(store: MongoAdapter, request: LocalProxy) -> Union[str, Response]:
111
108
  """Process a user request to create a new gene panel
112
109
 
113
- Args:
114
- store(scout.adapter.MongoAdapter)
115
- request(flask.request) request sent by browser form to the /panels endpoint
116
-
117
110
  Returns:
118
111
  redirect_id(str): the ID of the panel to redirect the page to
119
112
  """
120
- redirect_id = None
121
113
  panel_file = request.files["panel_file"]
122
114
  lines = panel_decode_lines(panel_file)
123
115
 
@@ -324,9 +316,9 @@ def downloaded_panel_name(panel_obj, format) -> str:
324
316
 
325
317
  def panel_data(store, panel_obj):
326
318
  """Preprocess a panel of genes."""
319
+
327
320
  panel_obj["institute"] = store.institute(panel_obj["institute"])
328
- full_name = "{}({})".format(panel_obj["display_name"], panel_obj["version"])
329
- panel_obj["name_and_version"] = full_name
321
+ panel_obj["name_and_version"] = "{}({})".format(panel_obj["display_name"], panel_obj["version"])
330
322
 
331
323
  return dict(panel=panel_obj)
332
324
 
@@ -28,13 +28,13 @@
28
28
  </select>
29
29
  </div>
30
30
  <div class="col-md-4">
31
+ {{ form.reduced_penetrance() }}
31
32
  {{ form.reduced_penetrance.label(class="control-label") }}
32
33
  (OMIM: {{ 'Yes' if gene.incomplete_penetrance else 'unknown' }})
33
- <div>{{ form.reduced_penetrance() }}</div>
34
34
  </div>
35
35
  <div class="col-md-4">
36
+ {{ form.mosaicism() }}
36
37
  {{ form.mosaicism.label(class="control-label") }}
37
- <div>{{ form.mosaicism() }}</div>
38
38
  </div>
39
39
  </div>
40
40
  <div class="row">
@@ -107,16 +107,24 @@
107
107
  {% if case and case.chanjo2_coverage and panel.genes %}
108
108
  <li class="list-group-item">
109
109
  <label for="coverage_report">Coverage report (chanjo2)</label>
110
- <span class="float-end">
110
+ <span class="float-end" style="cursor: pointer;">
111
111
  {{ chanjo2_report_form(panel.institute, case, panel.name_and_version, 'report', panel.genes|map(attribute='hgnc_id')|join(','), case.display_name) }} <!--chanjo2 report-->
112
112
  </span>
113
113
  </li>
114
114
  <li class="list-group-item">
115
115
  <label for="coverage_report">Coverage overview (chanjo2)</label>
116
- <span class="float-end">
116
+ <span class="float-end" style="cursor: pointer;">
117
117
  {{ chanjo2_report_form(panel.institute, case, panel.name_and_version, 'overview', panel.genes|map(attribute='hgnc_id')|join(','), case.display_name) }} <!--chanjo2 genes overview -->
118
118
  </span>
119
119
  </li>
120
+ {% if "38" in case.genome_build %}
121
+ <li class="list-group-item">
122
+ <label for="coverage_report">MANE coverage overview (chanjo2)</label>
123
+ <span class="float-end" style="cursor: pointer;">
124
+ {{ chanjo2_report_form(panel.institute, case, panel.name_and_version, 'mane_overview', panel.genes|map(attribute='hgnc_id')|join(','), case.display_name) }} <!--chanjo2 MANE overview -->
125
+ </span>
126
+ </li>
127
+ {% endif %}
120
128
  {% endif %}
121
129
  <li class="list-group-item">
122
130
  <div class="d-flex justify-content-between">
@@ -138,21 +146,30 @@
138
146
  <table class="table table-bordered" aria-label="Included genes">
139
147
  <thead class="table-light thead">
140
148
  <tr>
149
+ <th></th>
141
150
  <th>Gene</th>
142
151
  <th>HGNC ID</th>
143
- <th>Transcripts</th>
152
+ <th>Disease-associated transcripts</th>
144
153
  <th>Reduced penetrance</th>
145
154
  <th>Mosaicism</th>
146
155
  <th>Entry version</th>
147
156
  <th>Manual inheritance (pre-set terms)</th>
148
157
  <th>Manual inheritance (free text terms)</th>
149
158
  <th>Comment</th>
150
- <th>Action</th>
151
159
  </tr>
152
160
  </thead>
153
161
  <tbody>
154
162
  {% for gene in panel.genes|sort(attribute='symbol') %}
155
163
  <tr>
164
+ <td>
165
+ {% if not panel.is_archived %}
166
+ <form class="float-start" action="{{ url_for('panels.panel', panel_id=panel._id) }}" method="POST">
167
+ <input type="hidden" name="hgnc_id" value="{{ gene.hgnc_id }}">
168
+ <button name="action" type="submit" value="delete" class="btn btn-danger btn-xs">Delete</button>
169
+ </form>
170
+ <a class="btn btn-secondary text-white btn-xs ms-1" href="{{ url_for('panels.gene_edit', panel_id=panel._id, hgnc_id=gene.hgnc_id) }}">Edit</a>
171
+ {% endif %}
172
+ </td>
156
173
  <td>
157
174
  <a href="{{ url_for('genes.gene', hgnc_id=gene.hgnc_id) }}">
158
175
  {{ gene.symbol }}
@@ -167,15 +184,6 @@
167
184
  <td>{{ gene.inheritance_models|join(', ') }}</td>
168
185
  <td>{{ gene.custom_inheritance_models|join(', ') }}</td>
169
186
  <td>{{ gene.comment }}</td>
170
- <td>
171
- {% if not panel.is_archived %}
172
- <a class="btn btn-secondary btn-xs" href="{{ url_for('panels.gene_edit', panel_id=panel._id, hgnc_id=gene.hgnc_id) }}">Edit</a>
173
- <form class="float-end" action="{{ url_for('panels.panel', panel_id=panel._id) }}" method="POST">
174
- <input type="hidden" name="hgnc_id" value="{{ gene.hgnc_id }}">
175
- <button name="action" type="submit" value="delete" class="btn btn-danger btn-xs">Delete</button>
176
- </form>
177
- {% endif %}
178
- </td>
179
187
  </tr>
180
188
  {% endfor %}
181
189
  </tbody>
@@ -18,25 +18,28 @@
18
18
  <div class="card-body">
19
19
  <table class="table table-sm">
20
20
  <tr>
21
- <td>Updated:<span class="badge bg-secondary rounded-pill text-white">{{ panel.date.strftime('%Y-%m-%d') }}</span></td>
21
+ <td>Updated:{{ panel.date.strftime('%Y-%m-%d') }}</td>
22
22
  </tr>
23
23
  <tr>
24
- <td>Number of genes:<span class="badge bg-secondary rounded-pill text-white">{{ panel.genes|length }}</span></td>
24
+ <td>Number of genes:{{ panel.genes|length }}</td>
25
25
  </tr>
26
26
  <tr>
27
- <td>Institute: <span class="badge bg-secondary rounded-pill text-white">{{ panel.institute.display_name }}</span></td>
27
+ <td>Institute:{{ panel.institute.display_name }}</td>
28
28
  </tr>
29
29
  <tr>
30
30
  <td>Panel archived:
31
31
  {% if panel.is_archived %}
32
- <span class="badge bg-danger rounded-pill">True</span>
32
+ True
33
33
  {% else %}
34
- <span class="badge bg-secondary rounded-pill text-white">False</span>
34
+ False
35
35
  {% endif %}
36
36
  </td>
37
37
  </tr>
38
38
  <tr>
39
- <td>Panel database ID: <span class="badge bg-secondary rounded-pill text-white">{{ panel._id }}</span></td>
39
+ <td>Panel database ID: {{ panel._id }}</td>
40
+ </tr>
41
+ <tr>
42
+ <td>Maintainers: {{ panel.maintainer|join(", ") }}</td>
40
43
  </tr>
41
44
  </table>
42
45
  </div>
@@ -45,27 +48,31 @@
45
48
  <div>
46
49
  <table class="table table-sm">
47
50
  <tr>
48
- <td></td>
49
- <td>HGNC id</td>
50
- <td>Gene name</td>
51
- <td>Disease associated transcripts</td>
52
- <td>Reduced penetrance</td>
53
- <td>Mosaicism</td>
54
- <td>Entry version</td>
55
- <td>Inheritance</td>
51
+ <th></th>
52
+ <th>Gene</th>
53
+ <th>HGNC ID</th>
54
+ <th>Disease-associated transcripts</th>
55
+ <th>Reduced penetrance</th>
56
+ <th>Mosaicism</th>
57
+ <th>Entry version</th>
58
+ <th>Manual inheritance (pre-set terms)</th>
59
+ <th>Manual inheritance (free text terms)</th>
60
+ <th>Comment</th>
56
61
  </tr>
57
62
  {% for gene in panel.genes|sort(attribute='symbol') %}
58
63
  <tr>
59
64
  <td>{{loop.index}}</td>
65
+ <td>{{ gene.symbol }}</td>
60
66
  <td>
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>
67
+ <a style="text-decoration:none;" href="https://www.genenames.org/data/gene-symbol-report/#!/hgnc_id/HGNC:{{gene.hgnc_id}}" target="_blank">{{gene.hgnc_id}}</a>
62
68
  </td>
63
- <td>{{ gene.symbol }}</td>
64
69
  <td>{{ gene.disease_associated_transcripts|join(', ') }}</td>
65
70
  <td>{{ 'Reduced penetrance' if gene.reduced_penetrance }}</td>
66
- <td>{{ 'Mosaicism' if gene.mosaicism}}</td>
67
- <td><span class="badge bg-secondary">{{ gene.database_entry_version }}</span></td>
71
+ <td>{{ 'Mosaicism' if gene.mosaicism }}</td>
72
+ <td>{{ gene.database_entry_version }}</td>
68
73
  <td>{{ gene.inheritance_models|join(', ') }}</td>
74
+ <td>{{ gene.custom_inheritance_models|join(', ') }}</td>
75
+ <td>{{ gene.comment }}</td>
69
76
  </tr>
70
77
  {% endfor %}
71
78
  </table>
@@ -384,12 +384,14 @@ def gene_edit(panel_id, hgnc_id):
384
384
  form.disease_associated_transcripts.choices = tx_choices(hgnc_id, panel_obj)
385
385
  if form.validate_on_submit():
386
386
  action = "edit" if panel_gene else "add"
387
- info_data = form.data.copy()
388
- if "csrf_token" in info_data:
389
- del info_data["csrf_token"]
390
- if info_data["custom_inheritance_models"] != "":
391
- info_data["custom_inheritance_models"] = info_data["custom_inheritance_models"].split(
392
- ","
387
+ info_data: dict = {
388
+ k: v for k, v in form.data.copy().items() if v
389
+ } # Update only fields edited by user
390
+ info_data.pop("csrf_token", None)
391
+
392
+ if info_data.get("custom_inheritance_models", ""):
393
+ info_data["custom_inheritance_models"] = (
394
+ info_data["custom_inheritance_models"].replace(" ", "").split(",")
393
395
  )
394
396
  store.add_pending(panel_obj, hgnc_gene, action=action, info=info_data)
395
397
  return redirect(url_for(".panel", panel_id=panel_id))
@@ -416,4 +418,5 @@ def gene_edit(panel_id, hgnc_id):
416
418
  panel_value = panel_gene.get(field_key)
417
419
  if panel_value is not None:
418
420
  form_field.process_data(panel_value)
421
+
419
422
  return dict(panel=panel_obj, form=form, gene=hgnc_gene, panel_gene=panel_gene)
@@ -32,7 +32,7 @@
32
32
  {% if evaluation %}
33
33
  <h4>
34
34
  {{ evaluation.classification.label }}
35
- <span class="badge bg-info">{{ evaluation.classification.short }}</span>
35
+ <span class="badge bg-info">{{ evaluation.classification.short|safe }}</span>
36
36
  </h4>
37
37
  By {{ evaluation.user_name }} on {{ evaluation.created_at.date() }}
38
38
  {% if edit %}
@@ -42,14 +42,7 @@
42
42
  {% elif not evaluation %}
43
43
  <button class="btn btn-primary form-control">Submit</button>
44
44
  {% endif %}
45
- <!-- classification preview in the footer-->
46
- <div class="mt-3 fixed-bottom bg-light border">
47
- <div class="text-center">
48
- {% for option in ACMG_OPTIONS %}
49
- <a id="acmg-{{ option.code }}" class="btn acmg-preview">{{ option.label }}</a>
50
- {% endfor %}
51
- </div>
52
- </div>
45
+ <div id="conflicts_div" class="bg-warning"></div>
53
46
  </div>
54
47
  </div>
55
48
 
@@ -72,23 +65,23 @@
72
65
  {% endif %}
73
66
  <div class="list-group-item">
74
67
  <div class="d-flex justify-content-between">
75
- <div data-bs-toggle="tooltip" data-bs-placement="top" title="{{ criterion.description }}">
68
+ <div data-bs-toggle="tooltip" data-bs-placement="top" title="{{ criterion.description|safe }}">
76
69
  <span class="badge bg-info me-1">{{ criterion_code }}</span>
77
- {{ criterion.short }}
70
+ {{ criterion.short|safe}}
78
71
  </div>
79
72
  <div class="form-check form-switch">
80
- <input type="checkbox" class="form-check-input" id="checkbox-{{ criterion_code }}" name="criteria" value="{{ criterion_code }}" {{ 'checked' if evaluation and criterion_code in evaluation.criteria }} {{ 'disabled' if evaluation and edit is false}}>
73
+ <input type="checkbox" class="form-check-input" id="checkbox-{{ criterion_code }}" name="criteria" value="{{ criterion_code }}" {{ 'checked' if evaluation and criterion_code in evaluation.criteria }} {{ 'disabled' if evaluation and edit is false }}>
81
74
  <label class="form-check-label" for="checkbox-{{ criterion_code }}"></label>
82
75
  </div>
83
76
  </div>
84
77
  <div id="comment-{{ criterion_code }}" class="{{ 'collapse' if not (comment or link or modifier) }} mt-2">
85
- {% if criterion.documentation %}<div class="row"><span class="me-1 fw-light text-wrap">{{ criterion.documentation | safe}}</span></div>{% endif %}
78
+ {% if criterion.documentation %}<div class="row"><span class="me-1 fw-light text-wrap">{{ criterion.documentation | safe }}</span></div>{% endif %}
86
79
  <div class="row">
87
80
  <select {{ 'disabled' if evaluation and edit is false}} id="modifier-{{ criterion_code }}" name="modifier-{{ criterion_code }}" class="form-control form-select">
88
81
  <option value="" {% if not modifier %}selected{% endif %}>Strength modifier...</option>
89
82
  {% for level in "Strong", "Moderate", "Supporting" %}
90
83
  {% if(level != evidence) %}
91
- <option id="{{criterion_code}}-{{level}}" value="{{level}}" {% if modifier == level %}selected{% endif%}>{{ level }}</option>
84
+ <option id="{{ criterion_code }}-{{ level }}" value="{{ level }}" {% if modifier == level %}selected{% endif %}>{{ level }}</option>
92
85
  {% endif %}
93
86
  {% endfor %}
94
87
  </select>
@@ -108,19 +101,23 @@
108
101
  </div>
109
102
  {% endfor %}
110
103
  </div>
104
+ <!-- classification preview in the footer-->
105
+ <div class="mt-3 fixed-bottom bg-light border">
106
+ <div class="row">
107
+ <div class="col-3" style="font-size:1.5em">
108
+ <a href="https://clinicalgenome.org/docs/modeling-the-acmg-amp-variant-classification-gudielines-as-a-bayesian-classification-framework/" data-bs-toggle="tooltip" title="Classification based on the Bayesian score model in Tavtigian et al." rel="noopener noreferrer" target="_blank"><span id="temperature_span" class="badge"></span></a>
109
+ </div>
110
+ <div class="col-6 text-center">
111
+ {% for option in ACMG_OPTIONS %}
112
+ <a id="acmg-{{ option.code }}" href="https://www.acmg.net/docs/standards_guidelines_for_the_interpretation_of_sequence_variants.pdf" class="btn acmg-preview" data-bs-toggle="tooltip" title="Suggested classification based on Richards et al 2015.">{{ option.label }}</a>
113
+ {% endfor %}
114
+ </div>
115
+ </div>
116
+ </div>
111
117
  </form>
112
118
  </div>
113
119
  {% endblock %}
114
120
 
115
- {% macro preview() %}
116
- <div class="card panel-default">
117
- <div class="card-body">
118
- <span class="text-muted">Classification</span>
119
- <h5>Likely Pathogenic</h5>
120
- </div>
121
- </div>
122
- {% endmacro %}
123
-
124
121
  {% block scripts %}
125
122
  {{ super() }}
126
123
 
@@ -166,12 +163,19 @@
166
163
  return 'criterion=' + elem.value
167
164
  });
168
165
 
169
-
170
166
  $.getJSON('/api/v1/acmg?' + criteria.toArray().join('&'), function(data) {
171
167
  // reset the selection
172
168
  $('.acmg-preview').removeClass('btn-primary');
173
169
  // add new selection
174
170
  $('#acmg-' + data.classification).addClass('btn-primary');
171
+
172
+ var temperature_span = document.getElementById("temperature_span");
173
+ temperature_span.innerHTML = 'Score ' + data.points + ' <span class="fa ' + data.temperature_icon + '"></span> ' + data.temperature + ' (' + data.point_classification + ')'
174
+ temperature_span.className = 'badge bg-' + data.temperature_class
175
+
176
+ // Update any classification conflicts
177
+ var conflicts_div = document.getElementById("conflicts_div");
178
+ conflicts_div.innerHTML = data.conflicts.join("<br>");
175
179
  });
176
180
  }
177
181
  </script>
@@ -42,7 +42,6 @@
42
42
  <tr>
43
43
  <th>Gene</th>
44
44
  <th>ORPHA Phenotype</th>
45
- <th>Inheritance model</th>
46
45
  </tr>
47
46
  </thead>
48
47
  <tbody>
@@ -50,7 +49,7 @@
50
49
  {% if gene.common and gene.disease_terms %}
51
50
  {% for disease_term in gene.disease_terms %}
52
51
  {% if disease_term.source == 'ORPHA' %}
53
- <tr data-bs-toggle="tooltip" title="Some ORPHA disorders are phenotypic umbrella terms for multiple genetic entities. The inheritance models are in this case a set derived from all those entities, not necessarily modes of inheritance known for this gene. ORPHA inheritance modes will not be shown on the general case report.">
52
+ <tr data-bs-toggle="tooltip" title="We are not displaying inheritance models associated to ORPHANET terms. This is because some ORPHA disorders are phenotypic umbrella terms for multiple genetic entities. The inheritance models are in this case a set derived from all those entities, not necessarily modes of inheritance known for this gene.">
54
53
  <td>
55
54
  <a href="http://omim.org/entry/{{ gene.common.omim_id }}" rel="noopener" target="_blank">
56
55
  {{ gene.common.hgnc_symbol }}
@@ -62,7 +61,6 @@
62
61
  {{ disease_term.description }}
63
62
  </a>
64
63
  </td>
65
- <td>{{ disease_term.inheritance|join(', ') }}</td>
66
64
  </tr>
67
65
  {% endif %}
68
66
  {% endfor %}
@@ -451,7 +451,7 @@
451
451
  {% set symbol_genes_counter = namespace(value=0) %}
452
452
  {% set nosymbol_genes_counter = namespace(value=0) %}
453
453
  <a
454
- href="{{ url_for('panels.panel', panel_id=panel.panel_id) }}"
454
+ href="{{ url_for('panels.panel', panel_id=panel._id) }}"
455
455
  {#
456
456
  Add hovertip listing occurence of each gene on selected panels, in the case
457
457
  where variant covers multiple genes.
@@ -50,6 +50,7 @@ def add_panel_specific_gene_info(panel_info: List[dict]) -> dict:
50
50
  comment.append(panel_gene_comment)
51
51
 
52
52
  manual_inheritance.update(gene_info.get("inheritance_models", []))
53
+ manual_inheritance.update(gene_info.get("custom_inheritance_models", []))
53
54
 
54
55
  panel_specific["disease_associated_transcripts"] = list(disease_associated)
55
56
  panel_specific["disease_associated_no_version"] = disease_associated_no_version
@@ -26,7 +26,7 @@ from scout.server.blueprints.variant.verification_controllers import (
26
26
  )
27
27
  from scout.server.extensions import loqusdb, store
28
28
  from scout.server.utils import institute_and_case, public_endpoint, templated
29
- from scout.utils.acmg import get_acmg
29
+ from scout.utils.acmg import get_acmg, get_acmg_conflicts, get_acmg_temperature
30
30
  from scout.utils.ensembl_rest_clients import EnsemblRestApiClient
31
31
 
32
32
  LOG = logging.getLogger(__name__)
@@ -347,7 +347,10 @@ def acmg():
347
347
  """Calculate an ACMG classification from submitted criteria."""
348
348
  criteria = request.args.getlist("criterion")
349
349
  classification = get_acmg(criteria)
350
- return jsonify(dict(classification=classification))
350
+
351
+ acmg_bayesian = get_acmg_temperature(criteria)
352
+ acmg_conflicts = get_acmg_conflicts(criteria)
353
+ return jsonify({"classification": classification, "conflicts": acmg_conflicts, **acmg_bayesian})
351
354
 
352
355
 
353
356
  @variant_bp.route(
@@ -1,6 +1,6 @@
1
1
  {% extends "layout.html" %}
2
2
  {% from "variants/utils.html" import cancer_sv_filters,cell_rank, pagination_footer, pagination_hidden_div, filter_form_footer, filter_script_main, update_stash_filter_button_status, dismiss_variants_block %}
3
- {% from "variants/components.html" import external_scripts, external_stylesheets, frequency_cell_general, observed_cell_general, variant_gene_symbols_cell, variant_funct_anno_cell, variant_region_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
@@ -56,18 +56,17 @@
56
56
  <table id="variantsTable" class="table table-hover table-bordered" aria-label="Somatic SV variants table">
57
57
  <thead class="thead table-light">
58
58
  <tr>
59
- <th style="width:3%"></th>
59
+ <th style="width:2%"></th>
60
60
  <th style="width:9%">Index</th>
61
61
  <th>Type</th>
62
- <th>Chr</th>
62
+ <th style="width:5%">Chr</th>
63
63
  <th>Start</th>
64
64
  <th>End</th>
65
65
  <th>Length</th>
66
66
  <th>Pop Freq</th>
67
67
  <th>Observed</th>
68
- <th>Gene(s)</th>
69
- <th>Region</th>
70
- <th style="width:12%">Function</th>
68
+ <th style="width:12%">Gene(s)</th>
69
+ <th style="width:16%">Function</th>
71
70
  <th style="width:9%" data-bs-toggle="tooltip" data-bs-placement="top" title="Tumor alt. AF not computed as it varies with variant type and caller. &#013; Alt. allele support | Ref. allele support. [Somatic score if available from caller].">Tumor</th>
72
71
  <th style="width:6%" data-bs-toggle="tooltip" data-bs-placement="top" title="Normal alt. AF not computed as it varies with variant type and caller. &#013; Alt. allele support | Ref. allele support">Normal</th>
73
72
  </tr>
@@ -77,7 +76,7 @@
77
76
  {{ variant_row(variant) }}
78
77
  {% else %}
79
78
  <tr>
80
- <td colspan="10">No matching variants</td>
79
+ <td colspan="13">No matching variants</td>
81
80
  </tr>
82
81
  {% endfor %}
83
82
  </tbody>
@@ -114,10 +113,7 @@
114
113
  <td class="text-end">{{ frequency_cell_general(variant) }}</td>
115
114
  <td>{{observed_cell_general(variant)}}</td>
116
115
  <td>
117
- {{ variant_gene_symbols_cell(variant) }}
118
- </td>
119
- <td>
120
- {{ variant_region_anno_cell(variant) }}
116
+ {{ variant_gene_symbols_cell(variant, inherit_palette) }}
121
117
  </td>
122
118
  <td>
123
119
  {{ variant_funct_anno_cell(variant) }}