scout-browser 4.98.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 (91) 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/institute.py +42 -55
  5. scout/adapter/mongo/omics_variant.py +14 -1
  6. scout/adapter/mongo/query.py +24 -1
  7. scout/adapter/mongo/variant.py +44 -22
  8. scout/adapter/mongo/variant_loader.py +169 -186
  9. scout/build/individual.py +5 -1
  10. scout/build/variant/variant.py +8 -0
  11. scout/commands/download/ensembl.py +18 -3
  12. scout/commands/load/research.py +2 -3
  13. scout/commands/update/individual.py +3 -0
  14. scout/commands/update/panelapp.py +15 -2
  15. scout/constants/__init__.py +6 -2
  16. scout/constants/clnsig.py +2 -0
  17. scout/constants/file_types.py +12 -0
  18. scout/constants/igv_tracks.py +9 -6
  19. scout/constants/indexes.py +5 -4
  20. scout/constants/panels.py +3 -0
  21. scout/constants/query_terms.py +1 -0
  22. scout/constants/variant_tags.py +6 -6
  23. scout/demo/643594.config.yaml +1 -0
  24. scout/load/panelapp.py +11 -5
  25. scout/models/case/case.py +1 -0
  26. scout/models/case/case_loading_models.py +7 -1
  27. scout/parse/ensembl.py +8 -3
  28. scout/parse/variant/clnsig.py +38 -0
  29. scout/parse/variant/genotype.py +4 -10
  30. scout/parse/variant/models.py +5 -11
  31. scout/parse/variant/rank_score.py +5 -13
  32. scout/parse/variant/variant.py +90 -111
  33. scout/server/app.py +39 -22
  34. scout/server/blueprints/alignviewers/controllers.py +29 -10
  35. scout/server/blueprints/alignviewers/templates/alignviewers/igv_viewer.html +51 -11
  36. scout/server/blueprints/cases/controllers.py +9 -3
  37. scout/server/blueprints/cases/templates/cases/case_report.html +25 -13
  38. scout/server/blueprints/cases/templates/cases/chanjo2_form.html +1 -1
  39. scout/server/blueprints/cases/templates/cases/collapsible_actionbar.html +1 -1
  40. scout/server/blueprints/cases/templates/cases/gene_panel.html +1 -1
  41. scout/server/blueprints/cases/templates/cases/utils.html +25 -6
  42. scout/server/blueprints/clinvar/controllers.py +34 -15
  43. scout/server/blueprints/clinvar/templates/clinvar/clinvar_submissions.html +34 -12
  44. scout/server/blueprints/clinvar/templates/clinvar/multistep_add_variant.html +14 -5
  45. scout/server/blueprints/clinvar/views.py +14 -2
  46. scout/server/blueprints/diagnoses/static/diagnoses.js +8 -1
  47. scout/server/blueprints/institutes/controllers.py +10 -2
  48. scout/server/blueprints/institutes/static/variants_list_scripts.js +9 -1
  49. scout/server/blueprints/institutes/templates/overview/institute_sidebar.html +9 -1
  50. scout/server/blueprints/login/controllers.py +112 -12
  51. scout/server/blueprints/login/views.py +38 -60
  52. scout/server/blueprints/mme/__init__.py +1 -0
  53. scout/server/blueprints/mme/controllers.py +18 -0
  54. scout/server/blueprints/mme/templates/mme/mme_submissions.html +153 -0
  55. scout/server/blueprints/mme/views.py +34 -0
  56. scout/server/blueprints/panels/templates/panels/panel.html +19 -6
  57. scout/server/blueprints/phenotypes/templates/phenotypes/hpo_terms.html +8 -1
  58. scout/server/blueprints/public/templates/public/index.html +5 -1
  59. scout/server/blueprints/variant/controllers.py +19 -10
  60. scout/server/blueprints/variant/templates/variant/acmg.html +15 -2
  61. scout/server/blueprints/variant/templates/variant/cancer-variant.html +1 -1
  62. scout/server/blueprints/variant/templates/variant/components.html +38 -16
  63. scout/server/blueprints/variant/templates/variant/sv-variant.html +2 -2
  64. scout/server/blueprints/variant/templates/variant/utils.html +23 -11
  65. scout/server/blueprints/variant/templates/variant/variant.html +42 -1
  66. scout/server/blueprints/variant/views.py +12 -0
  67. scout/server/blueprints/variants/controllers.py +20 -3
  68. scout/server/blueprints/variants/forms.py +8 -3
  69. scout/server/blueprints/variants/templates/variants/components.html +34 -0
  70. scout/server/blueprints/variants/templates/variants/indicators.html +11 -13
  71. scout/server/blueprints/variants/templates/variants/mei-variants.html +8 -6
  72. scout/server/blueprints/variants/templates/variants/sv-variants.html +9 -7
  73. scout/server/blueprints/variants/templates/variants/utils.html +35 -34
  74. scout/server/blueprints/variants/templates/variants/variants.html +4 -25
  75. scout/server/config.py +8 -0
  76. scout/server/extensions/bionano_extension.py +0 -1
  77. scout/server/extensions/chanjo2_extension.py +54 -13
  78. scout/server/links.py +15 -0
  79. scout/server/static/bs_styles.css +34 -6
  80. scout/server/templates/utils.html +9 -10
  81. scout/server/utils.py +40 -5
  82. scout/utils/acmg.py +25 -26
  83. scout/utils/ensembl_biomart_clients.py +2 -1
  84. scout/utils/ensembl_rest_clients.py +25 -32
  85. scout/utils/hgvs.py +1 -1
  86. scout/utils/scout_requests.py +1 -3
  87. {scout_browser-4.98.0.dist-info → scout_browser-4.100.0.dist-info}/METADATA +10 -14
  88. {scout_browser-4.98.0.dist-info → scout_browser-4.100.0.dist-info}/RECORD +91 -87
  89. {scout_browser-4.98.0.dist-info → scout_browser-4.100.0.dist-info}/WHEEL +0 -0
  90. {scout_browser-4.98.0.dist-info → scout_browser-4.100.0.dist-info}/entry_points.txt +0 -0
  91. {scout_browser-4.98.0.dist-info → scout_browser-4.100.0.dist-info}/licenses/LICENSE +0 -0
@@ -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> using <strong>Scout v.{{current_scout_version}}</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> for genome build <strong>{{case.genome_build }}</strong>.<br><br>
67
67
  {{ phenotype_panel() }}
68
68
  {{ gene_panels_panel()}}
69
69
  {{ causatives_panel()}}
@@ -104,7 +104,7 @@
104
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
106
  {% if case.scout_load_version %}
107
- <td> Loaded with <strong>Scout v.{{case.scout_load_version}}</strong></td>
107
+ <td> Loaded with <strong>Scout v{{case.scout_load_version}}</strong></td>
108
108
  {% endif %}
109
109
  </tr>
110
110
  </table>
@@ -383,7 +383,7 @@
383
383
  {% set duplicated_variants = [] %}
384
384
  {% if variants.classified_detailed %}
385
385
  {% for variant in variants.classified_detailed|sort(attribute='variant_rank') %}
386
- {% if variant['_id'] not in printed_vars %}
386
+ {% if variant['_id'] not in printed_vars and variant not in variants.dismissed_detailed %}
387
387
  {% do printed_vars.append(variant['_id']) %}
388
388
  {{ variant_content(variant, loop.index) }}
389
389
  <br>
@@ -395,7 +395,7 @@
395
395
  No ACMG-classified variants available for this case
396
396
  {% endif %}
397
397
  {% if variants.classified_detailed and duplicated_variants|length == variants.classified_detailed|length %}
398
- All ACMG-classified variants are already described in the previous views
398
+ All ACMG-classified variants are already described in the other panels
399
399
  {% endif %}
400
400
  </div>
401
401
  </div>
@@ -410,7 +410,7 @@
410
410
  {% set duplicated_variants = [] %}
411
411
  {% if variants.ccv_classified_detailed %}
412
412
  {% for variant in variants.ccv_classified_detailed|sort(attribute='variant_rank') %}
413
- {% if variant['_id'] not in printed_vars %}
413
+ {% if variant['_id'] not in printed_vars and variant not in variants.dismissed_detailed %}
414
414
  {% do printed_vars.append(variant['_id']) %}
415
415
  {{ variant_content(variant, loop.index) }}
416
416
  <br>
@@ -422,7 +422,7 @@
422
422
  No ClinGen-CGC-VICC-classified variants available for this case
423
423
  {% endif %}
424
424
  {% if variants.ccv_classified_detailed and duplicated_variants|length == variants.ccv_classified_detailed|length %}
425
- All ClinGen-CGC-VICC-classified variants are already described in the previous views
425
+ All ClinGen-CGC-VICC-classified variants are already described in the other panels
426
426
  {% endif %}
427
427
  </div>
428
428
  </div>
@@ -437,7 +437,7 @@
437
437
  {% set duplicated_variants = [] %}
438
438
  {% if variants.tagged_detailed %}
439
439
  {% for variant in variants.tagged_detailed|sort(attribute='variant_rank') %}
440
- {% if variant['_id'] not in printed_vars %}
440
+ {% if variant['_id'] not in printed_vars and variant not in variants.dismissed_detailed %}
441
441
  {% do printed_vars.append(variant['_id']) %}
442
442
  {{ variant_content(variant, loop.index) }}
443
443
  <br>
@@ -461,7 +461,7 @@
461
461
  No tagged variants for this case
462
462
  {% endif %}
463
463
  {% if (variants.tagged_detailed or variants.tier_detailed) and duplicated_variants|length == (variants.tagged_detailed|length+variants.tier_detailed|length) %}
464
- All tagged variants are already described in the previous views
464
+ All tagged variants are already described in the other panels
465
465
  {% endif %}
466
466
  </div>
467
467
  </div>
@@ -500,7 +500,7 @@
500
500
  {% set duplicated_variants = [] %}
501
501
  {% if variants.commented_detailed %}
502
502
  {% for variant in variants.commented_detailed|sort(attribute='variant_rank') %}
503
- {% if variant['_id'] not in printed_vars %}
503
+ {% if variant['_id'] not in printed_vars and variant not in variants.dismissed_detailed %}
504
504
  {% do printed_vars.append(variant['_id']) %}
505
505
  {% if variant.category == 'snv' %}
506
506
  {{ sn_variant_content(variant, loop.index) }}
@@ -520,7 +520,7 @@
520
520
  No commented variants for this case
521
521
  {% endif %}
522
522
  {% if variants.commented_detailed and duplicated_variants|length == variants.commented_detailed|length %}
523
- All commented variants are already described in the previous views
523
+ All commented variants are already described in the other panels
524
524
  {% endif %}
525
525
  </div>
526
526
  </div>
@@ -845,7 +845,8 @@
845
845
  <th class="w-5"></th>
846
846
  <th class="w-25"><strong>Variant</strong></th>
847
847
  <th class="w-5"><strong>Category</strong></th>
848
- <th class="w-25"><strong>Genes</strong></th>
848
+ <th class="w-20"><strong>Genes</strong></th>
849
+ <th class="w-5"><strong>Classification</strong></th>
849
850
  <th class="w-45"><strong>Dismissed description</strong></th>
850
851
  </tr>
851
852
  </thead>
@@ -867,7 +868,14 @@
867
868
  <td style="width:15%;"
868
869
  {{ dismissed_gene_list(variant) }}
869
870
  </td>
870
-
871
+ <td>
872
+ {% if variant.acmg_classification %}
873
+ <span class="badge rounded-pill bg-{{variant.acmg_classification['color'] if variant.acmg_classification['color'] else 'secondary'}}" title="{{variant.acmg_classification['code']}}">{{variant.acmg_classification['short'] }}</span>
874
+ {% endif %}
875
+ {% if variant.ccv_classification %}
876
+ <span class="badge rounded-pill bg-{{variant.ccv_classification['color'] if variant.ccv_classification['color'] else 'secondary'}}" title="{{variant.ccv_classification['code']}}">{{variant.ccv_classification['short'] }}</span>
877
+ {% endif %}
878
+ </td>
871
879
  <td rowspan="2">
872
880
  <ul>
873
881
  {% for reason in variant.dismiss_variant if not reason == "Select a tag" %}
@@ -1531,7 +1539,11 @@
1531
1539
  <td>
1532
1540
  {% if variant.acmg_classification %}
1533
1541
  <span class="badge rounded-pill bg-{{variant.acmg_classification['color'] if variant.acmg_classification['color'] else 'secondary'}}" title="{{variant.acmg_classification['code']}}">{{variant.acmg_classification['short'] }}</span>
1534
- {% elif variant.manual_rank %}
1542
+ {% endif %}
1543
+ {% if variant.ccv_classification%}
1544
+ <span class="badge rounded-pill bg-{{variant.ccv_classification['color'] if variant.ccv_classification['color'] else 'secondary'}}" title="{{variant.ccv_classification['code']}}">{{variant.ccv_classification['short'] }}</span>
1545
+ {% endif%}
1546
+ {% if variant.manual_rank %}
1535
1547
  <span class="badge rounded-pill bg-secondary" title="Manual rank">{{ manual_rank_options[variant.manual_rank]['label'] }}</span>
1536
1548
  {% else %}
1537
1549
  -
@@ -1,6 +1,6 @@
1
1
  {% macro chanjo2_report_form(institute_obj, case_obj, panel_name, report_type, hgnc_ids, link_text, link_class = "link-primary") %}
2
2
 
3
- {% set form_name = "chanjo2_"+panel_name+"_"+report_type %}
3
+ {% set form_name = "chanjo2_" ~ panel_name ~ "_" ~ report_type %}
4
4
  {% set form_action = config.CHANJO2_URL+"/"+report_type %}
5
5
  {% set build = "GRCh38" if "38" in case_obj.get("genome_build", "37") else "GRCh37" %}
6
6
  {% set default_level = institute_obj.coverage_cutoff %}
@@ -196,7 +196,7 @@
196
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
197
  <div class="d-flex w-100 justify-content-start align-items-center">
198
198
  <span class="fa fa-gear fa-fw me-3"></span>
199
- <span class="menu-collapsed">v.{{ case.scout_load_version }}</span>
199
+ <span class="menu-collapsed">v{{ case.scout_load_version }}</span>
200
200
  </div>
201
201
  </div>
202
202
  {% endif %}
@@ -18,7 +18,7 @@
18
18
  {% for panel in case.panels %}
19
19
  <tr {% if panel.is_default %} class="bg-info" {% endif %}>
20
20
  <td>
21
- <a {% if panel.is_default %} class="text-white" {% endif %} href="{{ url_for('panels.panel', panel_id=panel.panel_id, case_id=case._id, institute_id=institute._id) }}">
21
+ <a {% if panel.is_default %} class="text-white" {% endif %} href="{{ url_for('panels.panel', panel_id=panel.panel_id, case_id=case._id, institute_id=institute._id) }}" target="_blank" rel="noopener">
22
22
  {{ panel.display_name|truncate(30, True) }}
23
23
  </a>
24
24
  {% if panel.removed %}
@@ -313,6 +313,22 @@
313
313
 
314
314
  {{ display_genes|join(", ") }}
315
315
 
316
+ {% elif variant.category == "outlier" %}
317
+ {{ variant.sub_category|upper }} - {% if variant.genes %}
318
+ {% for gene in variant.genes %}
319
+ {% if gene.hgnc_symbol %}
320
+ {{ gene.hgnc_symbol }}
321
+ {% else %}
322
+ {{gene.hgnc_id}}
323
+ {% endif %}
324
+ {% endfor %} - {% if variant.sub_category == "splicing" %}
325
+ {{ variant.delta_psi }}&Delta;&psi; {{ variant.potential_impact }} - fs {{ variant.causes_frameshift }}
326
+ {% else %}
327
+ {{ variant.l2fc }}{% if variant.l2fc > 0 %}&uarr;{% elif variant.l2fc < 0 %}&darr;{% endif %}
328
+ {% endif %}
329
+ {% else %}
330
+ {{ variant.gene_name_orig }}
331
+ {% endif %}
316
332
  {% else %} <!-- structural variants -->
317
333
  {{ variant.sub_category|upper }}({{ variant.chromosome }}{{ variant.cytoband_start }}-{{ variant.end_chrom }}{{ variant.cytoband_end }})
318
334
  {% endif %}
@@ -325,21 +341,24 @@
325
341
 
326
342
  {% if variant.category in ("mei", "str", "snv", "cancer") %}
327
343
  {% if variant.category == "cancer" %}
328
- <a href="{{ url_for('variant.cancer_variant',
344
+ <a href='{{ url_for('variant.cancer_variant',
329
345
  institute_id=variant.institute,
330
346
  case_name=case.display_name,
331
- variant_id=variant._id) }}" target="_blank">
347
+ variant_id=variant._id) }}' target='_blank'>
332
348
  {% else %}
333
- <a href="{{ url_for('variant.variant',
349
+ <a href='{{ url_for('variant.variant',
334
350
  institute_id=variant.institute,
335
351
  case_name=case.display_name,
336
- variant_id=variant._id) }}" target="_blank">
352
+ variant_id=variant._id) }}' target='_blank'>
337
353
  {% endif %}
354
+ {% elif variant.category == "outlier" %}
355
+ <a href='{{ url_for('omics_variants.outliers',
356
+ institute_id=variant.institute, case_name=case.display_name) }}' target='_blank'>
338
357
  {% else %} <!-- structural variants -->
339
- <a href="{{ url_for('variant.sv_variant',
358
+ <a href='{{ url_for('variant.sv_variant',
340
359
  institute_id=variant.institute,
341
360
  case_name=case.display_name,
342
- variant_id=variant._id) }}" target="_blank">
361
+ variant_id=variant._id) }}' target='_blank'>
343
362
  {% endif %}
344
363
  {{ pretty_variant(variant) }}
345
364
  </a>
@@ -28,30 +28,45 @@ LOG = logging.getLogger(__name__)
28
28
 
29
29
 
30
30
  def _get_var_tx_hgvs(case_obj: dict, variant_obj: dict) -> List[Tuple[str, str]]:
31
- """Retrieve all transcripts / hgvs for a given variant."""
31
+ """Retrieve all transcripts / HGVS for a given variant."""
32
32
 
33
33
  build = str(case_obj.get("genome_build", "37"))
34
34
  tx_hgvs_list = [("", "Do not specify")]
35
+ case_has_build_37 = "37" in case_obj.get("genome_build", "37")
36
+
35
37
  add_gene_info(store, variant_obj, genome_build=build)
38
+
36
39
  for gene in variant_obj.get("genes", []):
37
- for tx in gene.get("transcripts", []):
40
+ transcripts = gene.get("transcripts", [])
41
+
42
+ for tx in transcripts:
43
+
44
+ refseq_id = tx.get("refseq_id")
45
+ coding_seq_name = tx.get("coding_sequence_name")
46
+ if not (refseq_id and coding_seq_name):
47
+ continue # Skip transcripts missing required fields
48
+
38
49
  mane_select = tx.get("mane_select_transcript")
39
- if all([tx.get("refseq_id"), tx.get("coding_sequence_name")]):
40
- for refseq in tx.get("refseq_identifiers"):
41
- refseq_version = fetch_refseq_version(refseq) # adds version to a refseq ID
42
- hgvs_simple = ":".join([refseq_version, tx["coding_sequence_name"]])
50
+ mane_plus_clinical = tx.get("mane_plus_clinical_transcript")
51
+
52
+ for refseq in tx.get("refseq_identifiers", []):
53
+ refseq_version = fetch_refseq_version(refseq) # Adds version to a RefSeq ID
54
+ hgvs_simple = f"{refseq_version}:{coding_seq_name}"
55
+
56
+ refseq_is_mane_select = mane_select == refseq_version
57
+ refseq_is_mane_plus_clinical = mane_plus_clinical == refseq_version
43
58
 
44
- # Validate descriptor using VariantValidator
45
- validated = validate_hgvs(build, hgvs_simple)
59
+ # Transcript is validate only when conditions are met
60
+ validated = (
61
+ validate_hgvs(build, hgvs_simple)
62
+ if (case_has_build_37 or refseq_is_mane_select or refseq_is_mane_plus_clinical)
63
+ else ""
64
+ )
46
65
 
47
- label = hgvs_simple
48
- if validated:
49
- label += "_validated_"
66
+ label = f"{hgvs_simple}{'_validated_' if validated else ''}{'_mane-select_' if refseq_is_mane_select else ''}{'_mane-plus-clinical_' if refseq_is_mane_plus_clinical else ''}"
50
67
 
51
- if mane_select and mane_select == refseq_version:
52
- label += "_mane-select_"
68
+ tx_hgvs_list.append((hgvs_simple, label))
53
69
 
54
- tx_hgvs_list.append((hgvs_simple, label))
55
70
  return tx_hgvs_list
56
71
 
57
72
 
@@ -604,8 +619,12 @@ def remove_item_from_submission(submission: str, object_type: str, subm_variant_
604
619
  if object_type == "variant_data":
605
620
  variant_id: str = subm_variant_id.split("_")[-1]
606
621
  variant_obj: dict = store.variant(document_id=variant_id)
622
+ if not variant_obj:
623
+ return
624
+ case_obj = store.case(case_id=variant_obj["case_id"])
625
+ if not case_obj:
626
+ return
607
627
  institute_obj: dict = store.institute(institute_id=variant_obj["institute"])
608
- case_obj: dict = store.case(case_id=variant_obj["case_id"])
609
628
  user_obj: dict = store.user(user_id=current_user._id)
610
629
  for category in ["case", "variant"]:
611
630
  store.create_event(
@@ -126,13 +126,19 @@
126
126
  </thead>
127
127
  <tbody>
128
128
  {% set var_key_name = {} %}
129
+
129
130
  {% for subm_variant in subm_obj.variant_data %} <!-- loop over the submitted variants-->
131
+ {% set case_name = subm_obj.cases[subm_variant.case_id] %}
130
132
  <tr>
131
133
  <td>{{loop.index}}</td>
132
134
  {% if subm_variant.category == 'sv' %}
133
135
  {% do var_key_name.update( {subm_variant.local_id : '_'.join([subm_variant.var_type, subm_variant.chromosome, subm_variant.breakpoint1 or subm_variant.outer_start or ""]) }) %}
134
136
  <td>
135
- <a href="{{ url_for('variant.sv_variant', institute_id=institute._id, case_name=subm_obj.cases[subm_variant.case_id], variant_id=subm_variant.local_id) }}" target="_blank" rel="noopener"><strong>{{var_key_name[subm_variant.local_id]|truncate(25,true,'..')}}</strong></a>
137
+ {% if "N/A" not in case_name %}
138
+ <a href="{{ url_for('variant.sv_variant', institute_id=institute._id, case_name=case_name, variant_id=subm_variant.local_id) }}" target="_blank" rel="noopener"><strong>{{var_key_name[subm_variant.local_id]|truncate(25,true,'..')}}</strong></a>
139
+ {% else %}
140
+ {{ var_key_name[subm_variant.local_id]|truncate(25,true,'..') }} (N/A)
141
+ {% endif %}
136
142
  </td>
137
143
  <td><button id="{{subm_variant._id}}" type="button" class="btn btn-primary btn-xs var_btn"><span class="fa fa-search-plus" aria-hidden="true"></span></button></td>
138
144
  <td><div class="badge bg-warning">SV</div></td>
@@ -143,21 +149,27 @@
143
149
  {% do var_key_name.update({subm_variant.local_id : '_'.join([subm_variant.chromosome, subm_variant.start, subm_variant.ref[0:5], subm_variant.alt[0:5]]) }) %}
144
150
  {% endif %}
145
151
  <td>
146
- <a href="{{ url_for('variant.variant', institute_id=institute._id, case_name=subm_obj.cases[subm_variant.case_id], variant_id=subm_variant.local_id) }}" target="_blank" rel="noopener"><strong>{{var_key_name[subm_variant.local_id]|truncate(25,true,'..')}}</strong></a>
152
+ {% if "N/A" not in case_name %}
153
+ <a href="{{ url_for('variant.variant', institute_id=institute._id, case_name=case_name, variant_id=subm_variant.local_id) }}" target="_blank" rel="noopener"><strong>{{var_key_name[subm_variant.local_id]|truncate(25,true,'..')}}</strong></a>
154
+ {% else %}
155
+ {{ var_key_name[subm_variant.local_id]|truncate(25,true,'..') }} (N/A)
156
+ {% endif %}
147
157
  </td>
148
158
  <td><button id="{{subm_variant._id}}" type="button" class="btn btn-primary btn-xs var_btn"><span class="fa fa-search-plus" aria-hidden="true"></span></button></td>
149
159
  <td><div class="badge bg-success">SNV</div></td>
150
160
  {% endif %}
151
161
  </td>
152
- <td><a href="{{ url_for('cases.case', institute_id=institute._id, case_name=subm_obj.cases[subm_variant.case_id]) }}" target="_blank" rel="noopener">{{subm_obj.cases[subm_variant.case_id]}}</a></td>
162
+ <td>{{ case_link(institute_id=institute._id, case_name=case_name) }}</td>
153
163
  <td>{{subm_variant.ref_seq or '-'}}</td>
154
164
  <td>{{subm_variant.gene_symbol or '-'}}</td>
155
165
  <td>{{subm_variant.hgvs|truncate(100,true,'..') or '-'}}</td>
156
166
  <td>{{subm_variant.clinsig}}</td>
157
167
  <td>{{subm_variant.added_by or "N/A"}}</td>
158
- <form id="delete_variant_{{subm_variant._id}}" action="{{ url_for('clinvar.clinvar_delete_object', submission=subm_obj._id, object_type='variant_data') }}" method="POST">
159
- <td><button type="submit" name="delete_object" value="{{subm_variant._id}}" class="btn btn-danger btn-xs"><span class="fa fa-trash" aria-hidden="true"></span></button></td>
160
- </form>
168
+ <td>
169
+ <form id="delete_variant_{{subm_variant._id}}" action="{{ url_for('clinvar.clinvar_delete_object', submission=subm_obj._id, object_type='variant_data') }}" method="POST">
170
+ <button type="submit" name="delete_object" value="{{subm_variant._id}}" class="btn btn-danger btn-xs"><span class="fa fa-trash" aria-hidden="true"></span></button>
171
+ </form>
172
+ </td>
161
173
  </tr>
162
174
  <tr>
163
175
  <td colspan=11>
@@ -191,9 +203,9 @@
191
203
  <thead>
192
204
  <tr>
193
205
  <th></th>
194
- <th>Individual ID</th>
206
+ <th>Individual</th>
195
207
  <th></th>
196
- <th>Case ID</th>
208
+ <th>Case</th>
197
209
  <th>Variant</th>
198
210
  <th>Allele origin</th>
199
211
  <th></th>
@@ -209,12 +221,14 @@
209
221
  </td>
210
222
  </form>
211
223
  <td><button id="{{case._id}}" type="button" class="btn btn-primary btn-xs cd_btn"><span class="fa fa-search-plus" aria-hidden="true"></span></button></td>
212
- <td><a href="{{ url_for('cases.case', institute_id=institute._id, case_name=subm_obj.cases[case.case_id]) }}" target="_blank" rel="noopener">{{subm_obj.cases[case.case_id]}}</a></td>
224
+ <td>{{ case_link(institute_id=institute._id, case_name=subm_obj.cases[case.case_id]) }}</td>
213
225
  <td>{{var_key_name[case.linking_id]|truncate(100,true,'..')}}</td>
214
226
  <td>{{case.allele_origin}}</td>
215
- <form id="delete_casedata_{{case._id}}" action="{{ url_for('clinvar.clinvar_delete_object', submission=subm_obj._id, object_type='case_data') }}" method="POST">
216
- <td><button type="submit" name="delete_object" value="{{case._id}}" class="btn btn-danger btn-xs"><span class="fa fa-trash" aria-hidden="true"></span></button></td>
217
- </form>
227
+ <td>
228
+ <form id="delete_casedata_{{case._id}}" action="{{ url_for('clinvar.clinvar_delete_object', submission=subm_obj._id, object_type='case_data') }}" method="POST">
229
+ <button type="submit" name="delete_object" value="{{case._id}}" class="btn btn-danger btn-xs"><span class="fa fa-trash" aria-hidden="true"></span></button>
230
+ </form>
231
+ </td>
218
232
  </tr>
219
233
  <tr>
220
234
  <td colspan=8>
@@ -242,6 +256,14 @@
242
256
  </div>
243
257
  {% endmacro %}
244
258
 
259
+ {% macro case_link(institute_id, case_name) %}
260
+ {% if "N/A" in case_name %}
261
+ {{ case_name }}
262
+ {% else %}
263
+ <a href="{{ url_for('cases.case', institute_id=institute_id, case_name=case_name) }}" target="_blank">{{case_name}}</a>
264
+ {% endif %}
265
+ {% endmacro %}
266
+
245
267
  {% macro action_modal(action_type, subm_id) %}
246
268
  <div class="modal fade" id="{{action_type}}Modal_{{subm_id}}" tabindex="-1">
247
269
  <div class="modal-dialog">
@@ -81,7 +81,7 @@
81
81
  </div>
82
82
  <div class="my-2 mx-lg-2" style="width:30%; display: inline">{{variant_data.var_form.assertion_method_cit_id(class="bg-white")}}</div>
83
83
  </div>
84
-
84
+ <input type="button" name="previous" class="previous action-button-previous" value="Previous"/>
85
85
  <input type="button" name="next" class="next action-button" value="Next"/>
86
86
  </fieldset>
87
87
  <fieldset data-step="3">
@@ -92,7 +92,7 @@
92
92
  {% if var_category == 'snv' %}
93
93
  <br><br>
94
94
  <!-- Transcripts & HGVS:(optional) -->
95
- {{variant_data.var_form.tx_hgvs.label(class="fw-bold, text-dark")}}
95
+ {{ variant_data.var_form.tx_hgvs.label(class="fw-bold, text-dark") }}
96
96
 
97
97
  <span class="text-danger" data-bs-toggle='tooltip' title="If you do not provide any HGVS expression, chromosome coordinates will be used to describe this variant instead (automatic). HGVS expressions were validated using VariantValidator"><strong>?</strong></span>
98
98
  <span class="badge bg-primary float-end"><a class="text-white" href="https://variantvalidator.org/service/validate/" target="_blank" rel="noopener">VariantValidator</a></span>
@@ -101,7 +101,7 @@
101
101
  {% with messages = get_flashed_messages() %}
102
102
  {% if messages %}
103
103
  {% for message in messages %}
104
- <span class="ml-3" style="color:red">{{ message }}</span><br>
104
+ <span class="ml-3">{{ message }}</span><br>
105
105
  {% endfor %}
106
106
  <br><br>
107
107
  {% endif %}
@@ -113,14 +113,17 @@
113
113
  {% for item_row in variant_data.var_form.tx_hgvs | batch(3) %}
114
114
  <tr>
115
115
  {% for item in item_row %}
116
- {% set ns = namespace(label='', validated=false, mane_select=false) %}
117
-
116
+ {% set ns = namespace(label='', validated=false, mane_select=false, mane_plus_clinical=false) %}
118
117
  {% if "_validated_" in item.label.text %}
119
118
  {% set ns.validated = true %}
120
119
  {% endif %}
121
120
  {% if "_mane-select_" in item.label.text %}
122
121
  {% set ns.mane_select = true %}
123
122
  {% endif %}
123
+ {% if "_mane-plus-clinical_" in item.label.text %}
124
+ {% set ns.mane_plus_clinical = true %}
125
+ {% endif %}
126
+
124
127
  {% set ns.label = item.label.text | replace("_validated_", "") | replace("_mane-select_", "") %}
125
128
 
126
129
  <td style="width: 3%; text-align: right; vertical-align: baseline;">
@@ -138,6 +141,9 @@
138
141
  {% if ns.mane_select %}
139
142
  <span class='badge bg-dark'>MANE SELECT</span>
140
143
  {% endif %}
144
+ {% if ns.mane_plus_clinical %}
145
+ <span class='badge bg-dark'>MANE PLUS CLINICAL</span>
146
+ {% endif %}
141
147
  {% if ns.validated %}
142
148
  <em class="fa fa-check text-success" aria-hidden="true" data-bs-toggle="tooltip" title="Verified by VariantValidator"></em>
143
149
  {% endif %}
@@ -147,6 +153,9 @@
147
153
  </tr>
148
154
  {% endfor %}
149
155
  </table>
156
+
157
+ <span class="text-danger">HGVS validation is performed only for variants in build GRCh37 or MANE Select and MANE Plus Clinical transcripts. For any other available HGVS present in this list, manual validation can be performed using the VariantValidator link above.</span>
158
+
150
159
  <br><br>
151
160
  <!-- dbSNP identifier -->
152
161
  {{variant_data.var_form.variations_ids.label(class="fw-bold, text-dark")}}
@@ -3,10 +3,22 @@ from json import dumps
3
3
  from tempfile import NamedTemporaryFile
4
4
  from typing import List, Tuple
5
5
 
6
- from flask import Blueprint, flash, redirect, render_template, request, send_file, url_for
6
+ from flask import (
7
+ Blueprint,
8
+ flash,
9
+ redirect,
10
+ render_template,
11
+ request,
12
+ send_file,
13
+ url_for,
14
+ )
7
15
  from flask_login import current_user
8
16
 
9
- from scout.constants.clinvar import CASEDATA_HEADER, CLINVAR_HEADER, GERMLINE_CLASSIF_TERMS
17
+ from scout.constants.clinvar import (
18
+ CASEDATA_HEADER,
19
+ CLINVAR_HEADER,
20
+ GERMLINE_CLASSIF_TERMS,
21
+ )
10
22
  from scout.server.extensions import clinvar_api, store
11
23
  from scout.server.utils import institute_and_case
12
24
 
@@ -135,7 +135,14 @@ function initialiseTable(data) {
135
135
  $('#diagnoses_table').DataTable({
136
136
  data: data,
137
137
  paging: true,
138
- dom: 'Brtip',
138
+ layout: {
139
+ topStart: 'buttons',
140
+ topEnd: {
141
+ search: {
142
+ placeholder: 'Filter further...'
143
+ }
144
+ }
145
+ },
139
146
  buttons: [
140
147
  {
141
148
  extend: 'excelHtml5',
@@ -391,8 +391,16 @@ def update_institute_settings(store: MongoAdapter, institute_obj: Dict, form: Mu
391
391
  updated_institute = store.update_institute(
392
392
  internal_id=institute_obj["_id"],
393
393
  sanger_recipients=get_sanger_recipients(form),
394
- coverage_cutoff=int(form.get("coverage_cutoff")),
395
- frequency_cutoff=float(form.get("frequency_cutoff")),
394
+ coverage_cutoff=(
395
+ int(form["coverage_cutoff"])
396
+ if form.get("coverage_cutoff")
397
+ else form.get("coverage_cutoff")
398
+ ),
399
+ frequency_cutoff=(
400
+ float(form["frequency_cutoff"])
401
+ if form.get("frequency_cutoff")
402
+ else form.get("frequency_cutoff")
403
+ ),
396
404
  show_all_cases_status=form.getlist("show_all_cases_status"),
397
405
  display_name=form.get("display_name"),
398
406
  phenotype_groups=phenotype_groups,
@@ -1,7 +1,15 @@
1
1
  $(document).ready(function() {
2
2
  $('#variants_table').DataTable( {
3
3
  paging: false,
4
- dom: 'Bfrtip',
4
+ searching: true,
5
+ layout: {
6
+ topStart: 'buttons',
7
+ topEnd: {
8
+ search: {
9
+ placeholder: 'Search'
10
+ }
11
+ }
12
+ },
5
13
  buttons: [
6
14
  'copyHtml5',
7
15
  'excelHtml5',
@@ -51,7 +51,15 @@
51
51
  </div>
52
52
  </a>
53
53
 
54
- <!-- Variant filters -->
54
+ <!-- MME data menu item -->
55
+ <a href="{{ url_for('mme.mme_submissions', institute_id=institute._id) }}" class="bg-dark list-group-item list-group-item-action flex-column align-items-start">
56
+ <div class="d-flex w-100 justify-content-start align-items-center">
57
+ <span class="fas fa-people-arrows me-3"></span>
58
+ <span class="menu-collapsed">MME submissions</span>
59
+ </div>
60
+ </a>
61
+
62
+ <!-- Variant filters -->
55
63
  <a href="{{ url_for('overview.filters', institute_id=institute._id) }}" class="bg-dark list-group-item list-group-item-action flex-column align-items-start">
56
64
  <div class="d-flex w-100 justify-content-start align-items-center">
57
65
  <span class="fa fa-filter me-3"></span>