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
scout/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "4.89.2"
1
+ __version__ = "4.90.1"
@@ -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
- for update in panel_obj.get("pending", []):
494
- hgnc_id = update["hgnc_id"]
495
-
496
- # If action is add we create a new gene object
497
- if update["action"] != "add":
498
- updates[hgnc_id] = update
499
- continue
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 hgnc_id not in updates:
491
+ if not update: # No update, keep the gene
512
492
  new_genes.append(gene)
513
- continue
514
-
515
- current_update = updates[hgnc_id]
516
- action = current_update["action"]
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
- inserted_id = None
533
- # if the same version of the panel should be updated
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: # create a new version of the same panel
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
@@ -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
- try:
42
- # A gene has to have a hgnc id
43
- hgnc_id = gene_info["hgnc_id"]
44
- if not hgnc_id:
45
- raise KeyError()
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 {0} is not in the gene database!".format(hgnc_id))
25
+ raise IntegrityError(f"hgnc_id {hgnc_id} is not in the gene database!")
56
26
 
57
- gene_obj = dict(hgnc_id=hgnc_id)
27
+ gene_obj = {"hgnc_id": hgnc_id, "symbol": hgnc_gene["hgnc_symbol"]}
58
28
 
59
- gene_obj["symbol"] = hgnc_gene["hgnc_symbol"]
29
+ # Log warnings if symbols do not match
60
30
  if symbol != gene_obj["symbol"]:
61
- LOG.warning(
62
- "Symbol in database does not correspond to symbol in panel file for gene %s",
63
- hgnc_id,
64
- )
65
- LOG.warning(
66
- "Using symbol %s for gene %s, instead of %s"
67
- % (hgnc_gene["hgnc_symbol"], hgnc_id, symbol)
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 gene_info.get("transcripts"):
71
- gene_obj["disease_associated_transcripts"] = gene_info["transcripts"]
72
-
73
- for gene_member_variable_str in ["comment", "database_entry_version"]:
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
 
@@ -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 (HQ)",
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 (HQ)",
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 (HQ)",
130
- "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",
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 (WQ)",
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 >=hi_freq_cutoff",
198
- "description": "Allele frequency is >=hi_freq_cutoff in ESP, 1000G or ExAC",
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 (HQ)",
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 (HQ)",
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": "(not in use)",
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
+ ]
@@ -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
+ ]
@@ -61,4 +61,5 @@ SECONDARY_CRITERIA = [
61
61
  "junction_reads",
62
62
  "split_reads",
63
63
  "fusion_caller",
64
+ "rank_score",
64
65
  ]