scout-browser 4.89.2__py3-none-any.whl → 4.90__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scout/__version__.py +1 -1
- scout/adapter/mongo/panel.py +21 -58
- scout/adapter/mongo/query.py +9 -0
- scout/build/panel.py +36 -72
- scout/constants/__init__.py +28 -45
- scout/constants/acmg.py +76 -16
- scout/constants/gene_tags.py +4 -2
- scout/constants/panels.py +11 -0
- scout/constants/query_terms.py +1 -0
- scout/constants/variant_tags.py +58 -3
- scout/export/panel.py +30 -33
- scout/parse/panel.py +40 -49
- scout/server/blueprints/alignviewers/views.py +3 -0
- scout/server/blueprints/cases/controllers.py +4 -0
- scout/server/blueprints/cases/templates/cases/case_sma.html +14 -6
- scout/server/blueprints/cases/templates/cases/collapsible_actionbar.html +10 -2
- scout/server/blueprints/cases/templates/cases/matchmaker.html +12 -7
- scout/server/blueprints/institutes/controllers.py +11 -4
- scout/server/blueprints/institutes/templates/overview/causatives.html +1 -1
- scout/server/blueprints/institutes/templates/overview/gene_variants.html +3 -5
- scout/server/blueprints/institutes/templates/overview/utils.html +2 -2
- scout/server/blueprints/institutes/templates/overview/verified.html +1 -1
- scout/server/blueprints/institutes/views.py +22 -6
- scout/server/blueprints/omics_variants/templates/omics_variants/outliers.html +1 -1
- scout/server/blueprints/omics_variants/views.py +2 -0
- scout/server/blueprints/panels/controllers.py +8 -16
- scout/server/blueprints/panels/templates/panels/gene-edit.html +2 -2
- scout/server/blueprints/panels/templates/panels/panel.html +21 -13
- scout/server/blueprints/panels/templates/panels/panel_pdf_simple.html +25 -18
- scout/server/blueprints/panels/views.py +9 -6
- scout/server/blueprints/variant/templates/variant/acmg.html +28 -24
- scout/server/blueprints/variant/templates/variant/gene_disease_relations.html +1 -3
- scout/server/blueprints/variant/templates/variant/utils.html +1 -1
- scout/server/blueprints/variant/utils.py +1 -0
- scout/server/blueprints/variant/views.py +5 -2
- scout/server/blueprints/variants/templates/variants/cancer-sv-variants.html +7 -11
- scout/server/blueprints/variants/templates/variants/components.html +55 -38
- scout/server/blueprints/variants/templates/variants/mei-variants.html +2 -6
- scout/server/blueprints/variants/templates/variants/str-variants.html +8 -2
- scout/server/blueprints/variants/templates/variants/sv-variants.html +4 -8
- scout/server/blueprints/variants/templates/variants/variants.html +23 -18
- scout/server/blueprints/variants/views.py +6 -0
- scout/utils/acmg.py +155 -28
- scout/utils/scout_requests.py +8 -13
- {scout_browser-4.89.2.dist-info → scout_browser-4.90.dist-info}/METADATA +1 -1
- {scout_browser-4.89.2.dist-info → scout_browser-4.90.dist-info}/RECORD +50 -49
- {scout_browser-4.89.2.dist-info → scout_browser-4.90.dist-info}/LICENSE +0 -0
- {scout_browser-4.89.2.dist-info → scout_browser-4.90.dist-info}/WHEEL +0 -0
- {scout_browser-4.89.2.dist-info → scout_browser-4.90.dist-info}/entry_points.txt +0 -0
- {scout_browser-4.89.2.dist-info → scout_browser-4.90.dist-info}/top_level.txt +0 -0
scout/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "4.
|
1
|
+
__version__ = "4.90"
|
scout/adapter/mongo/panel.py
CHANGED
@@ -11,6 +11,7 @@ from bson import ObjectId
|
|
11
11
|
from bson.errors import InvalidId
|
12
12
|
|
13
13
|
from scout.build import build_panel
|
14
|
+
from scout.constants.panels import EXPORT_PANEL_FIELDS
|
14
15
|
from scout.exceptions import IntegrityError
|
15
16
|
from scout.parse.panel import get_omim_panel_genes
|
16
17
|
from scout.utils.date import get_date
|
@@ -245,8 +246,6 @@ class PanelHandler:
|
|
245
246
|
for panel in res:
|
246
247
|
return panel
|
247
248
|
|
248
|
-
LOG.warning("Gene panel not found")
|
249
|
-
|
250
249
|
return None
|
251
250
|
|
252
251
|
def gene_panels(self, panel_id=None, institute_id=None, version=None, include_hidden=False):
|
@@ -464,89 +463,53 @@ class PanelHandler:
|
|
464
463
|
)
|
465
464
|
return updated_panel
|
466
465
|
|
467
|
-
def apply_pending(self, panel_obj, version):
|
466
|
+
def apply_pending(self, panel_obj: dict, version: float) -> str:
|
468
467
|
"""Apply the pending changes to an existing gene panel or create a new version of the same panel.
|
469
468
|
|
470
|
-
Args:
|
471
|
-
panel_obj(dict): panel in database to update
|
472
|
-
version(double): panel version to update
|
473
|
-
|
474
469
|
Returns:
|
475
470
|
inserted_id(str): id of updated panel or the new one
|
476
471
|
"""
|
477
472
|
|
478
|
-
updates = {}
|
479
473
|
new_panel = deepcopy(panel_obj)
|
480
474
|
new_panel["pending"] = []
|
481
475
|
new_panel["date"] = dt.datetime.now()
|
482
|
-
info_fields = [
|
483
|
-
"disease_associated_transcripts",
|
484
|
-
"inheritance_models",
|
485
|
-
"custom_inheritance_models",
|
486
|
-
"reduced_penetrance",
|
487
|
-
"mosaicism",
|
488
|
-
"database_entry_version",
|
489
|
-
"comment",
|
490
|
-
]
|
491
476
|
new_genes = []
|
492
477
|
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
info = update.get("info", {})
|
501
|
-
gene_obj = {"hgnc_id": hgnc_id, "symbol": update["symbol"]}
|
502
|
-
|
503
|
-
for field in info_fields:
|
504
|
-
if field in info:
|
505
|
-
gene_obj[field] = info[field]
|
506
|
-
new_genes.append(gene_obj)
|
478
|
+
# Process 'add' actions and gather updates
|
479
|
+
updates = {u["hgnc_id"]: u for u in panel_obj.get("pending", []) if u["action"] != "add"}
|
480
|
+
new_genes += [
|
481
|
+
{"hgnc_id": u["hgnc_id"], "symbol": u["symbol"], **u.get("info", {})}
|
482
|
+
for u in panel_obj.get("pending", [])
|
483
|
+
if u["action"] == "add"
|
484
|
+
]
|
507
485
|
|
486
|
+
# Process existing genes
|
508
487
|
for gene in panel_obj.get("genes", []):
|
509
488
|
hgnc_id = gene["hgnc_id"]
|
489
|
+
update = updates.get(hgnc_id)
|
510
490
|
|
511
|
-
if
|
491
|
+
if not update: # No update, keep the gene
|
512
492
|
new_genes.append(gene)
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
info = current_update["info"]
|
518
|
-
|
519
|
-
# If action is delete we do not add the gene to new genes
|
520
|
-
if action == "delete":
|
521
|
-
continue
|
522
|
-
|
523
|
-
if action == "edit":
|
524
|
-
for field in info_fields:
|
525
|
-
if field in info:
|
526
|
-
gene[field] = info[field]
|
493
|
+
elif update["action"] == "edit": # Edit gene fields
|
494
|
+
for key in EXPORT_PANEL_FIELDS[2:]:
|
495
|
+
gene.pop(key[1], None) # Reset all fields except hgnc and symbol
|
496
|
+
gene.update(update["info"])
|
527
497
|
new_genes.append(gene)
|
498
|
+
# Skip 'delete' actions
|
528
499
|
|
529
500
|
new_panel["genes"] = new_genes
|
530
501
|
new_panel["version"] = float(version)
|
531
502
|
|
532
|
-
|
533
|
-
|
534
|
-
if new_panel["version"] == panel_obj["version"]:
|
535
|
-
# replace panel_obj with new_panel
|
503
|
+
# Update same version or create new version
|
504
|
+
if version == panel_obj["version"]:
|
536
505
|
result = self.panel_collection.find_one_and_replace(
|
537
|
-
{"_id": panel_obj["_id"]},
|
538
|
-
new_panel,
|
539
|
-
return_document=pymongo.ReturnDocument.AFTER,
|
506
|
+
{"_id": panel_obj["_id"]}, new_panel, return_document=pymongo.ReturnDocument.AFTER
|
540
507
|
)
|
541
508
|
inserted_id = result["_id"]
|
542
|
-
else:
|
509
|
+
else:
|
543
510
|
new_panel.pop("_id")
|
544
|
-
|
545
|
-
# archive the old panel
|
546
511
|
panel_obj["is_archived"] = True
|
547
512
|
self.update_panel(panel_obj=panel_obj, date_obj=panel_obj["date"])
|
548
|
-
|
549
|
-
# insert the new panel
|
550
513
|
inserted_id = self.panel_collection.insert_one(new_panel).inserted_id
|
551
514
|
|
552
515
|
return inserted_id
|
scout/adapter/mongo/query.py
CHANGED
@@ -691,6 +691,15 @@ class QueryHandler(object):
|
|
691
691
|
|
692
692
|
mongo_secondary_query.append(revel_query)
|
693
693
|
|
694
|
+
if criterion == "rank_score":
|
695
|
+
rank_score_query = {
|
696
|
+
"$or": [
|
697
|
+
{"rank_score": {"$gte": float(query["rank_score"])}},
|
698
|
+
{"rank_score": {"$exists": False}},
|
699
|
+
]
|
700
|
+
}
|
701
|
+
mongo_secondary_query.append(rank_score_query)
|
702
|
+
|
694
703
|
if criterion == "cadd_score":
|
695
704
|
cadd = query["cadd_score"]
|
696
705
|
cadd_query = {"cadd_score": {"$gt": float(cadd)}}
|
scout/build/panel.py
CHANGED
@@ -1,94 +1,58 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
import logging
|
3
|
-
from datetime import datetime as datetime
|
4
3
|
|
5
|
-
from scout.constants import VALID_MODELS
|
6
4
|
from scout.exceptions import IntegrityError
|
7
5
|
|
8
6
|
LOG = logging.getLogger(__name__)
|
9
7
|
|
10
8
|
|
11
|
-
def build_gene(gene_info, adapter):
|
12
|
-
"""Build a panel_gene object
|
9
|
+
def build_gene(gene_info: dict, adapter) -> dict:
|
10
|
+
"""Build a panel_gene object."""
|
13
11
|
|
14
|
-
Args:
|
15
|
-
gene_info(dict)
|
16
|
-
|
17
|
-
Returns:
|
18
|
-
gene_obj(dict)
|
19
|
-
|
20
|
-
panel_gene = dict(
|
21
|
-
hgnc_id = int, # required
|
22
|
-
symbol = str,
|
23
|
-
|
24
|
-
disease_associated_transcripts = list, # list of strings that represent refseq transcripts
|
25
|
-
reduced_penetrance = bool,
|
26
|
-
mosaicism = bool,
|
27
|
-
database_entry_version = str,
|
28
|
-
comment = str, # panel level gene comment str
|
29
|
-
|
30
|
-
ar = bool,
|
31
|
-
ad = bool,
|
32
|
-
mt = bool,
|
33
|
-
xr = bool,
|
34
|
-
xd = bool,
|
35
|
-
x = bool,
|
36
|
-
y = bool,
|
37
|
-
)
|
38
|
-
|
39
|
-
"""
|
40
12
|
symbol = gene_info.get("hgnc_symbol")
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
except KeyError as err:
|
47
|
-
raise KeyError(
|
48
|
-
"Gene {0} is missing hgnc id. Panel genes has to have hgnc_id".format(symbol)
|
49
|
-
)
|
13
|
+
hgnc_id = gene_info.get("hgnc_id")
|
14
|
+
|
15
|
+
# Validate presence of hgnc_id
|
16
|
+
if not hgnc_id:
|
17
|
+
raise KeyError(f"Gene {symbol} is missing hgnc id. Panel genes must have hgnc_id.")
|
50
18
|
|
19
|
+
# Try fetching gene information from either build "37" or "38"
|
51
20
|
hgnc_gene = adapter.hgnc_gene_caption(
|
52
21
|
hgnc_identifier=hgnc_id, build="37"
|
53
22
|
) or adapter.hgnc_gene_caption(hgnc_identifier=hgnc_id, build="38")
|
23
|
+
|
54
24
|
if hgnc_gene is None:
|
55
|
-
raise IntegrityError("hgnc_id {
|
25
|
+
raise IntegrityError(f"hgnc_id {hgnc_id} is not in the gene database!")
|
56
26
|
|
57
|
-
gene_obj =
|
27
|
+
gene_obj = {"hgnc_id": hgnc_id, "symbol": hgnc_gene["hgnc_symbol"]}
|
58
28
|
|
59
|
-
|
29
|
+
# Log warnings if symbols do not match
|
60
30
|
if symbol != gene_obj["symbol"]:
|
61
|
-
LOG.warning(
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
31
|
+
LOG.warning(f"Symbol in database does not match symbol in panel file for gene {hgnc_id}")
|
32
|
+
LOG.warning(f"Using symbol {gene_obj['symbol']} for gene {hgnc_id} instead of {symbol}")
|
33
|
+
|
34
|
+
# Add optional gene information
|
35
|
+
gene_obj.update(
|
36
|
+
{
|
37
|
+
key: gene_info[key]
|
38
|
+
for key in ["disease_associated_transcripts", "comment", "database_entry_version"]
|
39
|
+
if key in gene_info
|
40
|
+
}
|
41
|
+
)
|
42
|
+
|
43
|
+
# Add boolean flags
|
44
|
+
gene_obj.update(
|
45
|
+
{key: True for key in ["reduced_penetrance", "mosaicism"] if gene_info.get(key)}
|
46
|
+
)
|
47
|
+
|
48
|
+
# Handle inheritance models
|
49
|
+
if "inheritance_models" in gene_info:
|
50
|
+
gene_obj["inheritance_models"] = gene_info["inheritance_models"]
|
69
51
|
|
70
|
-
if
|
71
|
-
gene_obj["
|
72
|
-
|
73
|
-
|
74
|
-
if gene_info.get(gene_member_variable_str):
|
75
|
-
gene_obj[gene_member_variable_str] = gene_info[gene_member_variable_str]
|
76
|
-
|
77
|
-
for gene_member_variable_bool in ["reduced_penetrance", "mosaicism"]:
|
78
|
-
if gene_info.get(gene_member_variable_bool):
|
79
|
-
gene_obj[gene_member_variable_bool] = True
|
80
|
-
|
81
|
-
if gene_info.get("inheritance_models"):
|
82
|
-
gene_obj["inheritance_models"] = []
|
83
|
-
custom_models = []
|
84
|
-
for model in gene_info["inheritance_models"]:
|
85
|
-
if model not in VALID_MODELS:
|
86
|
-
custom_models.append(model)
|
87
|
-
continue
|
88
|
-
gene_obj["inheritance_models"].append(model)
|
89
|
-
lc_model = model.lower() # example ad = True
|
90
|
-
gene_obj[lc_model] = True
|
91
|
-
gene_obj["custom_inheritance_models"] = custom_models
|
52
|
+
if "custom_inheritance_models" in gene_info:
|
53
|
+
gene_obj["custom_inheritance_models"] = [
|
54
|
+
model for model in gene_info["custom_inheritance_models"]
|
55
|
+
]
|
92
56
|
|
93
57
|
return gene_obj
|
94
58
|
|
scout/constants/__init__.py
CHANGED
@@ -64,7 +64,6 @@ from .gene_tags import (
|
|
64
64
|
PANEL_GENE_INFO_TRANSCRIPTS,
|
65
65
|
PANELAPP_CONFIDENCE_EXCLUDE,
|
66
66
|
UPDATE_GENES_RESOURCES,
|
67
|
-
VALID_MODELS,
|
68
67
|
)
|
69
68
|
from .igv_tracks import CASE_SPECIFIC_TRACKS, HUMAN_REFERENCE, IGV_TRACKS, USER_DEFAULT_TRACKS
|
70
69
|
from .indexes import ID_PROJECTION, INDEXES
|
@@ -79,6 +78,7 @@ from .phenotype import (
|
|
79
78
|
from .query_terms import FUNDAMENTAL_CRITERIA, PRIMARY_CRITERIA, SECONDARY_CRITERIA
|
80
79
|
from .so_terms import SEVERE_SO_TERMS, SEVERE_SO_TERMS_SV, SO_TERM_KEYS, SO_TERMS
|
81
80
|
from .variant_tags import (
|
81
|
+
CALLERS,
|
82
82
|
CANCER_SPECIFIC_VARIANT_DISMISS_OPTIONS,
|
83
83
|
CANCER_TIER_OPTIONS,
|
84
84
|
CONSEQUENCE,
|
@@ -145,6 +145,33 @@ CHROMOSOMES_38 = AUTOSOMES + ["X", "Y", "M"]
|
|
145
145
|
# Maps chromosomes to integers
|
146
146
|
CHROMOSOME_INTEGERS = {chrom: i + 1 for i, chrom in enumerate(CHROMOSOMES)}
|
147
147
|
|
148
|
+
GENOME_REGION = {
|
149
|
+
"37": {
|
150
|
+
"smn1": {
|
151
|
+
"chrom": 5,
|
152
|
+
"start": 70247713,
|
153
|
+
"end": 70247832,
|
154
|
+
},
|
155
|
+
"smn2": {
|
156
|
+
"chrom": 5,
|
157
|
+
"start": 69372279,
|
158
|
+
"end": 69372427,
|
159
|
+
},
|
160
|
+
},
|
161
|
+
"38": {
|
162
|
+
"smn1": {
|
163
|
+
"chrom": 5,
|
164
|
+
"start": 70951877,
|
165
|
+
"end": 70952014,
|
166
|
+
},
|
167
|
+
"smn2": {
|
168
|
+
"chrom": 5,
|
169
|
+
"start": 70076451,
|
170
|
+
"end": 70076603,
|
171
|
+
},
|
172
|
+
},
|
173
|
+
}
|
174
|
+
|
148
175
|
|
149
176
|
PAR_COORDINATES = {
|
150
177
|
"37": {
|
@@ -181,50 +208,6 @@ PAR_COORDINATES = {
|
|
181
208
|
},
|
182
209
|
}
|
183
210
|
|
184
|
-
CALLERS = {
|
185
|
-
"snv": [
|
186
|
-
{"id": "gatk", "name": "GATK"},
|
187
|
-
{"id": "freebayes", "name": "Freebayes"},
|
188
|
-
{"id": "samtools", "name": "SAMtools"},
|
189
|
-
{"id": "bcftools", "name": "Bcftools"},
|
190
|
-
{"id": "deepvariant", "name": "DeepVariant"},
|
191
|
-
],
|
192
|
-
"cancer": [
|
193
|
-
{"id": "mutect", "name": "MuTect"},
|
194
|
-
{"id": "pindel", "name": "Pindel"},
|
195
|
-
{"id": "gatk", "name": "GATK"},
|
196
|
-
{"id": "freebayes", "name": "Freebayes"},
|
197
|
-
{"id": "tnscope", "name": "TNScope"},
|
198
|
-
{"id": "tnscope_umi", "name": "TNscope_UMI"},
|
199
|
-
{"id": "vardict", "name": "VarDict"},
|
200
|
-
],
|
201
|
-
"cancer_sv": [
|
202
|
-
{"id": "gatk", "name": "GATK"},
|
203
|
-
{"id": "manta", "name": "Manta"},
|
204
|
-
{"id": "dellysv", "name": "DellySV"},
|
205
|
-
{"id": "cnvkit", "name": "CNVkit"},
|
206
|
-
{"id": "ascat", "name": "ASCAT"},
|
207
|
-
{"id": "dellycnv", "name": "DellyCNV"},
|
208
|
-
{"id": "tiddit", "name": "TIDDIT"},
|
209
|
-
{"id": "igh_dux4", "name": "IGH-DUX4 detection"},
|
210
|
-
],
|
211
|
-
"mei": [{"id": "retroseq", "name": "RetroSeq"}],
|
212
|
-
"sv": [
|
213
|
-
{"id": "gatk", "name": "GATK"},
|
214
|
-
{"id": "cnvnator", "name": "CNVnator"},
|
215
|
-
{"id": "cnvpytor", "name": "CNVpytor"},
|
216
|
-
{"id": "delly", "name": "Delly"},
|
217
|
-
{"id": "sniffles", "name": "Sniffles"},
|
218
|
-
{"id": "tiddit", "name": "TIDDIT"},
|
219
|
-
{"id": "manta", "name": "Manta"},
|
220
|
-
],
|
221
|
-
"str": [{"id": "expansionhunter", "name": "ExpansionHunter"}],
|
222
|
-
"fusion": [
|
223
|
-
{"id": "arriba", "name": "Arriba"},
|
224
|
-
{"id": "starfusion", "name": "STARfusion"},
|
225
|
-
{"id": "fusioncatcher", "name": "FusionCatcher"},
|
226
|
-
],
|
227
|
-
}
|
228
211
|
|
229
212
|
BND_ALT_PATTERN = re.compile(r".*[\],\[](.*?):(.*?)[\],\[]")
|
230
213
|
CHR_PATTERN = re.compile(r"(chr)?(.*)", re.IGNORECASE)
|
scout/constants/acmg.py
CHANGED
@@ -47,7 +47,7 @@ ACMG_CRITERIA["pathogenicity"] = OrderedDict(
|
|
47
47
|
{
|
48
48
|
"short": "Null variant",
|
49
49
|
"description": "Null variant (nonsense, frameshift, canonical +/- 2 bp splice sites, initiation codon, single or multiexon deletion) in a gene where LOF is a known mechanism of disease.",
|
50
|
-
"documentation": 'Strength can be modified based on <a href="https://pubmed.ncbi.nlm.nih.gov/30192042/" target="_blank">Tayoun et al</a> and <a href="http://autopvs1.genetics.bgi.com/" target="_blank">AutoPVS1</a>.',
|
50
|
+
"documentation": 'Strength can be modified based on <a href="https://pubmed.ncbi.nlm.nih.gov/30192042/" target="_blank">Tayoun et al</a> and <a href="http://autopvs1.genetics.bgi.com/" target="_blank">AutoPVS1</a>, or for RNA <a href="https://www.clinicalgenome.org/docs/application-of-the-acmg-amp-framework-to-capture-evidence-relevant-to-predicted-and-observed-impact-on-splicing-recommendations/" target="_blank">Walker et al</a>.',
|
51
51
|
},
|
52
52
|
)
|
53
53
|
]
|
@@ -60,22 +60,24 @@ ACMG_CRITERIA["pathogenicity"] = OrderedDict(
|
|
60
60
|
(
|
61
61
|
"PS1",
|
62
62
|
{
|
63
|
-
"short": "Known pathogenic aa
|
63
|
+
"short": "Known pathogenic aa",
|
64
64
|
"description": "Same amino acid change as a previously established pathogenic variant regardless of nucleotide change",
|
65
65
|
},
|
66
66
|
),
|
67
67
|
(
|
68
68
|
"PS2",
|
69
69
|
{
|
70
|
-
"short": "De novo (confirmed)",
|
70
|
+
"short": "<i>De novo</i> (confirmed)",
|
71
71
|
"description": "De novo (both maternity and paternity confirmed) in a patient with the disease and no family history",
|
72
|
+
"documentation": 'Strength can be modified based on <a href="https://clinicalgenome.org/site/assets/files/3461/svi_proposal_for_de_novo_criteria_v1_1.pdf" target="_blank">SVI <i>de novo</i></a>.',
|
72
73
|
},
|
73
74
|
),
|
74
75
|
(
|
75
76
|
"PS3",
|
76
77
|
{
|
77
|
-
"short": "Functional damage
|
78
|
+
"short": "Functional damage",
|
78
79
|
"description": "Well-established in vitro or in vivo functional studies supportive of a damaging effect on the gene or gene product, and the evidence is strong",
|
80
|
+
"documentation": 'Strength can be modified based on <a href="https://clinicalgenome.org/docs/recommendations-for-application-of-the-functional-evidence-ps3-bs3-criterion-using-the-acmg-amp-sequence-variant-interpretation/" target="_blank">Brnich 2019</a>.',
|
79
81
|
},
|
80
82
|
),
|
81
83
|
(
|
@@ -113,7 +115,8 @@ ACMG_CRITERIA["pathogenicity"] = OrderedDict(
|
|
113
115
|
"PM3",
|
114
116
|
{
|
115
117
|
"short": "In trans pathogenic & AR",
|
116
|
-
"description": "For recessive disorders, detected in trans with a pathogenic variant
|
118
|
+
"description": "For recessive disorders, detected in trans with a pathogenic variant",
|
119
|
+
"documentation": 'Strength can be modified based on <a href="https://clinicalgenome.org/site/assets/files/3717/svi_proposal_for_pm3_criterion_-_version_1.pdf" target="_blank">SVI in <i>trans</i></a>.',
|
117
120
|
},
|
118
121
|
),
|
119
122
|
(
|
@@ -126,15 +129,16 @@ ACMG_CRITERIA["pathogenicity"] = OrderedDict(
|
|
126
129
|
(
|
127
130
|
"PM5",
|
128
131
|
{
|
129
|
-
"short": "Similar to known pathogenic aa
|
130
|
-
"description": "Novel missense change at an amino acid residue where a different missense change determined to be pathogenic has been seen before,
|
132
|
+
"short": "Similar to known pathogenic aa",
|
133
|
+
"description": "Novel missense change at an amino acid residue where a different missense change determined to be pathogenic has been seen before, the amino acids have similar properties and the evidence is strong",
|
131
134
|
},
|
132
135
|
),
|
133
136
|
(
|
134
137
|
"PM6",
|
135
138
|
{
|
136
|
-
"short": "De novo (unconfirmed)",
|
139
|
+
"short": "<i>De novo</i> (unconfirmed)",
|
137
140
|
"description": "Assumed de novo, but without confirmation of paternity and maternity",
|
141
|
+
"documentation": 'Strength can be modified based on <a href="https://clinicalgenome.org/site/assets/files/3461/svi_proposal_for_de_novo_criteria_v1_1.pdf" target="_blank">SVI <i>de novo</i></a>.',
|
138
142
|
},
|
139
143
|
),
|
140
144
|
]
|
@@ -147,22 +151,24 @@ ACMG_CRITERIA["pathogenicity"] = OrderedDict(
|
|
147
151
|
(
|
148
152
|
"PP1",
|
149
153
|
{
|
150
|
-
"short": "Cosegregation
|
154
|
+
"short": "Cosegregation",
|
151
155
|
"description": "Cosegregation with disease in multiple affected family members in a gene definitively known to cause the disease, and the evidence is weak",
|
156
|
+
"documentation": 'Strength can be modified based on <a href="https://clinicalgenome.org/docs/clingen-guidance-for-use-of-the-pp1-bs4-co-segregation-and-pp4-phenotype-specificity-criteria-for-sequence-variant/" target="_blank">Biesecker et al 2023</a>',
|
152
157
|
},
|
153
158
|
),
|
154
159
|
(
|
155
160
|
"PP2",
|
156
161
|
{
|
157
162
|
"short": "Missense: important",
|
158
|
-
"description": "Missense variant in a gene that has a low rate of benign missense variation and in which missense variants are a common mechanism of disease
|
163
|
+
"description": "Missense variant in a gene that has a low rate of benign missense variation and in which missense variants are a common mechanism of disease",
|
159
164
|
},
|
160
165
|
),
|
161
166
|
(
|
162
167
|
"PP3",
|
163
168
|
{
|
164
169
|
"short": "Predicted pathogenic",
|
165
|
-
"description": "Multiple lines of computational evidence support a deleterious effect on the gene or gene product (conservation, evolutionary, splicing impact, etc
|
170
|
+
"description": "Multiple lines of computational evidence support a deleterious effect on the gene or gene product (conservation, evolutionary, splicing impact, etc)",
|
171
|
+
"documentation": 'Strength can be modified based on <a href="https://clinicalgenome.org/docs/calibration-of-computational-tools-for-missense-variant-pathogenicity-classification-and-clingen-recommendations-for-pp3-bp4-cri/" target="_blank">Pejaver et al</a>',
|
166
172
|
},
|
167
173
|
),
|
168
174
|
(
|
@@ -170,6 +176,7 @@ ACMG_CRITERIA["pathogenicity"] = OrderedDict(
|
|
170
176
|
{
|
171
177
|
"short": "Phenotype: single gene",
|
172
178
|
"description": "Patient's phenotype or family history is highly specific for a disease with a single genetic etiology",
|
179
|
+
"documentation": 'Strength can be modified based on <a href="https://clinicalgenome.org/docs/clingen-guidance-for-use-of-the-pp1-bs4-co-segregation-and-pp4-phenotype-specificity-criteria-for-sequence-variant/" target="_blank">Biesecker et al 2023</a>',
|
173
180
|
},
|
174
181
|
),
|
175
182
|
(
|
@@ -177,6 +184,7 @@ ACMG_CRITERIA["pathogenicity"] = OrderedDict(
|
|
177
184
|
{
|
178
185
|
"short": "Reported pathogenic, evidence unavailable",
|
179
186
|
"description": "Reputable source recently reports variant as pathogenic, but the evidence is not available to the laboratory to perform an independent evaluation",
|
187
|
+
"documentation": 'Deprecated by ClinGen SVI <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6709533/" target="_blank">Biesecker et al 2018</a>.',
|
180
188
|
},
|
181
189
|
),
|
182
190
|
]
|
@@ -194,8 +202,9 @@ ACMG_CRITERIA["benign impact"] = OrderedDict(
|
|
194
202
|
(
|
195
203
|
"BA1",
|
196
204
|
{
|
197
|
-
"short": "Frequency >=
|
198
|
-
"description": "Allele frequency is >=
|
205
|
+
"short": "Frequency >=0.05",
|
206
|
+
"description": "Allele frequency is >=0.05 in a general continental population dataset",
|
207
|
+
"documentation": 'For clarification and exceptions see <a href="https://clinicalgenome.org/docs/updated-recommendation-for-the-benign-stand-alone-acmg-amp-criterion/" target="_blank">Ghosh et al</a>',
|
199
208
|
},
|
200
209
|
)
|
201
210
|
]
|
@@ -222,15 +231,17 @@ ACMG_CRITERIA["benign impact"] = OrderedDict(
|
|
222
231
|
(
|
223
232
|
"BS3",
|
224
233
|
{
|
225
|
-
"short": "No functional damage
|
234
|
+
"short": "No functional damage",
|
226
235
|
"description": "Well-established in vitro or in vivo functional studies show no damaging effect on protein function or splicing, and the evidence is strong",
|
236
|
+
"documentation": 'Strength can be modified based on <a href="https://clinicalgenome.org/docs/recommendations-for-application-of-the-functional-evidence-ps3-bs3-criterion-using-the-acmg-amp-sequence-variant-interpretation/" target="_blank">Brnich 2019</a>.',
|
227
237
|
},
|
228
238
|
),
|
229
239
|
(
|
230
240
|
"BS4",
|
231
241
|
{
|
232
|
-
"short": "Non-segregation
|
242
|
+
"short": "Non-segregation",
|
233
243
|
"description": "Lack of segregation in affected members of a family, and the evidence is strong",
|
244
|
+
"documentation": 'Strength can be modified based on <a href="https://clinicalgenome.org/docs/clingen-guidance-for-use-of-the-pp1-bs4-co-segregation-and-pp4-phenotype-specificity-criteria-for-sequence-variant/" target="_blank">Biesecker et al 2023</a>',
|
234
245
|
},
|
235
246
|
),
|
236
247
|
]
|
@@ -280,12 +291,13 @@ ACMG_CRITERIA["benign impact"] = OrderedDict(
|
|
280
291
|
{
|
281
292
|
"short": "Reported benign, evidence unavailable",
|
282
293
|
"description": "Reputable source recently reports variant as benign, but the evidence is not available to the laboratory to perform an independent evaluation",
|
294
|
+
"documentation": 'Deprecated by ClinGen SVI <a href="https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6709533/" target="_blank">Biesecker et al</a>.',
|
283
295
|
},
|
284
296
|
),
|
285
297
|
(
|
286
298
|
"BP7",
|
287
299
|
{
|
288
|
-
"short": "
|
300
|
+
"short": "Synonymous, no impact on splicing",
|
289
301
|
"description": "A synonymous variant for which splicing prediction algorithms predict no impact to the splice consensus sequence nor the creation of a new splice site",
|
290
302
|
},
|
291
303
|
),
|
@@ -294,3 +306,51 @@ ACMG_CRITERIA["benign impact"] = OrderedDict(
|
|
294
306
|
),
|
295
307
|
]
|
296
308
|
)
|
309
|
+
|
310
|
+
ACMG_POTENTIAL_CONFLICTS = [
|
311
|
+
(
|
312
|
+
"PVS1",
|
313
|
+
"PM4",
|
314
|
+
"Use of PVS1 and PM4 together risks double-counting evidence (Tayoun et al 2019).",
|
315
|
+
),
|
316
|
+
(
|
317
|
+
"PVS1",
|
318
|
+
"PM1",
|
319
|
+
"Use of PVS1 and PM1 together is not recommended (Durkie et al 2024).",
|
320
|
+
),
|
321
|
+
(
|
322
|
+
"PVS1",
|
323
|
+
"PP2",
|
324
|
+
"Use of PVS1 and PP2 together is not recommended (Durkie et al 2024).",
|
325
|
+
),
|
326
|
+
(
|
327
|
+
"PVS1",
|
328
|
+
"PS3",
|
329
|
+
"Note that for RNA PS3 should only be taken with PVS1 for well established functional assays, not splicing alone (Walker 2023).",
|
330
|
+
),
|
331
|
+
(
|
332
|
+
"PS1",
|
333
|
+
"PM4",
|
334
|
+
"Use of PS1 and PM4 together is not recommended (Durkie et al 2024).",
|
335
|
+
),
|
336
|
+
(
|
337
|
+
"PS1",
|
338
|
+
"PM5",
|
339
|
+
"Use of PS1 and PM5 together conflicts with original definition (Richards et al 2015).",
|
340
|
+
),
|
341
|
+
(
|
342
|
+
"PS1",
|
343
|
+
"PP3",
|
344
|
+
"Use of PS1 and PP3 together risks double-counting evidence (Tayoun et al 2019).",
|
345
|
+
),
|
346
|
+
(
|
347
|
+
"PS2",
|
348
|
+
"PM6",
|
349
|
+
"Use of PS2 and PM6 together conflicts with original definition (Richards et al 2015).",
|
350
|
+
),
|
351
|
+
(
|
352
|
+
"PM1",
|
353
|
+
"PP2",
|
354
|
+
"Avoid double-counting evidence for constraints in both PM1 and PP2 (Durkie et al 2024).",
|
355
|
+
),
|
356
|
+
]
|
scout/constants/gene_tags.py
CHANGED
@@ -8,6 +8,8 @@ GENE_PANELS_INHERITANCE_MODELS = (
|
|
8
8
|
("XL", "XL - X Linked"),
|
9
9
|
("XD", "XD - X Linked Dominant"),
|
10
10
|
("XR", "XR - X Linked Recessive"),
|
11
|
+
("Y", "Y-linked"),
|
12
|
+
("MT", "Mitochondrial inheritance"),
|
11
13
|
("NA", "NA - not available"),
|
12
14
|
("AD (imprinting)", "AD (imprinting) - Autosomal Dominant (imprinting)"),
|
13
15
|
("digenic", "digenic - Digenic"),
|
@@ -21,6 +23,8 @@ INHERITANCE_PALETTE = {
|
|
21
23
|
"AD (imprinting)": {"bgcolor": "bg-cyan", "text_color": "text-dark"},
|
22
24
|
"AR": {"bgcolor": "bg-pink", "text_color": "text-white"},
|
23
25
|
"XL": {"bgcolor": "bg-purple", "text_color": "text-white"},
|
26
|
+
"Y": {"bgcolor": "bg-purple", "text_color": "text-white"},
|
27
|
+
"MT": {"bgcolor": "bg-purple", "text_color": "text-white"},
|
24
28
|
"XD": {"bgcolor": "bg-gray-dark", "text_color": "text-white"},
|
25
29
|
"XR": {"bgcolor": "bg-green", "text_color": "text-white"},
|
26
30
|
"NA": {"bgcolor": "bg-light", "text_color": "text-dark"},
|
@@ -29,8 +33,6 @@ INHERITANCE_PALETTE = {
|
|
29
33
|
"other": {"bgcolor": "bg-light", "text_color": "text-dark"},
|
30
34
|
}
|
31
35
|
|
32
|
-
VALID_MODELS = ("AR", "AD", "MT", "XD", "XR", "X", "Y")
|
33
|
-
|
34
36
|
INCOMPLETE_PENETRANCE_MAP = {"unknown": None, "Complete": None, "Incomplete": True}
|
35
37
|
|
36
38
|
MODELS_MAP = {
|
@@ -0,0 +1,11 @@
|
|
1
|
+
EXPORT_PANEL_FIELDS = [
|
2
|
+
("#hgnc_id", "hgnc_id"),
|
3
|
+
("symbol", "symbol"),
|
4
|
+
("disease_associated_transcripts", "disease_associated_transcripts"),
|
5
|
+
("reduced_penetrance", "reduced_penetrance"),
|
6
|
+
("mosaicism", "mosaicism"),
|
7
|
+
("database_entry_version", "database_entry_version"),
|
8
|
+
("inheritance_models", "inheritance_models"),
|
9
|
+
("custom_inheritance_models", "custom_inheritance_models"),
|
10
|
+
("comment", "comment"),
|
11
|
+
]
|