scout-browser 4.95.0__py3-none-any.whl → 4.96.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. scout/adapter/mongo/case.py +26 -25
  2. scout/build/case.py +3 -1
  3. scout/constants/acmg.py +25 -18
  4. scout/demo/cancer.load_config.yaml +1 -3
  5. scout/demo/rnafusion.load_config.yaml +1 -0
  6. scout/models/case/case_loading_models.py +3 -0
  7. scout/parse/case.py +1 -0
  8. scout/server/app.py +12 -0
  9. scout/server/blueprints/cases/controllers.py +2 -0
  10. scout/server/blueprints/cases/templates/cases/case_report.html +28 -2
  11. scout/server/blueprints/cases/templates/cases/collapsible_actionbar.html +12 -0
  12. scout/server/blueprints/clinvar/controllers.py +1 -0
  13. scout/server/blueprints/clinvar/templates/clinvar/clinvar_submissions.html +10 -14
  14. scout/server/blueprints/clinvar/views.py +18 -31
  15. scout/server/blueprints/variant/templates/variant/cancer-variant.html +2 -2
  16. scout/server/blueprints/variant/templates/variant/variant_details.html +1 -1
  17. scout/server/blueprints/variant/views.py +10 -3
  18. scout/server/blueprints/variants/templates/variants/cancer-variants.html +5 -4
  19. scout/server/blueprints/variants/templates/variants/str-variants.html +13 -9
  20. scout/server/extensions/clinvar_extension.py +56 -2
  21. scout/server/links.py +0 -14
  22. scout/utils/acmg.py +5 -5
  23. {scout_browser-4.95.0.dist-info → scout_browser-4.96.0.dist-info}/METADATA +1 -1
  24. {scout_browser-4.95.0.dist-info → scout_browser-4.96.0.dist-info}/RECORD +27 -27
  25. {scout_browser-4.95.0.dist-info → scout_browser-4.96.0.dist-info}/WHEEL +0 -0
  26. {scout_browser-4.95.0.dist-info → scout_browser-4.96.0.dist-info}/entry_points.txt +0 -0
  27. {scout_browser-4.95.0.dist-info → scout_browser-4.96.0.dist-info}/licenses/LICENSE +0 -0
@@ -982,7 +982,6 @@ class CaseHandler(object):
982
982
  variant_type=variant_type,
983
983
  category=category,
984
984
  )
985
- # add variants
986
985
  self.load_variants(
987
986
  case_obj=case_obj,
988
987
  variant_type=variant_type,
@@ -994,33 +993,34 @@ class CaseHandler(object):
994
993
  ),
995
994
  )
996
995
 
997
- except (IntegrityError, ValueError, ConfigError, KeyError) as error:
998
- LOG.warning(error)
999
-
1000
- self._load_omics_variants(case_obj, build=genome_build, update=update)
1001
-
1002
- if existing_case:
1003
- self.update_case_data_sharing(old_case=existing_case, new_case=case_obj)
1004
- case_obj["rerun_requested"] = False
1005
- if case_obj["status"] in ["active", "archived"]:
1006
- case_obj["status"] = "inactive"
1007
-
1008
- case_obj["variants_stats"] = self.case_variants_count(
1009
- case_id=case_obj["_id"],
1010
- institute_id=institute_obj["_id"],
1011
- force_update_case=True,
1012
- )
996
+ self._load_omics_variants(case_obj, build=genome_build, update=update)
1013
997
 
1014
- self.update_case_cli(case_obj, institute_obj)
1015
- # update Sanger status for the new inserted variants
1016
- self.update_case_sanger_variants(institute_obj, case_obj, old_sanger_variants)
998
+ except (IntegrityError, ValueError, ConfigError, KeyError) as error:
999
+ LOG.exception(error)
1000
+ raise error
1001
+ else:
1002
+ if not existing_case:
1003
+ LOG.info("Loading case %s into database", case_obj["display_name"])
1004
+ self.add_case(case_obj, institute_obj)
1005
+ finally:
1006
+ if existing_case:
1007
+ self.update_case_data_sharing(old_case=existing_case, new_case=case_obj)
1008
+ case_obj["rerun_requested"] = False
1009
+ if case_obj["status"] in ["active", "archived"]:
1010
+ case_obj["status"] = "inactive"
1011
+
1012
+ case_obj["variants_stats"] = self.case_variants_count(
1013
+ case_id=case_obj["_id"],
1014
+ institute_id=institute_obj["_id"],
1015
+ force_update_case=True,
1016
+ )
1017
1017
 
1018
- if keep_actions and old_evaluated_variants:
1019
- self.update_variant_actions(institute_obj, case_obj, old_evaluated_variants)
1018
+ self.update_case_cli(case_obj, institute_obj)
1019
+ # update Sanger status for the new inserted variants
1020
+ self.update_case_sanger_variants(institute_obj, case_obj, old_sanger_variants)
1020
1021
 
1021
- else:
1022
- LOG.info("Loading case %s into database", case_obj["display_name"])
1023
- self.add_case(case_obj, institute_obj)
1022
+ if keep_actions and old_evaluated_variants:
1023
+ self.update_variant_actions(institute_obj, case_obj, old_evaluated_variants)
1024
1024
 
1025
1025
  return case_obj
1026
1026
 
@@ -1146,6 +1146,7 @@ class CaseHandler(object):
1146
1146
  "RNAfusion_report": case_obj.get("RNAfusion_report"),
1147
1147
  "RNAfusion_report_research": case_obj.get("RNAfusion_report_research"),
1148
1148
  "rna_delivery_report": case_obj.get("rna_delivery_report"),
1149
+ "scout_load_version": case_obj.get("scout_load_version"),
1149
1150
  "smn_tsv": case_obj.get("smn_tsv"),
1150
1151
  "status": case_obj.get("status"),
1151
1152
  "sv_rank_model_version": case_obj.get("sv_rank_model_version"),
scout/build/case.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import logging
2
2
  from datetime import datetime
3
3
  from typing import Dict
4
+ from scout import __version__
4
5
 
5
6
  from scout.constants import CUSTOM_CASE_REPORTS, PHENOTYPE_GROUPS
6
7
  from scout.exceptions import ConfigError, IntegrityError
@@ -154,6 +155,7 @@ def build_case(case_data, adapter):
154
155
  now = datetime.now()
155
156
  case_obj["created_at"] = now
156
157
  case_obj["updated_at"] = now
158
+ case_obj["scout_load_version"] = __version__
157
159
 
158
160
  if case_data.get("suspects"):
159
161
  case_obj["suspects"] = case_data["suspects"]
@@ -162,7 +164,7 @@ def build_case(case_data, adapter):
162
164
 
163
165
  case_obj["synopsis"] = case_data.get("synopsis", "")
164
166
 
165
- case_obj["status"] = "inactive"
167
+ case_obj["status"] = case_data.get("status") or "inactive"
166
168
  case_obj["is_research"] = False
167
169
  case_obj["research_requested"] = False
168
170
  case_obj["rerun_requested"] = False
scout/constants/acmg.py CHANGED
@@ -309,48 +309,55 @@ ACMG_CRITERIA["benign impact"] = OrderedDict(
309
309
 
310
310
  ACMG_POTENTIAL_CONFLICTS = [
311
311
  (
312
- "PVS1",
313
- "PM4",
312
+ {"PVS1", "PM4"},
314
313
  "Use of PVS1 and PM4 together risks double-counting evidence (Tayoun et al 2019).",
315
314
  ),
316
315
  (
317
- "PVS1",
318
- "PM1",
316
+ {"PVS1", "PM1"},
319
317
  "Use of PVS1 and PM1 together is not recommended (Durkie et al 2024).",
320
318
  ),
321
319
  (
322
- "PVS1",
323
- "PP2",
320
+ {"PVS1", "PP2"},
324
321
  "Use of PVS1 and PP2 together is not recommended (Durkie et al 2024).",
325
322
  ),
326
323
  (
327
- "PVS1",
328
- "PS3",
324
+ {"PVS1", "PS3"},
329
325
  "Note that for RNA PS3 should only be taken with PVS1 for well established functional assays, not splicing alone (Walker 2023).",
330
326
  ),
331
327
  (
332
- "PS1",
333
- "PM4",
328
+ {"PS1", "PM4"},
334
329
  "Use of PS1 and PM4 together is not recommended (Durkie et al 2024).",
335
330
  ),
336
331
  (
337
- "PS1",
338
- "PM5",
332
+ {"PS1", "PM5"},
339
333
  "Use of PS1 and PM5 together conflicts with original definition (Richards et al 2015).",
340
334
  ),
341
335
  (
342
- "PS1",
343
- "PP3",
336
+ {"PS1", "PP3"},
344
337
  "Use of PS1 and PP3 together risks double-counting evidence (Tayoun et al 2019).",
345
338
  ),
346
339
  (
347
- "PS2",
348
- "PM6",
340
+ {"PS2", "PM6"},
349
341
  "Use of PS2 and PM6 together conflicts with original definition (Richards et al 2015).",
350
342
  ),
351
343
  (
352
- "PM1",
353
- "PP2",
344
+ {"PM1", "PP2"},
354
345
  "Avoid double-counting evidence for constraints in both PM1 and PP2 (Durkie et al 2024).",
355
346
  ),
347
+ (
348
+ {"PP1", "PP4"},
349
+ "When applying phenotype specificity and segregation data together, a point-system is available from ClinGen SVI (Biesecker et al 2024).",
350
+ ),
351
+ (
352
+ {"BS4", "PP4"},
353
+ "When applying phenotype specificity and segregation data together, a point-system is available from ClinGen SVI (Biesecker et al 2024).",
354
+ ),
355
+ (
356
+ {"PS2", "PP4"},
357
+ "Consider using PS2 without the PP4 criterion, based on the SVI Recommendation for de novo Criteria (PS2 & PM6).",
358
+ ),
359
+ (
360
+ {"PM6", "PP4"},
361
+ "Consider using PM6 without the PP4 criterion, based on the SVI Recommendation for de novo Criteria (PS2 & PM6).",
362
+ ),
356
363
  ]
@@ -44,9 +44,7 @@ delivery_report: scout/demo/delivery_report.html
44
44
  cnv_report: scout/demo/cancer_cnv_report.pdf
45
45
  coverage_qc_report: scout/demo/cancer_coverage_qc_report.html
46
46
 
47
-
48
- # meta data
49
- rank_model_version: '1.1'
47
+ # metadata
50
48
  rank_score_threshold: -100
51
49
  analysis_date: 2018-10-12 14:00:46
52
50
  human_genome_build: '37'
@@ -22,3 +22,4 @@ RNAfusion_inspector_research: scout/demo/rnafusion_inspector_example.html
22
22
  analysis_date: 2022-11-02 14:00:46
23
23
  human_genome_build: '38'
24
24
  track: cancer
25
+ status: 'prioritized'
@@ -8,6 +8,8 @@ from os.path import abspath, dirname, exists, isabs
8
8
  from pathlib import Path
9
9
  from typing import Any, Dict, List, Optional, Tuple, Union
10
10
 
11
+ from scout.constants import CASE_STATUSES
12
+
11
13
  try:
12
14
  from typing import Literal
13
15
  except ImportError:
@@ -436,6 +438,7 @@ class CaseLoader(BaseModel):
436
438
  smn_tsv: Optional[str] = None
437
439
  sv_rank_model_version: Optional[str] = None
438
440
  synopsis: Optional[Union[List[str], str]] = None
441
+ status: Optional[Literal[tuple(CASE_STATUSES)]] = None
439
442
  track: Literal["rare", "cancer"] = "rare"
440
443
  vcf_files: Optional[VcfFiles]
441
444
 
scout/parse/case.py CHANGED
@@ -34,6 +34,7 @@ def parse_case_data(**kwargs):
34
34
  RNAfusion_report: Path to the RNA fusion report
35
35
  RNAfusion_report_research: Path to the research RNA fusion report
36
36
  smn_tsv(str): Path to an SMN tsv file
37
+ status(str): Optional case status ("prioritized", "inactive", "ignored", "active", "solved", "archived")
37
38
  vcf_cancer(str): Path to a vcf file
38
39
  vcf_cancer_sv(str): Path to a vcf file
39
40
  vcf_fusion(str): Path to a vcf file
scout/server/app.py CHANGED
@@ -13,6 +13,7 @@ from flask_login import current_user
13
13
  from markdown import markdown as python_markdown
14
14
  from markupsafe import Markup
15
15
 
16
+ from scout.constants import SPIDEX_HUMAN
16
17
  from scout.log import init_log
17
18
 
18
19
  from . import extensions
@@ -199,6 +200,17 @@ def register_filters(app):
199
200
  return "{:,}".format(int(value)).replace(",", " ")
200
201
  return value
201
202
 
203
+ @app.template_filter()
204
+ def spidex_human(spidex):
205
+ """Translate SPIDEX annotation to human readable string."""
206
+ if spidex is None:
207
+ return "not_reported"
208
+ if abs(spidex) < SPIDEX_HUMAN["low"]["pos"][1]:
209
+ return "low"
210
+ if abs(spidex) < SPIDEX_HUMAN["medium"]["pos"][1]:
211
+ return "medium"
212
+ return "high"
213
+
202
214
  @app.template_filter()
203
215
  def human_decimal(number, ndigits=4):
204
216
  """Return a standard representation of a decimal number.
@@ -13,6 +13,7 @@ from flask_login import current_user
13
13
  from requests.auth import HTTPBasicAuth
14
14
  from xlsxwriter import Workbook
15
15
 
16
+ from scout import __version__
16
17
  from scout.adapter import MongoAdapter
17
18
  from scout.constants import (
18
19
  CANCER_PHENOTYPE_MAP,
@@ -757,6 +758,7 @@ def case_report_content(store: MongoAdapter, institute_obj: dict, case_obj: dict
757
758
  data["manual_rank_options"] = MANUAL_RANK_OPTIONS
758
759
  data["genetic_models"] = dict(GENETIC_MODELS)
759
760
  data["report_created_at"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
761
+ data["current_scout_version"] = __version__
760
762
 
761
763
  case_report_variants(store, case_obj, institute_obj, data)
762
764
 
@@ -63,7 +63,7 @@
63
63
  </nav>
64
64
 
65
65
  <div id="container" class="container">
66
- <h4>Scout case analysis report</h4> - created on:&nbsp;<strong>{{report_created_at}}</strong><br><br>
66
+ <h4>Scout case analysis report</h4> - created on:&nbsp;<strong>{{report_created_at}}</strong> using <strong>Scout v.{{current_scout_version}}</strong><br><br>
67
67
  {{ phenotype_panel() }}
68
68
  {{ gene_panels_panel()}}
69
69
  {{ causatives_panel()}}
@@ -101,8 +101,11 @@
101
101
  <td>
102
102
  <table class="table table-sm">
103
103
  <tr>
104
- <td>Case created: <strong>{{case.created_at.strftime('%Y-%m-%d')}}</strong></td>
104
+ <td>Case created: <strong>{{case.created_at.strftime('%Y-%m-%d')}}</strong></td>
105
105
  <td>Last updated: <strong>{{case.updated_at.strftime('%Y-%m-%d') if case.updated_at else "n.a." }}</strong></td>
106
+ {% if case.scout_load_version %}
107
+ <td> Loaded with <strong>Scout v.{{case.scout_load_version}}</strong></td>
108
+ {% endif %}
106
109
  </tr>
107
110
  </table>
108
111
  <br>
@@ -746,12 +749,34 @@
746
749
  </tr>
747
750
  </tbody>
748
751
  </table>
752
+ <table id="severity-table" class="table table-sm" style="background-color: transparent">
753
+ <thead>
754
+ <tr>
755
+ <th>SIFT</th>
756
+ <th>REVEL score</th>
757
+ <th>REVEL rank score</th>
758
+ <th>Polyphen</th>
759
+ <th>SPIDEX</th>
760
+ <th>SpliceAI DS max</th>
761
+ </thead>
762
+ <tbody>
763
+ <tr>
764
+ <td>{{ variant.sift_predictions|join(', ') or '-'}}</td>
765
+ <td>{{ variant.revel or '-' }}</td>
766
+ <td>{{ variant.revel_score or '-' }}</td>
767
+ <td>{{ variant.polyphen_predictions|join(', ') or '-' }}</td>
768
+ <td>{{ variant.spidex|spidex_human if variant.spidex else none|spidex_human }}</td>
769
+ <td>{{ variant.spliceai_scores|join(', ') or '-' }}</td>
770
+ </tr>
771
+ </tbody>
772
+ </table>
749
773
  <table id="panel-table" class="table table-sm" style="background-color: transparent">
750
774
  <thead>
751
775
  <tr>
752
776
  <th>Affected gene(s)</th>
753
777
  <th>Description</th>
754
778
  <th>Region annotation</th>
779
+ <th>Consequence</th>
755
780
  <th>Transcript - HGVS - Protein</th>
756
781
  <th>Diagnoses [inheritance]</th>
757
782
  </tr>
@@ -767,6 +792,7 @@
767
792
  </td>
768
793
  <td>{{gene.description|title}}</td>
769
794
  <td>{{gene.region_annotation}}</td>
795
+ <td>{{gene.functional_annotation.replace("_"," ")|truncate(20, True)}}</td>
770
796
  <td>
771
797
  {{ variant_transcripts(gene) }}
772
798
  </td>
@@ -15,6 +15,7 @@
15
15
  {{ reports(institute,case, report_types) }}
16
16
  {{ default_gene_panel(institute, case) }}
17
17
  {{ analysis_date(case) }}
18
+ {{ software_version(case) }}
18
19
  {{ genome_build(case, case_groups, has_rna_tracks) }}
19
20
  {{ rank_model(case) }}
20
21
  <li class="list-group-item bg-dark sidebar-separator menu-collapsed"></li>
@@ -190,6 +191,17 @@
190
191
  {% endif %}
191
192
  {% endmacro %}
192
193
 
194
+ {% macro software_version(case) %}
195
+ {% if case.scout_load_version%}
196
+ <div href="#" class="bg-dark list-group-item text-white" data-bs-toggle="tooltip" title="Scout version used for loading the case" data-bs-placement="right">
197
+ <div class="d-flex w-100 justify-content-start align-items-center">
198
+ <span class="fa fa-gear fa-fw me-3"></span>
199
+ <span class="menu-collapsed">v.{{ case.scout_load_version }}</span>
200
+ </div>
201
+ </div>
202
+ {% endif %}
203
+ {% endmacro %}
204
+
193
205
  {% macro genome_build(case, case_groups, has_rna_tracks) %}
194
206
  <div href="#" class="bg-dark list-group-item text-white">
195
207
  <div class="d-flex w-100 justify-content-start align-items-center">
@@ -363,6 +363,7 @@ def update_clinvar_submission_status(request_obj, institute_id, submission_id):
363
363
  f"Removed {deleted_objects} objects and {deleted_submissions} submission from database",
364
364
  "info",
365
365
  )
366
+
366
367
  if update_status == "submit":
367
368
  submitter_key = request_obj.form.get("apiKey")
368
369
  send_api_submission(institute_id, submission_id, submitter_key)
@@ -58,13 +58,6 @@
58
58
  <nav aria-label="breadcrumb">
59
59
  <ol class="breadcrumb align-items-center">
60
60
  <li class="breadcrumb-item">
61
- <!-- Download the Variant data CSV file -->
62
- <a href="{{ url_for('clinvar.clinvar_download_csv', submission=subm_obj._id, csv_type='variant_data', clinvar_id=subm_obj.clinvar_subm_id or 'None') }}" class="btn btn-primary btn-xs text-white" target="_blank" rel="noopener">
63
- Download variants csv file
64
- </a>
65
- <a href=" {{ url_for('clinvar.clinvar_download_csv', submission=subm_obj._id, csv_type='case_data', clinvar_id=subm_obj.clinvar_subm_id or 'None') }}" class="btn btn-primary btn-xs text-white" target="_blank" rel="noopener">
66
- Download casedata csv file
67
- </a>
68
61
  <a id="download_clinvar_json" href="{{ url_for('clinvar.clinvar_download_json', submission=subm_obj._id, clinvar_id=subm_obj.clinvar_subm_id or 'None') }}" class="btn btn-primary btn-xs text-white" target="_blank" rel="noopener">
69
62
  Download submission json file
70
63
  </a>
@@ -77,8 +70,7 @@
77
70
  {% if subm_obj.status != 'submitted' %}
78
71
  <li class="breadcrumb-item"><button type="submit" name="update_submission" value="submitted" class="btn btn-success btn-xs">Mark as submitted</button></li>
79
72
  {% endif %}
80
-
81
- <li class="breadcrumb-item"><button type="submit" name="update_submission" value="delete" class="btn btn-danger btn-xs">Delete submission</button></li>
73
+ <li class="breadcrumb-item"><button type="submit" name="update_submission" value="delete" class="btn btn-danger btn-xs">Delete submission from Scout</button></li>
82
74
  </ol>
83
75
  </nav>
84
76
  </form>
@@ -101,9 +93,13 @@
101
93
  {% endif %}
102
94
  {% if subm_obj.status == 'submitted' %} <!--Submission status query -->
103
95
  <form id="statusApi_{{subm_obj._id}}" action="{{ url_for('clinvar.clinvar_submission_status', submission_id=subm_obj.clinvar_subm_id) }}" method="POST">
104
- {{ status_modal(subm_obj._id) }}
96
+ {{ action_modal("status", subm_obj._id) }}
105
97
  <td style="width: 20%"><button type="button" class="btn btn-sm btn-secondary form-control" name="status_enquiry" value="api_status" data-bs-toggle="modal" data-bs-target="#statusModal_{{subm_obj._id}}">Submission status enquiry</button></td>
106
98
  </form>
99
+ <form id="deleteApi_{{subm_obj._id}}" action="{{ url_for('clinvar.clinvar_submission_delete', submission_id=subm_obj.clinvar_subm_id) }}" method="POST">
100
+ {{ action_modal("remove", subm_obj._id) }}
101
+ <td style="width: 20%"><button type="button" class="btn btn-sm btn-danger form-control" name="_enquiry" value="api_status" data-bs-toggle="modal" data-bs-target="#removeModal_{{subm_obj._id}}">Delete submission from ClinVar</button></td>
102
+ </form>
107
103
  {% endif %}
108
104
  </tr>
109
105
  </table>
@@ -246,12 +242,12 @@
246
242
  </div>
247
243
  {% endmacro %}
248
244
 
249
- {% macro status_modal(subm_id) %}
250
- <div class="modal fade" id="statusModal_{{subm_id}}" tabindex="-1">
245
+ {% macro action_modal(action_type, subm_id) %}
246
+ <div class="modal fade" id="{{action_type}}Modal_{{subm_id}}" tabindex="-1">
251
247
  <div class="modal-dialog">
252
248
  <div class="modal-content">
253
249
  <div class="modal-header">
254
- <h5 class="modal-title">Submission status</h5>
250
+ <h5 class="modal-title">Submission {{action_type}}</h5>
255
251
  <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
256
252
  </div>
257
253
  <div class="modal-body">
@@ -260,7 +256,7 @@
260
256
  </div>
261
257
  <div class="modal-footer">
262
258
  <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
263
- <button type="submit" name="show_status" value="status" class="btn btn-primary">Submission status enquiry</button>
259
+ <button type="submit" name="{{action_type}}" value="{{action_type}}" class="btn btn-primary">Submission {{action_type}} enquiry</button>
264
260
  </div>
265
261
  </div>
266
262
  </div>
@@ -1,8 +1,7 @@
1
- import csv
2
1
  import logging
3
2
  from json import dumps
4
3
  from tempfile import NamedTemporaryFile
5
- from typing import List
4
+ from typing import List, Tuple
6
5
 
7
6
  from flask import Blueprint, flash, redirect, render_template, request, send_file, url_for
8
7
  from flask_login import current_user
@@ -29,10 +28,25 @@ def clinvar_submission_status(submission_id):
29
28
  """Sends a request to ClinVar to retrieve and display the status of a submission."""
30
29
 
31
30
  # flash a message with current submission status for a ClinVar submission
32
- clinvar_api.show_submission_status(
33
- submission_id=submission_id, api_key=request.form.get("apiKey")
31
+ flash(
32
+ f'Response from ClinVar: {clinvar_api.json_submission_status( submission_id=submission_id, api_key=request.form.get("apiKey"))}',
33
+ "primary",
34
34
  )
35
+ return redirect(request.referrer)
36
+
37
+
38
+ @clinvar_bp.route("/clinvar/delete-enquiry/<submission_id>", methods=["POST"])
39
+ def clinvar_submission_delete(submission_id):
40
+ """Sends a request to ClinVar to delete a successfully processed submission."""
35
41
 
42
+ # Retrieve the actual submission status:
43
+ delete_res: Tuple[int, dict] = clinvar_api.delete_clinvar_submission(
44
+ submission_id=submission_id, api_key=request.form.get("apiKey")
45
+ )
46
+ flash(
47
+ f"ClinVar response: { str(delete_res[1]) }",
48
+ "success" if delete_res[0] == 201 else "warning",
49
+ )
36
50
  return redirect(request.referrer)
37
51
 
38
52
 
@@ -104,33 +118,6 @@ def clinvar_update_submission(institute_id, submission):
104
118
  return redirect(request.referrer)
105
119
 
106
120
 
107
- @clinvar_bp.route("/<submission>/download/csv/<csv_type>/<clinvar_id>", methods=["GET"])
108
- def clinvar_download_csv(submission, csv_type, clinvar_id):
109
- """Download a csv (Variant file or CaseData file) for a clinVar submission"""
110
-
111
- clinvar_file_data = controllers.clinvar_submission_file(submission, csv_type, clinvar_id)
112
-
113
- if clinvar_file_data is None:
114
- return redirect(request.referrer)
115
-
116
- # Write temp CSV file and serve it in response
117
- tmp_csv = NamedTemporaryFile(
118
- mode="a+", prefix=clinvar_file_data[0].split(".")[0], suffix=".csv"
119
- )
120
- writes = csv.writer(tmp_csv, delimiter=",", quoting=csv.QUOTE_ALL)
121
- writes.writerow(clinvar_file_data[1]) # Write header
122
- writes.writerows(clinvar_file_data[2]) # Write lines
123
- tmp_csv.flush()
124
- tmp_csv.seek(0)
125
-
126
- return send_file(
127
- tmp_csv.name,
128
- download_name=clinvar_file_data[0],
129
- mimetype="text/csv",
130
- as_attachment=True,
131
- )
132
-
133
-
134
121
  @clinvar_bp.route("/<submission>/download/json/<clinvar_id>", methods=["GET"])
135
122
  def clinvar_download_json(submission, clinvar_id):
136
123
  """Download a json for a clinVar submission"""
@@ -235,10 +235,10 @@
235
235
  <span class="text-muted">exon </span><strong>{{ primary_gene.exon }}</strong>
236
236
  {% endif %}
237
237
  {% if primary_transcript and primary_transcript.coding_sequence_name %}
238
- {{ primary_transcript.coding_sequence_name | url_decode }}
238
+ {{ primary_transcript.coding_sequence_name | url_decode | truncate(50, True) }}
239
239
  {% endif %}
240
240
  {% if primary_transcript and primary_transcript.protein_sequence_name %}
241
- <strong>{{ primary_transcript.protein_sequence_name | url_decode }}</strong>
241
+ <strong>{{ primary_transcript.protein_sequence_name | url_decode | truncate(50, True) }}</strong>
242
242
  {% endif %}
243
243
  {% if primary_gene and primary_gene.region_annotation %}
244
244
  <div>(<span class="font-weight-bold">{{ primary_gene.functional_annotation|truncate(20, True) }}</span> in <span class="font-weight-bold">{{ primary_gene.region_annotation }} region</span>)</div>
@@ -375,7 +375,7 @@
375
375
  </li>
376
376
  <li class="list-group-item">
377
377
  SPIDEX
378
- <span class="float-end">{{ variant.spidex_human }}</span>
378
+ <span class="float-end">{{ variant.spidex|spidex_human if variant.spidex else none|spidex_human }}</span>
379
379
  </li>
380
380
  <li class="list-group-item">
381
381
  <a href="{{ variant.spliceai_link }}" target="_blank" rel="noopener">SpliceAI</a> <a href="https://github.com/Illumina/SpliceAI" target="_blank" rel="noopener">DS max</a>
@@ -27,12 +27,19 @@ from scout.server.blueprints.variant.controllers import (
27
27
  check_reset_variant_classification,
28
28
  )
29
29
  from scout.server.blueprints.variant.controllers import evaluation as evaluation_controller
30
- from scout.server.blueprints.variant.controllers import observations, str_variant_reviewer
30
+ from scout.server.blueprints.variant.controllers import (
31
+ observations,
32
+ str_variant_reviewer,
33
+ )
31
34
  from scout.server.blueprints.variant.controllers import variant as variant_controller
32
35
  from scout.server.blueprints.variant.controllers import variant_acmg as acmg_controller
33
- from scout.server.blueprints.variant.controllers import variant_acmg_post
36
+ from scout.server.blueprints.variant.controllers import (
37
+ variant_acmg_post,
38
+ )
34
39
  from scout.server.blueprints.variant.controllers import variant_ccv as ccv_controller
35
- from scout.server.blueprints.variant.controllers import variant_ccv_post
40
+ from scout.server.blueprints.variant.controllers import (
41
+ variant_ccv_post,
42
+ )
36
43
  from scout.server.blueprints.variant.verification_controllers import (
37
44
  MissingVerificationRecipientError,
38
45
  variant_verification,
@@ -83,17 +83,18 @@
83
83
  </td>
84
84
  <td>{{ gene_cell(variant) }}</td>
85
85
  <td>
86
+
86
87
  <a target="_blank" href="{{ url_for('variant.cancer_variant', institute_id=institute._id, case_name=case.display_name,
87
88
  variant_id=variant._id, cancer='yes') }}">
88
89
  {% if variant.first_rep_gene.hgvs_identifier %}
89
- <div>{{ variant.first_rep_gene.hgvs_identifier }}</div>
90
- <div>{{ (variant.first_rep_gene.hgvsp_identifier or '') |url_decode }}</div>
90
+ <div>{{ variant.first_rep_gene.hgvs_identifier|truncate(30, True) }}</div>
91
+ <div>{{ (variant.first_rep_gene.hgvsp_identifier or '') |url_decode|truncate(30, True) }}</div>
91
92
  {% else %}
92
- <div>{{ variant.reference }}→
93
+ <div>{{ variant.reference|truncate(30, True) }}→
93
94
  {% if variant.alternative | length > 5 %}
94
95
  {{ variant.alternative[0] }}...{{ variant.alternative[-1] }}
95
96
  {% else %}
96
- {{ variant.alternative }}
97
+ {{ variant.alternative|truncate(30, True) }}
97
98
  {% endif %}
98
99
  </div>
99
100
  {% endif %}
@@ -3,7 +3,7 @@
3
3
  {% from "variant/buttons.html" import reviewer_button%}
4
4
  {% from "variant/gene_disease_relations.html" import inheritance_badge %}
5
5
  {% from "variants/components.html" import external_scripts, external_stylesheets, frequency_cell_general %}
6
- {% from "variants/utils.html" import cell_rank, dismiss_variants_block, filter_form_footer, update_stash_filter_button_status, pagination_footer, pagination_hidden_div, str_filters, filter_script_main %}
6
+ {% from "variants/utils.html" import callers_cell, cell_rank, dismiss_variants_block, filter_form_footer, update_stash_filter_button_status, pagination_footer, pagination_hidden_div, str_filters, filter_script_main %}
7
7
 
8
8
 
9
9
  {% block title %}
@@ -60,13 +60,14 @@
60
60
  <thead class="thead table-light">
61
61
  <tr>
62
62
  <th style="width:8%" title="Index">Index</th>
63
- <th title="Repeat ID">Repeat locus</th>
64
- <th title="Repeat unit">Reference repeat unit</th>
65
- <th title="ALT">Estimated size</th>
66
- <th title="ReferenceSize">Reference size</th>
67
- <th title="Status">Status</th>
63
+ <th title="Repeat locus ID">Repeat locus</th>
64
+ <th style="width:8%" title="Reference repeat unit">Ref RU</th>
65
+ <th style="width:6%" title="ALT">Est size</th>
66
+ <th style="width:6%" title="ReferenceSize">Ref size</th>
67
+ <th style="width:8%" title="Caller and call filter status">Qual</th>
68
+ <th style="width:8%" title="Status">Status</th>
68
69
  <th title="GT">Genotype</th>
69
- <th title="Chromosome" style="width:6%">Chr.</th>
70
+ <th style="width:6%" title="Chromosome" style="width:6%">Chr.</th>
70
71
  <th title="Position" style="width:20%">Position</th>
71
72
  </tr>
72
73
  </thead>
@@ -95,11 +96,14 @@
95
96
  <td class="text-end">{{ variant.str_display_ru or variant.str_ru or variant.reference }}</td>
96
97
  <td class="text-end"><b><span data-bs-toggle="tooltip" title="{{ variant.alternative }}">{{ variant.str_mc }}</span></b></td>
97
98
  <td class="text-end"><span data-bs-toggle="tooltip" title="{{ variant.reference }}">{{ variant.str_ref or "." }}</span></td>
99
+ <td>{{ callers_cell(variant) }}</td>
98
100
  <td>{{ str_status(variant) }}</td>
99
101
  <td>{% for sample in variant.samples %}
100
102
  {% if sample.genotype_call != "./." %}
101
- <div class="float-start">{{ sample.display_name }}</div>
102
- <div class="float-end">{{ sample.genotype_call }}</div><br>
103
+ <div class="row">
104
+ <div class="col-8">{{ sample.display_name }}</div>
105
+ <div class="col-4 text-end">{{ sample.genotype_call }}</div>
106
+ </div>
103
107
  {% endif %}
104
108
  {% endfor %}
105
109
  </td>
@@ -1,5 +1,7 @@
1
1
  import json
2
2
  import logging
3
+ from io import StringIO
4
+ from typing import Optional, Tuple
3
5
 
4
6
  import requests
5
7
  from flask import flash
@@ -17,6 +19,7 @@ class ClinVarApi:
17
19
 
18
20
  def init_app(self, app):
19
21
  self.convert_service = "/".join([PRECLINVAR_URL, "csv_2_json"])
22
+ self.delete_service = "/".join([PRECLINVAR_URL, "delete"])
20
23
  self.submit_service_url = app.config.get("CLINVAR_API_URL") or CLINVAR_API_URL_DEFAULT
21
24
 
22
25
  def set_header(self, api_key) -> dict:
@@ -77,10 +80,61 @@ class ClinVarApi:
77
80
  except Exception as ex:
78
81
  return self.submit_service_url, None, ex
79
82
 
80
- def show_submission_status(self, submission_id: str, api_key=None):
83
+ def json_submission_status(self, submission_id: str, api_key=None) -> dict:
81
84
  """Retrieve the status of a ClinVar submission using the https://submit.ncbi.nlm.nih.gov/api/v1/submissions/SUBnnnnnn/actions/ endpoint."""
82
85
 
83
86
  header: dict = self.set_header(api_key)
84
87
  actions_url = f"{self.submit_service_url}{submission_id}/actions/"
85
88
  actions_resp: requests.models.Response = requests.get(actions_url, headers=header)
86
- flash(f"Response from ClinVar: {actions_resp.json()}", "primary")
89
+ return actions_resp.json()
90
+
91
+ def get_clinvar_scv_accession(self, url: str) -> Optional[str]:
92
+ """Downloads a submission summary from the given URL into a temporary file and parses this file to retrieve a SCV accession, if available."""
93
+ # Send a GET request to download the file
94
+ response = requests.get(url)
95
+ response.raise_for_status() # Raise an error if the request failed
96
+
97
+ # Use an in-memory file-like object to hold the JSON content
98
+ with StringIO(response.text) as memory_file:
99
+
100
+ json_data = json.load(memory_file)
101
+
102
+ submission_data: dict = json_data["submissions"][0]
103
+ processing_status: str = submission_data["processingStatus"]
104
+ if processing_status != "Success":
105
+ flash(
106
+ f"Could not delete provided submission because its processing status is '{processing_status}'.",
107
+ "warning",
108
+ )
109
+ return
110
+ return submission_data["identifiers"]["clinvarAccession"]
111
+
112
+ def delete_clinvar_submission(self, submission_id: str, api_key=None) -> Tuple[int, dict]:
113
+ """Remove a successfully processed submission from ClinVar."""
114
+
115
+ try:
116
+ submission_status_doc: dict = self.json_submission_status(
117
+ submission_id=submission_id, api_key=api_key
118
+ )
119
+
120
+ subm_response: dict = submission_status_doc["actions"][0]["responses"][0]
121
+ submission_status = subm_response["status"]
122
+
123
+ if submission_status != "processed":
124
+ return (
125
+ 500,
126
+ f"Clinvar submission status should be 'processed' and in order to attempt data deletion. Submission status is '{submission_status}'.",
127
+ )
128
+
129
+ # retrieve ClinVar SCV accession (SCVxxxxxxxx) from file url returned by subm_response
130
+ subm_summary_url: str = subm_response["files"][0]["url"]
131
+ scv_accession: Optional(str) = self.get_clinvar_scv_accession(url=subm_summary_url)
132
+
133
+ # Remove ClinVar submission using preClinVar's 'delete' endpoint
134
+ resp = requests.post(
135
+ self.delete_service, data={"api_key": api_key, "clinvar_accession": scv_accession}
136
+ )
137
+ return resp.status_code, resp.json()
138
+
139
+ except Exception as ex:
140
+ return 500, str(ex)
scout/server/links.py CHANGED
@@ -3,7 +3,6 @@ from urllib.parse import quote
3
3
 
4
4
  from flask import current_app
5
5
 
6
- from scout.constants import SPIDEX_HUMAN
7
6
  from scout.utils.convert import amino_acid_residue_change_3_to_1
8
7
 
9
8
  SHALLOW_REFERENCE_STR_LOCI = ["ARX", "HOXA13"]
@@ -486,7 +485,6 @@ def get_variant_links(institute_obj: dict, variant_obj: dict, build: int = None)
486
485
  ensembl_link=ensembl_link(variant_obj, build),
487
486
  mitomap_link=mitomap_link(variant_obj),
488
487
  hmtvar_link=hmtvar_link(variant_obj),
489
- spidex_human=spidex_human(variant_obj),
490
488
  spliceai_link=spliceai_link(variant_obj, build),
491
489
  str_source_link=str_source_link(variant_obj),
492
490
  snp_links=snp_links(variant_obj),
@@ -908,18 +906,6 @@ def hmtvar_link(variant_obj):
908
906
  return url_template.format(id=variant_obj.get("hmtvar_variant_id"))
909
907
 
910
908
 
911
- def spidex_human(variant_obj):
912
- """Translate SPIDEX annotation to human readable string."""
913
- if variant_obj.get("spidex") is None:
914
- return "not_reported"
915
- if abs(variant_obj["spidex"]) < SPIDEX_HUMAN["low"]["pos"][1]:
916
- return "low"
917
- if abs(variant_obj["spidex"]) < SPIDEX_HUMAN["medium"]["pos"][1]:
918
- return "medium"
919
-
920
- return "high"
921
-
922
-
923
909
  def external_primer_order_link(variant_obj, build=None):
924
910
  """Compose link for primers orders based on the configuration paramaters EXTERNAL_PRIMER_ORDER_LINK_(37|38)"""
925
911
  build = build or 37
scout/utils/acmg.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # coding=UTF-8
2
2
 
3
- from typing import Optional
3
+ from typing import List, Optional
4
4
 
5
5
  from scout.constants import ACMG_COMPLETE_MAP
6
6
  from scout.constants.acmg import ACMG_POTENTIAL_CONFLICTS
@@ -362,12 +362,12 @@ def get_acmg_temperature(acmg_terms: set) -> Optional[dict]:
362
362
  }
363
363
 
364
364
 
365
- def get_acmg_conflicts(acmg_terms: set) -> list:
366
- """Check potential conflict paris, return list of reference strings."""
365
+ def get_acmg_conflicts(acmg_terms: List[str]) -> List[str]:
366
+ """Check for potential conflicting terms, return a list of references as strings."""
367
367
 
368
368
  conflicts = []
369
- for t1, t2, reference in ACMG_POTENTIAL_CONFLICTS:
370
- if t1 in acmg_terms and t2 in acmg_terms:
369
+ for conflict_set, reference in ACMG_POTENTIAL_CONFLICTS:
370
+ if conflict_set.issubset(set(acmg_terms)):
371
371
  conflicts.append(reference)
372
372
 
373
373
  return conflicts
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scout-browser
3
- Version: 4.95.0
3
+ Version: 4.96.0
4
4
  Summary: Clinical DNA variant visualizer and browser
5
5
  Project-URL: Repository, https://github.com/Clinical-Genomics/scout
6
6
  Project-URL: Changelog, https://github.com/Clinical-Genomics/scout/blob/main/CHANGELOG.md
@@ -4,7 +4,7 @@ scout/adapter/client.py,sha256=IuajRsEwTG41ZP14X09Q1Cj94zIgmIvUtlXfcAFn0EA,1513
4
4
  scout/adapter/mongo/__init__.py,sha256=NdHYCUXWUAuX5cUS3-6HCws2hW9uoGep8i0SC-oJd3k,31
5
5
  scout/adapter/mongo/acmg.py,sha256=v2Zuw-6APVmcnBnNXa18WJEu2vj5GUhZNiKMkruJsBI,4170
6
6
  scout/adapter/mongo/base.py,sha256=iIa2AjGNztKHcZzolY0T6r7Oh0guj6R1putztp4OTNY,4427
7
- scout/adapter/mongo/case.py,sha256=aHHCOeB1wjEX98HKBpDFWC0zZ149Orn93XkW0m7Wj7A,65148
7
+ scout/adapter/mongo/case.py,sha256=TS2erNplLCulGoF7zRMr_3eW1MyJd3VL2mOW7XsOZJM,65342
8
8
  scout/adapter/mongo/case_events.py,sha256=slHR4XJF9vRuEbuInJKMMAImLF8m7tHWVfGP42fbXr0,26859
9
9
  scout/adapter/mongo/case_group.py,sha256=tG8DuO0rNYepV4k0yCGPqssODErc0HMsAypg3mfhcV0,1575
10
10
  scout/adapter/mongo/ccv.py,sha256=VIz-Yqzm-1UVPDKvZkBllO4BOKXzvKCXcQUjTtZCHTI,4165
@@ -31,7 +31,7 @@ scout/adapter/mongo/variant_events.py,sha256=yNnMM58P1LbYFw73rWzti6l2zWa_G93ozUT
31
31
  scout/adapter/mongo/variant_loader.py,sha256=C05StRMFVChopcolPYXFIbh_S-FhYHu4NvBCpiBLOeE,28327
32
32
  scout/build/__init__.py,sha256=GUWEaXTpwsJil_KtrXBQJpZIwCQFSgo8NlK49R9IkA8,521
33
33
  scout/build/acmg.py,sha256=M21MrrP_dtEyOuu6t-jBDdaqYcHPMLcwJlt9fHG2ycE,1523
34
- scout/build/case.py,sha256=7Hry6ja0KvVhNQ1ecXy3HuaR7dY2x9O8f8FpYt4P6jo,11404
34
+ scout/build/case.py,sha256=LtYx6zQcCoGCss48qf7uluzTlXVH0Pl-WhqYzkbIcZ8,11510
35
35
  scout/build/ccv.py,sha256=cfAWSQ5cSBWURkL9_fPm1Y5aRcTIDOE9ieSWaYLufB4,1660
36
36
  scout/build/disease.py,sha256=Zew9AF_z1NbbKcO3uJZ2wgni501SkfnYRgnaCZ4m8FY,2020
37
37
  scout/build/hpo.py,sha256=LJBCTq-x09D0CSKcUHB8a6ynuUrVh_7Ia0ooA1BxMys,1207
@@ -126,7 +126,7 @@ scout/commands/view/panels.py,sha256=a0fQcP9-SDPuRYV7aEgIGUCYaMN6V47h6finpcdoomU
126
126
  scout/commands/view/transcripts.py,sha256=59WyNNp7zHPJIz9QgzrkoeKaSXTtuLli0VuL8IidEmY,1277
127
127
  scout/commands/view/users.py,sha256=MKlmhDYRM7Yf-Trmi1ijEuqsDIUn326bdFADyDs7XYg,832
128
128
  scout/constants/__init__.py,sha256=ke7uVYgqn6dqByEQdfLQ1H061yOvaNyt8E-WP84Dgr8,5854
129
- scout/constants/acmg.py,sha256=hYPzoLUqpuTjGXfIN80Nb1njriesH9oAELu1scp-ByU,18083
129
+ scout/constants/acmg.py,sha256=N9X2sJLbK6g6tDPhW0gYQifImzaowb4F6jfTYUBr-Z0,18717
130
130
  scout/constants/case_tags.py,sha256=O-BwEzU36MSpN7qqd-aSvoi4-VDRY8rM5hQ7Jg7DMgs,9447
131
131
  scout/constants/ccv.py,sha256=YP82qWCrjv3JB8d2LkUdBlBZolk0uF3nhNmkNgmebiI,9734
132
132
  scout/constants/clinvar.py,sha256=nr7KhwMIO_7taNQokRJlpgZfenMlKsdPIMpdOx3TwKY,5594
@@ -187,7 +187,7 @@ scout/demo/ADM1059A2.test.cgh,sha256=29YOnGgPB3wxWwxVwf_mCLrhZ4Cf5hqVxw_DUggBe7Y
187
187
  scout/demo/ADM1059A3.d4,sha256=Da7zycL1LjrzhX1171G1sJTedyOLUyYMc_e5EAhI4eQ,961059
188
188
  scout/demo/ADM1059A3.test.cgh,sha256=29YOnGgPB3wxWwxVwf_mCLrhZ4Cf5hqVxw_DUggBe7Y,29
189
189
  scout/demo/__init__.py,sha256=ggXVz3_6ZUAzIZtuaK8kz3C6BuxSfaQ56PAzinJcYoI,2061
190
- scout/demo/cancer.load_config.yaml,sha256=1wz9eTRI54lu4TERQ3WJbbkEhrdLHhm1X_IMktXZX2M,1401
190
+ scout/demo/cancer.load_config.yaml,sha256=T4v2xvUA5vv3kZ8HT_7uQFq20xG1qq4YguVcTdqyKzE,1373
191
191
  scout/demo/cancer_cnv_report.pdf,sha256=_2_nj7Hc9SdE_mwDBqoquOFTLzZq5URnslADRMFjOm4,1910043
192
192
  scout/demo/cancer_coverage_qc_report.html,sha256=BlE_d6i68fK6VPv1wCyEmJy3qGSU67-in5Y1BGustU8,6914
193
193
  scout/demo/cancer_test.ped,sha256=NN_IGuCTulYXQ18u1eFcvj_AwTnlSpu9eHurQZfkoys,36
@@ -211,7 +211,7 @@ scout/demo/panelapp_panels_reduced.json,sha256=dwvRRwfIIFq6H4ze0wyOIllN-LSreK5jh
211
211
  scout/demo/reduced_mt.bam,sha256=DlC0lBAQrqbNrRSJ27MrOVmF5_bjRINmHwMn45a0-_c,492247
212
212
  scout/demo/reduced_mt.bam.bai,sha256=S8k17QiK9jkLHM3usZP-Rsc5xGe5kvHfbMbB3-KKIRM,808
213
213
  scout/demo/reference_info.yaml,sha256=-9kgT14q-IY3xzz9iPSoV22hR7u89xOq4FJMEOqb3-0,7526
214
- scout/demo/rnafusion.load_config.yaml,sha256=7a8Tox78q4RiioeTXivioheexrmPL4W9G3SCwNUlo_0,540
214
+ scout/demo/rnafusion.load_config.yaml,sha256=nbx-uEnEY4wA0ro8mJI4cRHk--h3Tbtj0sJD7BYO6Jk,562
215
215
  scout/demo/rnafusion_inspector_example.html,sha256=rDxfsZR4vYyhxD_gzA9pKPpposOcHe0tqq7UpzP6Dbo,1547345
216
216
  scout/demo/rnafusion_report_example.html,sha256=Ktd1UuW41pNYI7qT84cyYconJJQJxx7AkkAD3767tsc,1755020
217
217
  scout/demo/scout_example_tumor_only.SV.CNV.sorted.vcf.gz,sha256=lABVdx4zlpUuP2uL92ZYsHIiQNZNl35bGXlUECyiLGE,3443
@@ -398,13 +398,13 @@ scout/models/phenotype_term.py,sha256=jY7dbfPzgE14M1gWqifm5YKkwMlrtfFa_WBHMT1_og
398
398
  scout/models/user.py,sha256=oercrjpf9fLomqAcN0Fv1BL_XPjOrS_vchURo0RP7es,1134
399
399
  scout/models/case/__init__.py,sha256=Sqczn7Wm9KYZtPGAHCvwX_6j9vlaK-0myJtSDlS-448,121
400
400
  scout/models/case/case.py,sha256=Wu2D6IZKkFXLeF7emcBr7n1HQ7Mj9rO-cN-8T9rhkSU,5282
401
- scout/models/case/case_loading_models.py,sha256=GNeXZFrJ_1ISSxqO2VpKXazCLksLsPbTNL67csIIwQQ,21568
401
+ scout/models/case/case_loading_models.py,sha256=Fs1jxbaHBsxC3l3_ECHFczukWFWQwPhigXW4035rZS8,21670
402
402
  scout/models/variant/__init__.py,sha256=H-IZ2hSTSVS28S8FZzA8j2Cyu1PHQFXyMWJFtCucPAk,40
403
403
  scout/models/variant/gene.py,sha256=98CG_JcAklGGFIrUulf1_olQalV65kXQO-gOf7VQZ0A,1095
404
404
  scout/models/variant/transcript.py,sha256=rfflEbTs7Bn4HDENqrxtGopQ_0HKnrVLLyBcrj4NpwM,1720
405
405
  scout/models/variant/variant.py,sha256=SppFVdCYrlZiMBce38YrAykYZZ-0el3DzrArJHtC1yU,4473
406
406
  scout/parse/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
407
- scout/parse/case.py,sha256=-sGKWYWcskMagrDpEoeCIAJacwCR2feC8SwWvT0FJVw,11577
407
+ scout/parse/case.py,sha256=P7ya8LaV5G_R-5AOwPU5mMbGdc1sG7Ojt16JXTgrpKo,11690
408
408
  scout/parse/cytoband.py,sha256=7flY3b_wegupHHBLRcs4KyM1ns-uzuTfVHm4CycnupE,1055
409
409
  scout/parse/disease_terms.py,sha256=-JIm4GWEvqg9nmWehK18mlIQ-N5nZhT2u5pbfDRXoxE,7437
410
410
  scout/parse/ensembl.py,sha256=nnqOVtLgWh9wbtHnzGIidnNIvRoOp2bTct5OuAFSSB0,10618
@@ -444,10 +444,10 @@ scout/resources/cytoBand_hg19.txt.gz,sha256=pheUD5b9NlVuvwwnbKwDc2FG80Yg70gvPxVX
444
444
  scout/resources/cytoBand_hg38.txt.gz,sha256=sqSVmvPlktQ-0hTiTapJM-5UgyV6xDoYZuTF0kPuETs,6105
445
445
  scout/resources/custom_igv_tracks/mane.bb,sha256=flEexDxHmbX7IwwrMM0P5DWOxcSCjmHxGNlyg_WqElQ,3519360
446
446
  scout/server/__init__.py,sha256=iwhKnzeBJLKxpRVjvzwiRE63_zNpIBfaKLITauVph-0,24
447
- scout/server/app.py,sha256=70YdN9eWL1ySEYkuAHKOk_WA4Fm5dcIwtIZEcEf-xA0,10836
447
+ scout/server/app.py,sha256=S29_mBkNFWr7JDHB0I3JEyzdNwn7Qw28mKV7X5VMoN0,11254
448
448
  scout/server/auto.py,sha256=8B6GwfOaUChkTLuLgYQDFMWlxGuHkEegF1argH2G2Ik,401
449
449
  scout/server/config.py,sha256=BFx6ix8D3KM90FqmaHLxv_feudO2kN2CkX1UWBGTjXE,5923
450
- scout/server/links.py,sha256=f2h_zUFt4Tm_383ZmdIGsA6mUVQbpQmJ199ZTzUWemE,28115
450
+ scout/server/links.py,sha256=rJTHO4G40uLiWCtPr2n0Q0pBMtSOhjjh7F41jBoufM4,27656
451
451
  scout/server/utils.py,sha256=d1fGdSwo-XjNHVjHd-uT3mGmUJ8yYB6weT7VgHo9nxM,12592
452
452
  scout/server/blueprints/__init__.py,sha256=iwhKnzeBJLKxpRVjvzwiRE63_zNpIBfaKLITauVph-0,24
453
453
  scout/server/blueprints/alignviewers/__init__.py,sha256=XMVed2ekVUAvroqENDHSr2pwM8otqau8ZA-rbH1T2U8,59
@@ -460,7 +460,7 @@ scout/server/blueprints/alignviewers/templates/alignviewers/utils.html,sha256=x2
460
460
  scout/server/blueprints/api/__init__.py,sha256=HR6HjS7ot1K_8Lt5eQdNT154z_FCdHGSigy8r2LpNCI,26
461
461
  scout/server/blueprints/api/views.py,sha256=pbl78wfhrm1T8JmiJDYF3BbTbfFrlF-hQRbuv2GWI0s,3729
462
462
  scout/server/blueprints/cases/__init__.py,sha256=_c17kPFITFYcIVphF4V9bf0PZBer8bU3rtVWQnljKDU,52
463
- scout/server/blueprints/cases/controllers.py,sha256=UzzFpDfS66f2ZL7cwDdpDFFRR_OtJzds9kc7Wx0U0wc,55747
463
+ scout/server/blueprints/cases/controllers.py,sha256=08QudunYV7deJ2YYTa3Y4TxJ6zLaE8OxXdWHpJWAAPA,55825
464
464
  scout/server/blueprints/cases/views.py,sha256=MQDOnLuywAQkVBgYaZAbaj9f6tps18bpo4nDFm77S4s,43165
465
465
  scout/server/blueprints/cases/static/case_images.js,sha256=pb_gG7DNQc-1lADqSII8YvjBwmHyeQWYVtuu2jyrTlU,14997
466
466
  scout/server/blueprints/cases/static/case_styles.css,sha256=2Pgc8pFf9DR5HM1sTdAjaRWhjL-bK5bsQnLpH54HZak,541
@@ -468,11 +468,11 @@ scout/server/blueprints/cases/static/edit_pedigree.js,sha256=ntC5fie7SsOYJau8qkk
468
468
  scout/server/blueprints/cases/static/madeline.js,sha256=KHxKMBVlYVJODNu5QkY9hhsGkDJNoaCoCZZ0DRu0YN0,1175
469
469
  scout/server/blueprints/cases/templates/cases/case.html,sha256=9Fcn-OFA1yIHchD0PjDs7-Y8I7Qqr8o6cavN0eOi5rI,37183
470
470
  scout/server/blueprints/cases/templates/cases/case_bionano.html,sha256=PLoRv7hDJcHwxhi-0hC9fQSZc7V_aUYHBhhQqcn_2G8,5946
471
- scout/server/blueprints/cases/templates/cases/case_report.html,sha256=-ATAfUnT4a6dmdUSFuGjGPK7r6_XgOXPJtC-Lu8hOgs,66304
471
+ scout/server/blueprints/cases/templates/cases/case_report.html,sha256=lum4fIh6ur_bdnMeYLFGXht0LaF2t-T1StAk8F0cZ5o,67481
472
472
  scout/server/blueprints/cases/templates/cases/case_sma.html,sha256=99rmRyDXFXjooB52TI5_ebJKv1ZAJbVXEw4deHfSVMA,7285
473
473
  scout/server/blueprints/cases/templates/cases/case_tabular_view.html,sha256=ko-LDUKmIoTazMZ2nFWvPEZsgObU07RwqIkDYFjokoY,4317
474
474
  scout/server/blueprints/cases/templates/cases/chanjo2_form.html,sha256=5Wmk7DM8LI3MynqzxeTzAr_EoEBwVVo31djcI5ZlTdo,2164
475
- scout/server/blueprints/cases/templates/cases/collapsible_actionbar.html,sha256=H45WZK2qVY47wgttdASjRooRKFs2wQXAnH18u80hRfg,30895
475
+ scout/server/blueprints/cases/templates/cases/collapsible_actionbar.html,sha256=Zk-ezZ_Ae7gtDw2pDCvyXk-iFoPcD5y3h1THLPKPgk8,31404
476
476
  scout/server/blueprints/cases/templates/cases/diseases.html,sha256=ETTQI0Nrl_v86NoX9mFZcvWD-qM1IJoqPmHPWn__Grw,1677
477
477
  scout/server/blueprints/cases/templates/cases/gene_panel.html,sha256=lkC_Piqaq-paYr4GUCwQaR8EgGOUXDMoW5sPLDW7yzg,11628
478
478
  scout/server/blueprints/cases/templates/cases/index.html,sha256=y91d7yI64Fbz7wS8CSsi3vcCo6rFmS0mnstUipnVHUQ,1136
@@ -482,12 +482,12 @@ scout/server/blueprints/cases/templates/cases/matchmaker.html,sha256=kPYnmcZJ1gm
482
482
  scout/server/blueprints/cases/templates/cases/phenotype.html,sha256=7vz5XPUExD6vc-wdijLKnPzaOFm9mQxOZ_ITAL3y7U8,16420
483
483
  scout/server/blueprints/cases/templates/cases/utils.html,sha256=gHcxf3DOGcJJZMfjKY4NgvU_tjta5OnyWrKZy9pfGyY,35981
484
484
  scout/server/blueprints/clinvar/__init__.py,sha256=BV3aH2AbiA2WWrUEMbGd0H9MefFd2eTsRE9ShywbzpI,30
485
- scout/server/blueprints/clinvar/controllers.py,sha256=lCrVlokjnSURvsYkm6sTMxrZOL1Xj3VQAWbYr1o_mEY,24251
485
+ scout/server/blueprints/clinvar/controllers.py,sha256=usIiPsk-Ku_mUq975LRpxgibnD6wtupmveVE_RcERkk,24252
486
486
  scout/server/blueprints/clinvar/form.py,sha256=2h42YJzaOtsdEglxqt7F1i2ncjSU_IHNt-m4QOJytK4,5148
487
- scout/server/blueprints/clinvar/views.py,sha256=hPyTJA7Qy6QOL-ENSG1N0atnQXuYCb-iiO8fuNDjJns,6036
487
+ scout/server/blueprints/clinvar/views.py,sha256=nXZMPjldV_wuvj9k5_hsfkVGCvFlhT8fssS-tMlVXYk,5710
488
488
  scout/server/blueprints/clinvar/static/form_style.css,sha256=Tro2w0Su9st2ZRpt8PjF7qXYet-0n6Eyol4oh94JafU,4073
489
489
  scout/server/blueprints/clinvar/templates/clinvar/clinvar_howto.html,sha256=phFsRl6Hv94sy4GueBN0MXYbQsW6qmR1NoH-3Iwt2zs,4852
490
- scout/server/blueprints/clinvar/templates/clinvar/clinvar_submissions.html,sha256=NqR66lFN-Svm0IC0FZTts1oPK8S80t69SRSgT-727LA,18185
490
+ scout/server/blueprints/clinvar/templates/clinvar/clinvar_submissions.html,sha256=zJJehPFmxwL6tTChYQBvtOKn3Q2v6RD8pBLiJF6jHaQ,18095
491
491
  scout/server/blueprints/clinvar/templates/clinvar/multistep_add_variant.html,sha256=zfU_dPLtjiX8NE7IGTfABt9q46Li8rWFXyyMSvc_U-E,32017
492
492
  scout/server/blueprints/dashboard/__init__.py,sha256=9YTjGeFexyEbl4P-gs7j8VEjyhnVwHZFfz57eTtod1M,69
493
493
  scout/server/blueprints/dashboard/controllers.py,sha256=x6EWKROskF4iyZ5_hAgL7CWp1X3CXHp-7v0JVsDHKZU,9612
@@ -607,10 +607,10 @@ scout/server/blueprints/variant/__init__.py,sha256=SlD8-Aoj9Jq9aVTJjtFfsu-0sUVfk
607
607
  scout/server/blueprints/variant/controllers.py,sha256=dnx5YFVF62V2kAspfGpw0Mr0qUH1VoU1EBTP1hvIlZM,29691
608
608
  scout/server/blueprints/variant/utils.py,sha256=BMezzz9Y9ZoGMaLKRbQopJUkWWUo1M9Xi-pw82Vdm4k,25079
609
609
  scout/server/blueprints/variant/verification_controllers.py,sha256=eKzP222e7xuFOaQaI9MLOrD9RWtI8uGB1cJYbcXLzF0,10972
610
- scout/server/blueprints/variant/views.py,sha256=lP6K0BD0d4TDxOMFiQ-UUxF4UkoALzX-nxo_aSY7muI,18969
610
+ scout/server/blueprints/variant/views.py,sha256=82gYXNREV17l8XTWCaptrv5lDfJOG4kiqAaX5IN62Do,19000
611
611
  scout/server/blueprints/variant/templates/variant/acmg.html,sha256=Fk4vL1Pu4G3wZsfiUO2jBlFLFoRgFAeqChlIyas5Bb4,8758
612
612
  scout/server/blueprints/variant/templates/variant/buttons.html,sha256=4vlnvJKhr28qqzevlecAIvumvOgLZhGyPYQm68AnKzU,7608
613
- scout/server/blueprints/variant/templates/variant/cancer-variant.html,sha256=ZUnZYURdlLfiJ1Ryok5oRVa96bvBErhIgym2VlWlryQ,14001
613
+ scout/server/blueprints/variant/templates/variant/cancer-variant.html,sha256=vBtPp_jvMeRlwQ71TjGNdG8eCFU27ylFExza5_kJiqg,14043
614
614
  scout/server/blueprints/variant/templates/variant/ccv.html,sha256=X33qKY1EvzoLldko1hK5tgE__xxNU54vq6fRzFew6Vc,8671
615
615
  scout/server/blueprints/variant/templates/variant/components.html,sha256=dmKxuSrJgvKRtRAzXMN9W2-uZwsLwzde0W4CHqnBb-Q,26185
616
616
  scout/server/blueprints/variant/templates/variant/gene_disease_relations.html,sha256=1U77akxqbb4AS2GSyvFwGD6D7rP68L3KXKLUmP73664,7256
@@ -621,7 +621,7 @@ scout/server/blueprints/variant/templates/variant/sv-variant.html,sha256=4FBomOY
621
621
  scout/server/blueprints/variant/templates/variant/tx_overview.html,sha256=EXLBDh_SgNVEO7MPMjlmfO6MDhtDcj0JyvZdRgxbwSM,6756
622
622
  scout/server/blueprints/variant/templates/variant/utils.html,sha256=lF-w3400plEn0gVpHG-9k7N9L_p1U-PFGitcT_YlZw8,25414
623
623
  scout/server/blueprints/variant/templates/variant/variant.html,sha256=JA0jI1ITvKamJY88U6-uBXYrHRZa3H2oyBUROtX9TKw,17874
624
- scout/server/blueprints/variant/templates/variant/variant_details.html,sha256=KAdrLo8UTxO1Nr5ggfdn663E7xMq1rK0A2PrKXCJGjM,21049
624
+ scout/server/blueprints/variant/templates/variant/variant_details.html,sha256=FeuANKP5gL9SWwYnC-4-dXyZOgy0Nq6FXAjED3nuqjI,21097
625
625
  scout/server/blueprints/variants/__init__.py,sha256=W1KCz9kEbVlNO0o3NvLitYLQoP_3JSJ5KSjhpcjlUBQ,55
626
626
  scout/server/blueprints/variants/controllers.py,sha256=ILJt2Jl9ShkePgZI1Grff-_gcxlZFzQ8zoQ86iZPxOI,74205
627
627
  scout/server/blueprints/variants/forms.py,sha256=nxsZGHOr2M9GyQob8_8CK5qFgPgxZ3wBdFT69PkVVJc,11447
@@ -629,12 +629,12 @@ scout/server/blueprints/variants/utils.py,sha256=ifFBoyigx0A5KPE4iz9NSpyuUeF1bEl
629
629
  scout/server/blueprints/variants/views.py,sha256=skUGpZyRDzW4BEDIqWKajHBLF3qBUSP-UYSZYxbv3l8,28895
630
630
  scout/server/blueprints/variants/static/form_scripts.js,sha256=o3GCboaesA9Sm1HgejS_yQwt0I-NTkvcl56jiBdLqZs,8319
631
631
  scout/server/blueprints/variants/templates/variants/cancer-sv-variants.html,sha256=QlGmUEdUQ7gCq7tMMUFAlGqqC9jFB78Q0h6tSp3QUas,7271
632
- scout/server/blueprints/variants/templates/variants/cancer-variants.html,sha256=LnybOzNu4RkbighdIcV6okJwQWiO5ixOhTev_-QaQII,9611
632
+ scout/server/blueprints/variants/templates/variants/cancer-variants.html,sha256=nqJ1q23arq4yJokMJpsyf8-ayzZkD2zgwH7j-Y9bpfE,9688
633
633
  scout/server/blueprints/variants/templates/variants/components.html,sha256=PGtcPGVbd3gcdG_6ozA66LDo3ZJ8VoehaDMUZjwyA5Q,17431
634
634
  scout/server/blueprints/variants/templates/variants/fusion-variants.html,sha256=XGaLgWobzeFHwyQLXr_Yq9THssf8tGU91VbFKdGOFBg,4801
635
635
  scout/server/blueprints/variants/templates/variants/indicators.html,sha256=5aSXytiWvaU87cqcR9GcB7U5jP8t-PVnor8FpKLl_k0,4847
636
636
  scout/server/blueprints/variants/templates/variants/mei-variants.html,sha256=2Tb0vfzM--kJa5mVbT7L32h4E8nKYRSb245g6O5JIUU,5860
637
- scout/server/blueprints/variants/templates/variants/str-variants.html,sha256=bjjeyoEO1aScqIDLtCh3xexZfvf1906yusPGJTyeNLU,10644
637
+ scout/server/blueprints/variants/templates/variants/str-variants.html,sha256=n424D8xV76bCKDSFzzIsWfFAoU2dAYE-PPZyTtQeMdM,10924
638
638
  scout/server/blueprints/variants/templates/variants/sv-variants.html,sha256=fRDnB9wXago2OB2mthp0rD_Es4kxnj9YKRlOKCGVW3s,6407
639
639
  scout/server/blueprints/variants/templates/variants/utils.html,sha256=MNDc2JwumU9ukISizSAraxIY06rHXR2Ze32RNnDEBI4,50042
640
640
  scout/server/blueprints/variants/templates/variants/variants.html,sha256=KnCcsA1VaRdsbRCCw9Rg0TJTUvq03X9S24QgCqVToUk,9328
@@ -643,7 +643,7 @@ scout/server/extensions/beacon_extension.py,sha256=YDXQQl5kFcsA4OFHDMVurIKLw_3Gl
643
643
  scout/server/extensions/bionano_extension.py,sha256=0rWPLMSCRP8uK4_yozo6HTPR6V-oITF492vrGA3wSj0,7129
644
644
  scout/server/extensions/chanjo2_extension.py,sha256=ZKCIv8muR9bzCV0_rM277ePvxdWC3wuPIwY4VppH7lY,1530
645
645
  scout/server/extensions/chanjo_extension.py,sha256=JtKAgT6ASnCcKYbgKMWGwflISLzHuyDKpcyljzCV_aY,4045
646
- scout/server/extensions/clinvar_extension.py,sha256=w1fOzGKRhxmIlZkAqqd_rdGD49qE_nn-tgZsEMTrZNw,3870
646
+ scout/server/extensions/clinvar_extension.py,sha256=X3LsJZ4XL8hr8FyqhW1Zn4OmXEG0_edCZRHtWhTuLVk,6332
647
647
  scout/server/extensions/gens_extension.py,sha256=KOF-pP4DiRVQkygthAq6XCHnZwAGHo1kjIxmvW7ItYI,1003
648
648
  scout/server/extensions/ldap_extension.py,sha256=nVgJ6YhSyvpg8J4bSYzJwoEvKhP0faWazt3Xk0ixE2U,2746
649
649
  scout/server/extensions/loqus_extension.py,sha256=uiqUXQ7Q7DCj6C20TKgL8yLu9DXov95vrJfhq0tvbTM,12602
@@ -666,7 +666,7 @@ scout/server/translations/sv/LC_MESSAGES/messages.po,sha256=Wp7Mx4LoiFNtzsV1tpAo
666
666
  scout/update/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
667
667
  scout/update/panel.py,sha256=4z-vQ7GVIJXtlIub9pubFcQ-I9mLX5fRXKNPBdpuhJw,1649
668
668
  scout/utils/__init__.py,sha256=DHCMH05dxkyD7m9QSs0WXsQQPgVRFQ9XvyNeNpHjjvg,74
669
- scout/utils/acmg.py,sha256=IkWWmHxc0YvoSurzXimKkH_Vf8C0bncywVUVu8m-YlY,11539
669
+ scout/utils/acmg.py,sha256=b2WLE2-s0pijXWBdwfrGE3SFogYMDoeVVKQd9d7pBQA,11576
670
670
  scout/utils/algorithms.py,sha256=w--NauXbQohZis7obr39a8bS57C4NRelYXn79V7m1dU,800
671
671
  scout/utils/ccv.py,sha256=WhVyIzNW0ttfT4ZegOPGFR1xqqjRFNgnJSY7DPfXGNQ,5605
672
672
  scout/utils/convert.py,sha256=asrsis3zkt9jXzseRmCqSa4_t1UT73HPPQRW-DKDdqE,1794
@@ -683,8 +683,8 @@ scout/utils/md5.py,sha256=KkgdxOf7xbF9AF40ZjQKCgWaxFWJ9tp9RKjd8SU6IoA,649
683
683
  scout/utils/scout_requests.py,sha256=lgPumNI_EikBZR1m9ztZI_mZAfV29y1KGoiBv9kejzQ,12797
684
684
  scout/utils/sort.py,sha256=1AcbeZ6vdt_UXM3BLDBa3aQmN4qxrqtskxwD19oBhvw,756
685
685
  scout/utils/track_resources.py,sha256=eUjSEe-Ff8BIb4BHPC_COkJocQO2PaWueiPz1GAuiwY,2614
686
- scout_browser-4.95.0.dist-info/METADATA,sha256=IbeBpNPEf-Th3spPxj1Jjt1KXYuLBgWig8t7CWb6-dY,15642
687
- scout_browser-4.95.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
688
- scout_browser-4.95.0.dist-info/entry_points.txt,sha256=q_mxFwbMFTwXRDDIRVcqKram2ubMVmvs3CSNvZri1nY,45
689
- scout_browser-4.95.0.dist-info/licenses/LICENSE,sha256=TM1Y9Cqbwk55JVfxD-_bpGLtZQAeN9RovQlqHK6eOTY,1485
690
- scout_browser-4.95.0.dist-info/RECORD,,
686
+ scout_browser-4.96.0.dist-info/METADATA,sha256=Jipku15t2ek-OH7TQfUdgEIM1yieNz1hpRoOrcBkr-U,15642
687
+ scout_browser-4.96.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
688
+ scout_browser-4.96.0.dist-info/entry_points.txt,sha256=q_mxFwbMFTwXRDDIRVcqKram2ubMVmvs3CSNvZri1nY,45
689
+ scout_browser-4.96.0.dist-info/licenses/LICENSE,sha256=TM1Y9Cqbwk55JVfxD-_bpGLtZQAeN9RovQlqHK6eOTY,1485
690
+ scout_browser-4.96.0.dist-info/RECORD,,