scout-browser 4.99.0__py3-none-any.whl → 4.100.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 (64) hide show
  1. scout/adapter/mongo/case.py +30 -15
  2. scout/adapter/mongo/clinvar.py +23 -31
  3. scout/adapter/mongo/event.py +14 -4
  4. scout/adapter/mongo/omics_variant.py +14 -1
  5. scout/adapter/mongo/query.py +24 -1
  6. scout/adapter/mongo/variant.py +37 -19
  7. scout/adapter/mongo/variant_loader.py +159 -176
  8. scout/build/individual.py +3 -1
  9. scout/commands/download/ensembl.py +1 -2
  10. scout/commands/load/research.py +2 -3
  11. scout/commands/update/individual.py +1 -0
  12. scout/constants/__init__.py +7 -2
  13. scout/constants/igv_tracks.py +4 -3
  14. scout/constants/indexes.py +5 -4
  15. scout/constants/query_terms.py +1 -0
  16. scout/models/case/case.py +1 -0
  17. scout/models/case/case_loading_models.py +3 -1
  18. scout/parse/ensembl.py +8 -3
  19. scout/server/app.py +6 -0
  20. scout/server/blueprints/alignviewers/templates/alignviewers/igv_viewer.html +10 -0
  21. scout/server/blueprints/cases/controllers.py +9 -3
  22. scout/server/blueprints/cases/templates/cases/case_report.html +25 -13
  23. scout/server/blueprints/cases/templates/cases/chanjo2_form.html +1 -1
  24. scout/server/blueprints/cases/templates/cases/collapsible_actionbar.html +1 -1
  25. scout/server/blueprints/cases/templates/cases/gene_panel.html +1 -1
  26. scout/server/blueprints/cases/templates/cases/utils.html +19 -0
  27. scout/server/blueprints/clinvar/controllers.py +5 -1
  28. scout/server/blueprints/clinvar/templates/clinvar/clinvar_submissions.html +34 -12
  29. scout/server/blueprints/clinvar/templates/clinvar/multistep_add_variant.html +1 -1
  30. scout/server/blueprints/diagnoses/static/diagnoses.js +8 -1
  31. scout/server/blueprints/institutes/static/variants_list_scripts.js +9 -1
  32. scout/server/blueprints/institutes/templates/overview/institute_sidebar.html +9 -1
  33. scout/server/blueprints/mme/__init__.py +1 -0
  34. scout/server/blueprints/mme/controllers.py +18 -0
  35. scout/server/blueprints/mme/templates/mme/mme_submissions.html +153 -0
  36. scout/server/blueprints/mme/views.py +34 -0
  37. scout/server/blueprints/panels/templates/panels/panel.html +19 -6
  38. scout/server/blueprints/phenotypes/templates/phenotypes/hpo_terms.html +8 -1
  39. scout/server/blueprints/variant/controllers.py +19 -10
  40. scout/server/blueprints/variant/templates/variant/acmg.html +9 -0
  41. scout/server/blueprints/variant/templates/variant/cancer-variant.html +1 -1
  42. scout/server/blueprints/variant/templates/variant/components.html +19 -16
  43. scout/server/blueprints/variant/templates/variant/sv-variant.html +2 -2
  44. scout/server/blueprints/variant/templates/variant/utils.html +20 -8
  45. scout/server/blueprints/variant/templates/variant/variant.html +42 -1
  46. scout/server/blueprints/variant/views.py +12 -0
  47. scout/server/blueprints/variants/controllers.py +17 -9
  48. scout/server/blueprints/variants/forms.py +8 -3
  49. scout/server/blueprints/variants/templates/variants/components.html +8 -2
  50. scout/server/blueprints/variants/templates/variants/indicators.html +11 -13
  51. scout/server/blueprints/variants/templates/variants/utils.html +28 -23
  52. scout/server/extensions/bionano_extension.py +0 -1
  53. scout/server/extensions/chanjo2_extension.py +54 -13
  54. scout/server/links.py +15 -0
  55. scout/server/static/bs_styles.css +34 -6
  56. scout/server/templates/utils.html +9 -10
  57. scout/server/utils.py +18 -0
  58. scout/utils/ensembl_biomart_clients.py +1 -0
  59. scout/utils/scout_requests.py +1 -3
  60. {scout_browser-4.99.0.dist-info → scout_browser-4.100.0.dist-info}/METADATA +1 -1
  61. {scout_browser-4.99.0.dist-info → scout_browser-4.100.0.dist-info}/RECORD +64 -60
  62. {scout_browser-4.99.0.dist-info → scout_browser-4.100.0.dist-info}/WHEEL +0 -0
  63. {scout_browser-4.99.0.dist-info → scout_browser-4.100.0.dist-info}/entry_points.txt +0 -0
  64. {scout_browser-4.99.0.dist-info → scout_browser-4.100.0.dist-info}/licenses/LICENSE +0 -0
@@ -193,9 +193,9 @@
193
193
  {% endif %}
194
194
  <td>
195
195
  {% if compound.not_loaded %}
196
- {{ compound.display_name }} <small>(not loaded)</small>
196
+ {{ compound.display_name|truncate(20, True) }} <small>(not loaded)</small>
197
197
  {% elif is_popover %}
198
- {{ compound.display_name }}
198
+ {{ compound.display_name|truncate(20, True) }}
199
199
  {% else %}
200
200
  <a href='{{ url_for("variant.variant",
201
201
  institute_id=institute._id,
@@ -218,7 +218,7 @@
218
218
  <td>
219
219
  {% for annotation in compound.functional_annotations %}
220
220
  {{ annotation }}<br>
221
- {% endfor %}
221
+ {% endfor %}x
222
222
  </td>
223
223
  </tr>
224
224
  {% endfor %}
@@ -243,7 +243,7 @@
243
243
  {{ pretty_link_variant(variant, case) }}
244
244
  </td>
245
245
  <td class='text-end'>{{ variant.sub_category }}</td>
246
- <td class='text-end'>{{ variant.length if variant.length < 100000000000 else '-' }}</td>
246
+ <td class='text-end'>{{ variant.length if variant.length and variant.length < 100000000000 else '-' }}</td>
247
247
  <td class='text-end'>{{ variant.rank_score }}</td>
248
248
  </tr>
249
249
  {% endfor %}
@@ -332,7 +332,7 @@
332
332
  {{ form.spidex_human(class="selectpicker", data_style="btn-secondary") }}
333
333
  </div>
334
334
  <div class="col-2">
335
- <span>{{ form.clinsig.label(class="control-label") }}</span>
335
+ <span>{{ form.clinsig.label(class="control-label", data_bs_toggle="tooltip", data_bs_placement="left", title="Germline classification criteria.") }}</span>
336
336
  <span style="float:right;">{{ form.clinsig_exclude.label(class="control-label", data_bs_toggle="tooltip", data_bs_placement="left", title="Exclude variants with clinical significance among the selected categories.") }} {{form.clinsig_exclude}}</span>
337
337
  {{ form.clinsig(class="selectpicker", data_style="btn-secondary") }}
338
338
  </div>
@@ -621,7 +621,7 @@
621
621
  </div>
622
622
  </div>
623
623
  <div class="col-2">
624
- {{ form.clinsig.label(class="control-label") }}
624
+ {{ form.clinsig.label(class="control-label", data_bs_toggle="tooltip", data_bs_placement="left", title="Germline classification criteria.") }}
625
625
  {{ form.clinsig(class="selectpicker", data_style="btn-secondary") }}
626
626
  </div>
627
627
  <div class="col-1">
@@ -722,26 +722,17 @@
722
722
  {{ form.genetic_models(class="selectpicker", data_style="btn-secondary") }}
723
723
  </div>
724
724
  <div class="col-2">
725
- <span>{{ form.clinsig.label(class="control-label") }}</span>
725
+ <span>{{ form.clinsig.label(class="control-label", data_bs_toggle="tooltip", data_bs_placement="left", title="Germline classification criteria.") }}</span>
726
726
  <span style="float:right;">{{ form.clinsig_exclude.label(class="control-label", data_bs_toggle="tooltip", data_bs_placement="left", title="Exclude variants with clinical significance among the selected categories.") }} {{form.clinsig_exclude}}</span>
727
727
  {{ form.clinsig(class="selectpicker", data_style="btn-secondary") }}
728
728
  </div>
729
729
  <div class="col-2">
730
- <div class="form-check d-flex justify-content-start">
731
- {{ form.mvl_tag(class="form-check-input",type="checkbox") }}
732
- {{ form.mvl_tag.label(class="ms-2 form-check-label") }}
733
- </div>
734
- <div class="form-check d-flex justify-content-start">
735
- {{ form.clinvar_tag(class="form-check-input",type="checkbox") }}
736
- {{ form.clinvar_tag.label(class="ms-2 form-check-label") }}
737
- </div>
738
- <div class="form-check d-flex justify-content-start">
739
- {{ form.cosmic_tag(class="form-check-input",type="checkbox") }}
740
- {{ form.cosmic_tag.label(class="ms-2 form-check-label") }}
741
- </div>
730
+ <span>{{ form.clinsig_onc.label(class="control-label", data_bs_toggle="tooltip", data_bs_placement="left", title="ClinVar oncogenicity criteria will be applied alongside the other search criteria, not as an alternative. Oncogenicity annotations are still sparse in ClinVar, so relying solely on them could be too restrictive.") }}</span>
731
+ <span style="float:right;">{{ form.clinsig_onc_exclude.label(class="control-label", data_bs_toggle="tooltip", data_bs_placement="left", title="Exclude variants with oncogenicity among the selected categories.") }} {{form.clinsig_onc_exclude}}</span>
732
+ {{ form.clinsig_onc(class="selectpicker", data_style="btn-secondary") }}
742
733
  </div>
743
734
  </div>
744
- <div class="row">
735
+ <div class="row mt-2">
745
736
  <div class="col-4">
746
737
  {{ form.hgnc_symbols.label(class="control-label") }}
747
738
  {{ form.hgnc_symbols(class="form-control") }}
@@ -762,14 +753,28 @@
762
753
  {{ form.alt_count.label(class="control-label") }}
763
754
  {{ form.alt_count(class="form-control") }}
764
755
  </div>
765
- <div class="col-2">
756
+ <div class="col-1">
766
757
  {{ form.tumor_frequency.label(class="control-label") }}
767
758
  {{ form.tumor_frequency(class="form-control", min="0", max=1) }}
768
759
  </div>
769
- <div class="col-2">
760
+ <div class="col-1">
770
761
  {{ form.control_frequency.label(class="control-label") }}
771
762
  {{ form.control_frequency(class="form-control", min="0", max=1) }}
772
763
  </div>
764
+ <div class="col-2">
765
+ <div class="form-check d-flex justify-content-start">
766
+ {{ form.mvl_tag(class="form-check-input",type="checkbox") }}
767
+ {{ form.mvl_tag.label(class="ms-2 form-check-label") }}
768
+ </div>
769
+ <div class="form-check d-flex justify-content-start">
770
+ {{ form.clinvar_tag(class="form-check-input",type="checkbox") }}
771
+ {{ form.clinvar_tag.label(class="ms-2 form-check-label") }}
772
+ </div>
773
+ <div class="form-check d-flex justify-content-start">
774
+ {{ form.cosmic_tag(class="form-check-input",type="checkbox") }}
775
+ {{ form.cosmic_tag.label(class="ms-2 form-check-label") }}
776
+ </div>
777
+ </div>
773
778
  </div>
774
779
  <div class="form" id="chromosome_search">
775
780
  <div class="row" style="margin-top:20px;">
@@ -861,7 +866,7 @@
861
866
  {{ form.genetic_models(class="selectpicker", data_style="btn-secondary") }}
862
867
  </div>
863
868
  <div class="col-2">
864
- {{ form.clinsig.label(class="control-label") }}
869
+ {{ form.clinsig.label(class="control-label", data_bs_toggle="tooltip", data_bs_placement="left", title="Germline classification criteria.") }}
865
870
  {{ form.clinsig(class="selectpicker", data_style="btn-secondary") }}
866
871
  </div>
867
872
  </div>
@@ -7,7 +7,6 @@ For further development, the server has a Swagger-like demo interface at https:/
7
7
  which is useful for details, and for sniffing actual message content structure, required cookie variable names etc.
8
8
  """
9
9
 
10
- import json
11
10
  import logging
12
11
  from typing import Dict, Iterable, List, Optional, Tuple
13
12
 
@@ -1,11 +1,13 @@
1
1
  import logging
2
- from typing import Dict, List
2
+ from typing import Dict
3
3
 
4
4
  import requests
5
- from flask import current_app
5
+ from flask import Flask, current_app
6
+
7
+ from scout.server.utils import get_case_mito_chromosome
8
+ from scout.utils.scout_requests import get_request_json, post_request_json
6
9
 
7
10
  REF_CHROM = "14"
8
- MT_CHROM = "MT"
9
11
  LOG = logging.getLogger(__name__)
10
12
 
11
13
  CHANJO_BUILD_37 = "GRCh37"
@@ -15,14 +17,33 @@ CHANJO_BUILD_38 = "GRCh38"
15
17
  class Chanjo2Client:
16
18
  """Runs requests to chanjo2 and returns results in the expected format."""
17
19
 
18
- def mt_coverage_stats(self, individuals: dict) -> Dict[str, dict]:
20
+ def init_app(self, app: Flask):
21
+ """The chanjo2 client has nothing to init, just check chanjo2 heartbeat."""
22
+ self.get_status(app)
23
+
24
+ def get_status(self, app: Flask) -> dict:
25
+ """Check Chanjo2 heartbeat, LOG status and return status."""
26
+ chanjo2_heartbeat_url: str = app.config.get("CHANJO2_URL")
27
+ json_resp = get_request_json(chanjo2_heartbeat_url)
28
+
29
+ if not json_resp:
30
+ LOG.warning(
31
+ f"Chanjo2 is configured at {chanjo2_heartbeat_url} but does not return heartbeat."
32
+ )
33
+ return json_resp
34
+
35
+ LOG.info(f"{json_resp.get('content',{}).get('message')}")
36
+ return json_resp
37
+
38
+ def mt_coverage_stats(self, case_obj: dict) -> Dict[str, dict]:
19
39
  """Sends a POST requests to the chanjo2 coverage/d4/interval to collect stats for the MT case report."""
20
40
 
21
41
  chanjo2_chrom_cov_url: str = "/".join(
22
42
  [current_app.config.get("CHANJO2_URL"), "coverage/d4/interval/"]
23
43
  )
24
44
  coverage_stats = {}
25
- for ind in individuals:
45
+ case_mt_chrom = get_case_mito_chromosome(case_obj)
46
+ for ind in case_obj.get("individuals", []):
26
47
 
27
48
  if not ind.get("d4_file"):
28
49
  continue
@@ -30,14 +51,21 @@ class Chanjo2Client:
30
51
 
31
52
  # Get mean coverage over chr14
32
53
  chrom_cov_query["chromosome"] = REF_CHROM
33
- resp = requests.post(chanjo2_chrom_cov_url, json=chrom_cov_query)
34
- autosome_cov = resp.json().get("mean_coverage")
35
54
 
36
- # Get mean coverage over chrMT
37
- chrom_cov_query["chromosome"] = MT_CHROM
38
- resp = requests.post(chanjo2_chrom_cov_url, json=chrom_cov_query)
55
+ autosome_cov_json = post_request_json(chanjo2_chrom_cov_url, chrom_cov_query)
56
+ if autosome_cov_json.get("status_code") != 200:
57
+ raise ValueError(
58
+ f"Chanjo2 get autosome coverage failed: {autosome_cov_json.get('message')}"
59
+ )
60
+
61
+ autosome_cov = autosome_cov_json.get("content", {}).get("mean_coverage")
39
62
 
40
- mt_cov = resp.json().get("mean_coverage")
63
+ # Get mean coverage over chrMT
64
+ chrom_cov_query["chromosome"] = case_mt_chrom
65
+ mt_cov_json = post_request_json(chanjo2_chrom_cov_url, chrom_cov_query)
66
+ if mt_cov_json.get("status_code") != 200:
67
+ raise ValueError(f"Chanjo2 get MT coverage failed: {mt_cov_json.get('message')}")
68
+ mt_cov = mt_cov_json.get("content", {}).get("mean_coverage")
41
69
 
42
70
  coverage_info = dict(
43
71
  mt_coverage=mt_cov,
@@ -66,6 +94,8 @@ class Chanjo2Client:
66
94
  "interval_type": "genes",
67
95
  "samples": [],
68
96
  }
97
+ analysis_types = []
98
+
69
99
  for ind in individuals:
70
100
  if not ind.get("d4_file"):
71
101
  continue
@@ -73,10 +103,21 @@ class Chanjo2Client:
73
103
  gene_cov_query["samples"].append(
74
104
  {"coverage_file_path": ind["d4_file"], "name": ind["individual_id"]}
75
105
  )
106
+ analysis_types.append(ind.get("analysis_type"))
76
107
 
77
- resp = requests.post(chanjo2_gene_cov_url, json=gene_cov_query)
78
- gene_cov = resp.json()
108
+ if "wes" in analysis_types:
109
+ gene_cov_query["interval_type"] = "exons"
110
+ elif "wts" in analysis_types:
111
+ gene_cov_query["interval_type"] = "transcripts"
112
+
113
+ gene_cov_json = post_request_json(chanjo2_gene_cov_url, gene_cov_query)
114
+
115
+ if gene_cov_json.get("status_code") != 200:
116
+ raise ValueError(
117
+ f"Chanjo2 get complete coverage failed: {gene_cov_json.get('message')}"
118
+ )
79
119
 
120
+ gene_cov = gene_cov_json.get("content")
80
121
  full_coverage = bool(gene_cov)
81
122
  for sample in gene_cov.keys():
82
123
  if gene_cov[sample]["coverage_completeness_percent"] < 100:
scout/server/links.py CHANGED
@@ -54,6 +54,7 @@ def add_gene_links(
54
54
  gene_obj["string_link"] = string(ensembl_id)
55
55
  gene_obj["reactome_link"] = reactome(ensembl_id)
56
56
  gene_obj["clingen_link"] = clingen(hgnc_id)
57
+ gene_obj["cspec_link"] = clingen_cspec(hgnc_id)
57
58
  gene_obj["gencc_link"] = gencc(hgnc_id)
58
59
  gene_obj["expression_atlas_link"] = expression_atlas(ensembl_id)
59
60
  gene_obj["exac_link"] = exac(ensembl_id)
@@ -80,6 +81,7 @@ def add_gene_links(
80
81
  gene_obj["gnomad_str_link"] = gnomad_str_gene(hgnc_symbol)
81
82
  gene_obj["panelapp_link"] = panelapp_gene(hgnc_symbol)
82
83
  gene_obj["decipher_link"] = decipher_gene(hgnc_symbol)
84
+ gene_obj["cancer_hotspots_link"] = cancer_hotspots_gene(hgnc_symbol)
83
85
  if institute:
84
86
  gene_obj["alamut_link"] = alamut_gene_link(institute, gene_obj, build)
85
87
 
@@ -90,6 +92,12 @@ def decipher_gene(hgnc_symbol: str) -> Optional[str]:
90
92
  return f"https://www.deciphergenomics.org/gene/{hgnc_symbol}/overview/clinical-info"
91
93
 
92
94
 
95
+ def cancer_hotspots_gene(hgnc_symbol: str) -> Optional[str]:
96
+ """Create link to Decipher gene."""
97
+ if hgnc_symbol:
98
+ return f"https://www.cancerhotspots.org/#/home?search={hgnc_symbol}"
99
+
100
+
93
101
  def panelapp_gene(hgnc_symbol):
94
102
  link = "https://panelapp.genomicsengland.co.uk/panels/entities/{}"
95
103
 
@@ -250,6 +258,13 @@ def clingen(hgnc_id):
250
258
  return link.format(hgnc_id)
251
259
 
252
260
 
261
+ def clingen_cspec(hgnc_id):
262
+ link = "https://cspec.genome.network/cspec/ui/svi/?search=HGNC:{}"
263
+ if not hgnc_id:
264
+ return None
265
+ return link.format(hgnc_id)
266
+
267
+
253
268
  def gencc(hgnc_id):
254
269
  link = "https://search.thegencc.org/genes/HGNC:{}"
255
270
  if not hgnc_id:
@@ -371,6 +371,23 @@ body {
371
371
  }
372
372
  /* end of sidebar-related stuff */
373
373
 
374
+ /* A collapse icon for button use */
375
+ .btn[aria-expanded="false"] .collapse-button-icon::before {
376
+ content: " \f0da";
377
+ font-family: "Font Awesome 5 Free", ui-monospace;
378
+ font-weight: 900;
379
+ display: inline;
380
+ text-align: left;
381
+ }
382
+
383
+ .btn[aria-expanded="true"] .collapse-button-icon::before {
384
+ content: " \f0d7";
385
+ font-family: "Font Awesome 5 Free", ui-monospace;
386
+ font-weight: 900;
387
+ display: inline;
388
+ text-align: left;
389
+
390
+
374
391
  option {
375
392
  width: 100%;
376
393
  }
@@ -386,9 +403,20 @@ option {
386
403
  }
387
404
 
388
405
  .str-variants-reviewer-container {
389
- padding: 20px 5px;
390
- }
391
- .str-variants-reviewer-container svg {
392
- width: 100%;
393
- height: auto;
394
- }
406
+ padding: 20px 5px;
407
+ }
408
+
409
+ .str-variants-reviewer-container svg {
410
+ width: 100%;
411
+ height: auto;
412
+ }
413
+
414
+ .blink_me {
415
+ animation: blinker 2s linear infinite;
416
+ }
417
+
418
+ @keyframes blinker {
419
+ 50% {
420
+ opacity: 0;
421
+ }
422
+ }
@@ -234,16 +234,15 @@
234
234
  {% endmacro %}
235
235
 
236
236
  {% macro db_table_external_stylesheets() %}
237
- <link rel="stylesheet" href="https://cdn.datatables.net/1.12.0/css/dataTables.bootstrap5.min.css" integrity="sha512-r9doM4NDlA2Cr0R56ielwMfkzL8miUuqbwNV4G1detiqlX58aTINapm2g2CoASFYedwgn3ulX6xmcDmRS0bmzw==" crossorigin="anonymous">
238
- <link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.2.3/css/buttons.dataTables.min.css" integrity="sha512-tnmsL7vm/5wo8jsDSW4033D6dW3xn8qyIDZTIssv/3YKyLU3pMg5IZB0k88RGmZPlyyUoK7EEghuaoXZIinDXA==" crossorigin="anonymous">
239
- <link rel="stylesheet" href="https://cdn.datatables.net/buttons/2.2.3/css/buttons.bootstrap5.min.css" integrity="sha512-VX0h3jcn1Oc0lFy0aRxuq6U/tTk/6Ryurar5O3Az2DHLA1mpURv2Zgzl5MJJ5weChE7rdlsiB/ka5rUstkTN8g==" crossorigin="anonymous">
240
- {% endmacro %}
237
+ <link rel="stylesheet" href="https://cdn.datatables.net/2.2.2/css/dataTables.bootstrap5.min.css" integrity="sha512-pVSTZJo4Kj/eLMUG1w+itkGx+scwF00G5dMb02FjgU9WwF7F/cpZvu1Bf1ojA3iAf8y94cltGnuPV9vwv3CgZw==" referrerpolicy="no-referrer" crossorigin="anonymous">
238
+ <link rel="stylesheet" href="https://cdn.datatables.net/buttons/3.2.2/css/buttons.bootstrap5.min.css" integrity="sha512-9Mi4C/wtfinscXIdOGZvqv0ZYvhBUOQCrwqmTZyiYuEgJQHWnXenkYQOC44I3kyh7uaOmz9eNxeMkC8xGBLOWg==" referrerpolicy="no-referrer" crossorigin="anonymous">
239
+ {% endmacro %}
241
240
 
242
241
  {% macro db_table_external_scripts() %}
243
- <script src="https://cdn.datatables.net/1.12.0/js/jquery.dataTables.min.js" integrity="sha512-fu0WiDG5xqtX2iWk7cp17Q9so54SC+5lk/z/glzwlKFdEOwGG6piUseP2Sik9hlvlmyOJ0lKXRSuv1ltdVk9Jg==" referrerpolicy="no-referrer" crossorigin="anonymous"></script>
244
- <script src="https://cdn.datatables.net/1.12.0/js/dataTables.bootstrap5.min.js" integrity="sha512-nfoMMJ2SPcUdaoGdaRVA1XZpBVyDGhKQ/DCedW2k93MTRphPVXgaDoYV1M/AJQLCiw/cl2Nbf9pbISGqIEQRmQ==" referrerpolicy="no-referrer" crossorigin="anonymous"></script>
245
- <script src="https://cdn.datatables.net/buttons/2.2.3/js/dataTables.buttons.min.js" integrity="sha512-QT3oEXamRhx0x+SRDcgisygyWze0UicgNLFM9Dj5QfJuu2TVyw7xRQfmB0g7Z5/TgCdYKNW15QumLBGWoPefYg==" referrerpolicy="no-referrer" crossorigin="anonymous"></script>
246
- <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.2.0/jszip.min.js" integrity="sha512-0zVs73boVJk7Mlo/06K7cX+GWqW4xv0waiKkfXPGEhQ3Ww3UznkFlywBKIx4XetI/StJwac4bUNoeBGJY3Yugw==" referrerpolicy="no-referrer" crossorigin="anonymous"></script>
247
- <script src="https://cdn.datatables.net/buttons/2.2.3/js/buttons.html5.js" integrity="sha512-BSdPiqLbAJOVF1Q+rleIJJIio/8Ihf1zXxfYMinSHMpKdRWX634Mi4Rt8LRYfn0k5nbSlFO7Y7klzNCG8tokFQ==" referrerpolicy="no-referrer" crossorigin="anonymous"></script>
248
- <script src="https://cdn.datatables.net/buttons/2.2.3/js/buttons.bootstrap5.js" integrity="sha512-ZA1gDCJI+Hul95Y1tSRi3D/GfWRRX11oJH+QqtjnpzJLBDmU9DsO2db5oL3Gn7LezkSL/XWCL5v04ZiCy/RpKQ==" referrerpolicy="no-referrer" crossorigin="anonymous"></script>
242
+ <script src="https://cdn.datatables.net/2.2.2/js/dataTables.min.js" integrity="sha512-iwuEh+XTZQNzwdjYrqsxyWJXyReKVclGX4D2uGYBGNIR6o0VBwIfeYQv+lQjxmye87K6C6mc7qrqJlCcaeZJhA==" referrerpolicy="no-referrer" crossorigin="anonymous"></script>
243
+ <script src="https://cdn.datatables.net/2.2.2/js/dataTables.bootstrap5.min.js" integrity="sha512-Cwi0jz7fz7mrX990DlJ1+rmiH/D9/rjfOoEex8C9qrPRDDqwMPdWV7pJFKzhM10gAAPlufZcWhfMuPN699Ej0w==" referrerpolicy="no-referrer" crossorigin="anonymous"></script>
244
+ <script src="https://cdn.datatables.net/buttons/3.2.2/js/dataTables.buttons.min.js" integrity="sha512-T/4qQRgBJ8Ev6Lk8M943pMIbCpgqtVf5XI77hxe3nQn0f9a0gn/WKXWMbuGv6cpjp9NM8Mc+3/3GnpW+3+TckA==" referrerpolicy="no-referrer" crossorigin="anonymous"></script>
245
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js" integrity="sha512-XMVd28F1oH/O71fzwBnV7HucLxVwtxf26XV8P4wPk26EDxuGZ91N8bsOttmnomcCD3CS5ZMRL50H0GgOHvegtg==" referrerpolicy="no-referrer" crossorigin="anonymous"></script>
246
+ <script src="https://cdn.datatables.net/buttons/3.2.2/js/buttons.html5.min.js" integrity="sha512-I86DAquH004N60kPVNHp+9QkC5y61C5ODHj6ewhddXnewOJ31wyOJHNlNEr8NUR3xqtGozfMb557So1pR0uDCA==" referrerpolicy="no-referrer" crossorigin="anonymous"></script>
247
+ <script src="https://cdn.datatables.net/buttons/3.2.2/js/buttons.bootstrap5.min.js" integrity="sha512-rVAaUqNTbX7lADp767RxnIMvbROobK+gn7SpbbPc+qMUPotgAkSsRhCKF5ziUEquBsdGcv3eOaZK1fIbGwh5CA==" referrerpolicy="no-referrer" crossorigin="anonymous"></script>
249
248
  {% endmacro %}
scout/server/utils.py CHANGED
@@ -206,6 +206,19 @@ def user_institutes(store, login_user):
206
206
  return institutes
207
207
 
208
208
 
209
+ def get_case_genome_build(case_obj: dict) -> str:
210
+ """returns the genome build of a case, as a string."""
211
+ return "38" if "38" in case_obj.get("genome_build", "37") else "37"
212
+
213
+
214
+ def get_case_mito_chromosome(case_obj: dict) -> str:
215
+ """Returns MT or M, according to the genome build of a case."""
216
+ case_build = get_case_genome_build(case_obj)
217
+ if case_build == "38":
218
+ return "M"
219
+ return "MT"
220
+
221
+
209
222
  def case_has_mtdna_report(case_obj: dict):
210
223
  """Display mtDNA report on the case sidebar only for some specific cases."""
211
224
  if case_obj.get("track", "rare") == "cancer":
@@ -326,6 +339,11 @@ def case_append_alignments(case_obj: dict):
326
339
  {"path": "rhocall_wig", "append_to": "rhocall_wigs", "index": None},
327
340
  {"path": "upd_regions_bed", "append_to": "upd_regions_beds", "index": None},
328
341
  {"path": "upd_sites_bed", "append_to": "upd_sites_beds", "index": None},
342
+ {
343
+ "path": "minor_allele_frequency_wig",
344
+ "append_to": "minor_allele_frequency_wigs",
345
+ "index": None,
346
+ },
329
347
  {"path": "tiddit_coverage_wig", "append_to": "tiddit_coverage_wigs", "index": None},
330
348
  ]
331
349
 
@@ -7,6 +7,7 @@ LOG = logging.getLogger(__name__)
7
7
  SCHUG_BASE = "https://schug.scilifelab.se"
8
8
 
9
9
  BUILDS: Dict[str, str] = {"37": "GRCh37", "38": "GRCh38"}
10
+ CHROM_SEPARATOR = "[success]"
10
11
 
11
12
  SCHUG_RESOURCE_URL: Dict[str, str] = {
12
13
  "genes": "/genes/ensembl_genes/?build=",
@@ -8,7 +8,6 @@ from urllib.error import HTTPError
8
8
 
9
9
  import requests
10
10
  from defusedxml import ElementTree
11
- from flask import flash
12
11
 
13
12
  from scout.constants import HPO_URL, HPOTERMS_URL, ORPHA_URLS
14
13
 
@@ -344,7 +343,7 @@ def fetch_constraint():
344
343
  return exac_lines
345
344
 
346
345
 
347
- def fetch_refseq_version(refseq_acc):
346
+ def fetch_refseq_version(refseq_acc: str) -> str:
348
347
  """Fetch refseq version from entrez and return refseq version
349
348
 
350
349
  Args:
@@ -362,7 +361,6 @@ def fetch_refseq_version(refseq_acc):
362
361
  try:
363
362
  resp = get_request(base_url.format(refseq_acc))
364
363
  if resp is None:
365
- flash(f"Error: could not retrieve HGVS version for {refseq_acc} from Entrez eutils!")
366
364
  return version
367
365
  tree = ElementTree.fromstring(resp.content)
368
366
  version = tree.find("IdList").find("Id").text or version
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: scout-browser
3
- Version: 4.99.0
3
+ Version: 4.100.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