scout-browser 4.100.2__py3-none-any.whl → 4.102.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 (52) hide show
  1. scout/adapter/mongo/case.py +20 -6
  2. scout/adapter/mongo/clinvar.py +7 -7
  3. scout/adapter/mongo/hgnc.py +7 -2
  4. scout/adapter/mongo/omics_variant.py +8 -0
  5. scout/adapter/mongo/variant_loader.py +6 -2
  6. scout/constants/__init__.py +1 -0
  7. scout/constants/file_types.py +1 -1
  8. scout/constants/igv_tracks.py +6 -2
  9. scout/constants/phenotype.py +1 -0
  10. scout/load/hpo.py +8 -2
  11. scout/server/blueprints/alignviewers/controllers.py +8 -6
  12. scout/server/blueprints/alignviewers/templates/alignviewers/igv_viewer.html +2 -0
  13. scout/server/blueprints/alignviewers/templates/alignviewers/utils.html +1 -1
  14. scout/server/blueprints/cases/controllers.py +56 -28
  15. scout/server/blueprints/cases/templates/cases/case_report.html +9 -88
  16. scout/server/blueprints/cases/templates/cases/matchmaker.html +1 -1
  17. scout/server/blueprints/cases/templates/cases/phenotype.html +1 -1
  18. scout/server/blueprints/cases/templates/cases/utils.html +27 -25
  19. scout/server/blueprints/cases/views.py +32 -33
  20. scout/server/blueprints/clinvar/controllers.py +18 -23
  21. scout/server/blueprints/clinvar/templates/clinvar/multistep_add_variant.html +0 -2
  22. scout/server/blueprints/diagnoses/controllers.py +4 -8
  23. scout/server/blueprints/diagnoses/templates/diagnoses/diagnoses.html +1 -1
  24. scout/server/blueprints/diagnoses/templates/diagnoses/disease_term.html +1 -1
  25. scout/server/blueprints/diagnoses/views.py +2 -2
  26. scout/server/blueprints/institutes/controllers.py +107 -73
  27. scout/server/blueprints/institutes/templates/overview/cases.html +8 -7
  28. scout/server/blueprints/login/controllers.py +2 -1
  29. scout/server/blueprints/login/views.py +5 -2
  30. scout/server/blueprints/omics_variants/views.py +2 -2
  31. scout/server/blueprints/panels/views.py +11 -2
  32. scout/server/blueprints/phenotypes/controllers.py +15 -2
  33. scout/server/blueprints/phenotypes/templates/phenotypes/hpo_terms.html +1 -1
  34. scout/server/blueprints/variant/controllers.py +10 -11
  35. scout/server/blueprints/variant/templates/variant/utils.html +1 -1
  36. scout/server/blueprints/variant/templates/variant/variant_details.html +68 -60
  37. scout/server/blueprints/variant/utils.py +25 -0
  38. scout/server/blueprints/variants/controllers.py +11 -42
  39. scout/server/blueprints/variants/templates/variants/cancer-variants.html +3 -3
  40. scout/server/blueprints/variants/templates/variants/indicators.html +18 -15
  41. scout/server/blueprints/variants/templates/variants/utils.html +1 -1
  42. scout/server/blueprints/variants/views.py +9 -8
  43. scout/server/config.py +3 -0
  44. scout/server/extensions/beacon_extension.py +7 -2
  45. scout/server/templates/bootstrap_global.html +11 -1
  46. scout/server/templates/layout.html +6 -1
  47. scout/server/utils.py +24 -3
  48. {scout_browser-4.100.2.dist-info → scout_browser-4.102.0.dist-info}/METADATA +1 -1
  49. {scout_browser-4.100.2.dist-info → scout_browser-4.102.0.dist-info}/RECORD +52 -52
  50. {scout_browser-4.100.2.dist-info → scout_browser-4.102.0.dist-info}/WHEEL +0 -0
  51. {scout_browser-4.100.2.dist-info → scout_browser-4.102.0.dist-info}/entry_points.txt +0 -0
  52. {scout_browser-4.100.2.dist-info → scout_browser-4.102.0.dist-info}/licenses/LICENSE +0 -0
@@ -293,8 +293,18 @@
293
293
 
294
294
  {% if variant.category %}
295
295
  {% if variant.category in "str" %}
296
- {{ variant.str_repid }} {{ variant.alternative | replace("<", " ") | replace(">", "")}}
297
-
296
+ {% if variant.str_repid %}
297
+ {{ variant.str_repid }}
298
+ {% elif variant.str_trid %}
299
+ {{ variant.str_trid }}
300
+ {% else %}
301
+ {% for gene in variant.genes %} {{ gene.symbol }} {% endfor %}
302
+ {% endif %}
303
+ {% if variant.str_mc %}
304
+ STR{{ variant.str_mc }}
305
+ {% else %}
306
+ {{ variant.alternative|truncate(20,True) }}
307
+ {% endif %}
298
308
  {% elif variant.category in ("snv", "cancer") %}
299
309
  {% set display_genes = [] %}
300
310
  {% for gene in variant.genes %}
@@ -339,18 +349,24 @@
339
349
  {% macro pretty_link_variant(variant, case) %}
340
350
  {# Returns human readable links to the corresponding variant page #}
341
351
 
342
- {% if variant.category in ("mei", "str", "snv", "cancer") %}
343
- {% if variant.category == "cancer" %}
344
- <a href='{{ url_for('variant.cancer_variant',
352
+ {% if variant.category in ("mei", "snv") %}
353
+ <a href='{{ url_for('variant.variant',
345
354
  institute_id=variant.institute,
346
355
  case_name=case.display_name,
347
356
  variant_id=variant._id) }}' target='_blank'>
348
- {% else %}
357
+ {% elif variant.category == "str" %}
349
358
  <a href='{{ url_for('variant.variant',
359
+ institute_id=variant.institute,
360
+ case_name=case.display_name,
361
+ variant_id=variant._id) }}'
362
+ data-bs-toggle='tooltip'
363
+ title='{{ variant.alternative | replace("<", " ") | replace(">", "")}}'
364
+ target='_blank'>
365
+ {% elif variant.category == "cancer" %}
366
+ <a href='{{ url_for('variant.cancer_variant',
350
367
  institute_id=variant.institute,
351
368
  case_name=case.display_name,
352
369
  variant_id=variant._id) }}' target='_blank'>
353
- {% endif %}
354
370
  {% elif variant.category == "outlier" %}
355
371
  <a href='{{ url_for('omics_variants.outliers',
356
372
  institute_id=variant.institute, case_name=case.display_name) }}' target='_blank'>
@@ -360,7 +376,7 @@
360
376
  case_name=case.display_name,
361
377
  variant_id=variant._id) }}' target='_blank'>
362
378
  {% endif %}
363
- {{ pretty_variant(variant) }}
379
+ {{ pretty_variant(variant) }}
364
380
  </a>
365
381
  {% endmacro %}
366
382
 
@@ -442,21 +458,7 @@
442
458
  <div class="row">
443
459
  <div class="col">
444
460
  <i class="far fa-check-circle"></i>
445
- {% if variant.category == "snv" %}
446
- <a href="{{ url_for('variant.variant',
447
- institute_id=variant.institute,
448
- case_name=case.display_name,
449
- variant_id=variant._id) }}">
450
- {{ variant.hgnc_symbols|join(', ') }} (partial causative)
451
- {% else %}
452
- <a href="{{ url_for('variant.sv_variant',
453
- institute_id=variant.institute,
454
- case_name=case.display_name,
455
- variant_id=variant._id) }}">
456
- {{ variant.sub_category|upper }}({{ variant.chromosome }}{{ variant.cytoband_start }}-{{ variant.chromosome }}{{ variant.cytoband_end }})
457
- (partial causative)
458
- {% endif %}
459
- </a>
461
+ {{ pretty_link_variant(variant, case) }} (partial causative)
460
462
  </div>
461
463
  <div class="col-2" style="width:fit-content;">
462
464
  {{ remove_form(url_for('cases.mark_causative',
@@ -495,7 +497,7 @@
495
497
  </div>
496
498
  <div class="col-8">
497
499
  {% for hpo in variant_phenotypes.hpo_terms %}
498
- <a target="_blank" href="http://hpo.jax.org/app/browse/term/{{hpo.phenotype_id}}">
500
+ <a target="_blank" href="https://hpo.jax.org/browse/term/{{hpo.phenotype_id}}">
499
501
  <span class="badge badge-sm bg-info">{{hpo.phenotype_id}}</span>
500
502
  </a>
501
503
  {% else %}
@@ -627,7 +629,7 @@
627
629
  (included in ClinVar submission)
628
630
  {% elif variant.category in ('cancer', 'cancer_sv') %}
629
631
  <button data-bs-toggle='tooltip' data-bs-placement="bottom" title="Submission of somatic variants from Scout is temporarily suspended. We are working to harmonize submissions with changes introduced by ClinVar for this variant category." disabled >Add to ClinVar submission</button>
630
- {% else %}
632
+ {% elif variant.category in ('snv', 'sv') %}
631
633
  <button type="submit" name="var_id" value="{{variant._id}}" class="btn btn-secondary btn-sm" style="float: right;">Add to ClinVar submission</button>
632
634
  {% endif %}
633
635
  </form>
@@ -36,6 +36,7 @@ from scout.server.utils import (
36
36
  html_to_pdf_file,
37
37
  institute_and_case,
38
38
  jsonconverter,
39
+ safe_redirect_back,
39
40
  templated,
40
41
  user_cases,
41
42
  user_institutes,
@@ -148,7 +149,7 @@ def beacon_add_variants(institute_id, case_name):
148
149
  store, institute_id, case_name
149
150
  ) # This function checks if user has permissions to access the case
150
151
  beacon.add_variants(store, case_obj, request.form)
151
- return redirect(request.referrer)
152
+ return safe_redirect_back(request)
152
153
 
153
154
 
154
155
  @cases_bp.route("/beacon_remove_variants/<institute_id>/<case_name>", methods=["GET"])
@@ -158,7 +159,7 @@ def beacon_remove_variants(institute_id, case_name):
158
159
  store, institute_id, case_name
159
160
  ) # This function checks if user has permissions to access the case
160
161
  beacon.remove_variants(store, institute_id, case_obj)
161
- return redirect(request.referrer)
162
+ return safe_redirect_back(request)
162
163
 
163
164
 
164
165
  @cases_bp.route("/<institute_id>/<case_name>/mme_matches", methods=["GET", "POST"])
@@ -175,7 +176,7 @@ def matchmaker_match(institute_id, case_name, target):
175
176
  """Starts an internal match or a match against one or all MME external nodes"""
176
177
  institute_obj, case_obj = institute_and_case(store, institute_id, case_name)
177
178
  match_results = controllers.matchmaker_match(request, target, institute_id, case_name)
178
- return redirect(request.referrer)
179
+ return safe_redirect_back(request)
179
180
 
180
181
 
181
182
  @cases_bp.route("/<institute_id>/<case_name>/mme_add", methods=["POST"])
@@ -183,7 +184,7 @@ def matchmaker_add(institute_id, case_name):
183
184
  """Add or update a case in MatchMaker"""
184
185
  # Call matchmaker_delete controller to add a patient to MatchMaker
185
186
  controllers.matchmaker_add(request, institute_id, case_name)
186
- return redirect(request.referrer)
187
+ return safe_redirect_back(request)
187
188
 
188
189
 
189
190
  @cases_bp.route("/<institute_id>/<case_name>/mme_delete", methods=["POST"])
@@ -191,7 +192,7 @@ def matchmaker_delete(institute_id, case_name):
191
192
  """Remove a case from MatchMaker"""
192
193
  # Call matchmaker_delete controller to delete a patient from MatchMaker
193
194
  controllers.matchmaker_delete(request, institute_id, case_name)
194
- return redirect(request.referrer)
195
+ return safe_redirect_back(request)
195
196
 
196
197
 
197
198
  @cases_bp.route("/<institute_id>/<case_name>/individuals", methods=["POST"])
@@ -212,7 +213,7 @@ def update_individual(institute_id, case_name):
212
213
  age=age,
213
214
  tissue=tissue,
214
215
  )
215
- return redirect(request.referrer)
216
+ return safe_redirect_back(request)
216
217
 
217
218
 
218
219
  @cases_bp.route("/<institute_id>/<case_name>/samples", methods=["POST"])
@@ -237,7 +238,7 @@ def update_cancer_sample(institute_id, case_name):
237
238
  tumor_type=tumor_type,
238
239
  tumor_purity=tumor_purity,
239
240
  )
240
- return redirect(request.referrer)
241
+ return safe_redirect_back(request)
241
242
 
242
243
 
243
244
  @cases_bp.route("/<institute_id>/<case_name>/synopsis", methods=["POST"])
@@ -247,7 +248,7 @@ def case_synopsis(institute_id, case_name):
247
248
  user_obj = store.user(current_user.email)
248
249
  new_synopsis = request.form.get("synopsis")
249
250
  controllers.update_synopsis(store, institute_obj, case_obj, user_obj, new_synopsis)
250
- return redirect(request.referrer)
251
+ return safe_redirect_back(request)
251
252
 
252
253
 
253
254
  @cases_bp.route("/api/v1/<institute_id>/<case_name>/case_report", methods=["GET"])
@@ -344,7 +345,7 @@ def mt_report(institute_id, case_name):
344
345
  shutil.rmtree(temp_excel_dir)
345
346
 
346
347
  flash("No MT report excel file could be exported for this sample", "warning")
347
- return redirect(request.referrer)
348
+ return safe_redirect_back(request)
348
349
 
349
350
 
350
351
  @cases_bp.route("/<institute_id>/<case_name>/diagnose", methods=["POST"])
@@ -366,7 +367,7 @@ def case_diagnosis(institute_id, case_name):
366
367
  affected_inds=affected_inds,
367
368
  remove=True if request.args.get("remove") == "yes" else False,
368
369
  )
369
- return redirect("#".join([link, "disease_assign"]))
370
+ return safe_redirect_back(request, "#".join([link, "disease_assign"]))
370
371
 
371
372
 
372
373
  @cases_bp.route("/<institute_id>/<case_name>/phenotypes", methods=["POST"])
@@ -414,7 +415,7 @@ def phenotypes(institute_id, case_name, phenotype_id=None):
414
415
  )
415
416
  return redirect(case_url)
416
417
 
417
- return redirect("#".join([case_url, "phenotypes_panel"]))
418
+ return safe_redirect_back(request, "#".join([case_url, "phenotypes_panel"]))
418
419
 
419
420
 
420
421
  @cases_bp.route("/<institute_id>/<case_name>/phenotype_export", methods=["POST"])
@@ -526,7 +527,7 @@ def phenotypes_actions(institute_id, case_name):
526
527
  hgnc_ids = [result[0] for result in results if result[1] >= hpo_count]
527
528
  store.update_dynamic_gene_list(case_obj, hgnc_ids=hgnc_ids, phenotype_ids=hpo_ids)
528
529
 
529
- return redirect("#".join([case_url, "phenotypes_panel"]))
530
+ return safe_redirect_back(request, "#".join([case_url, "phenotypes_panel"]))
530
531
 
531
532
 
532
533
  @cases_bp.route("/<institute_id>/<case_name>/events", methods=["POST"])
@@ -567,7 +568,7 @@ def events(institute_id, case_name, event_id=None):
567
568
  # create a case comment
568
569
  store.comment(institute_obj, case_obj, user_obj, link, content=content)
569
570
 
570
- return redirect(request.referrer)
571
+ return safe_redirect_back(request)
571
572
 
572
573
 
573
574
  @cases_bp.route("/<institute_id>/<case_name>/status", methods=["POST"])
@@ -588,7 +589,7 @@ def status(institute_id, case_name):
588
589
  if tags or case_obj.get("tags") and tags != case_obj.get("tags"):
589
590
  store.tag_case(institute_obj, case_obj, user_obj, tags, link)
590
591
 
591
- return redirect(request.referrer)
592
+ return safe_redirect_back(request)
592
593
 
593
594
 
594
595
  @cases_bp.route("/<institute_id>/<case_name>/assign", methods=["POST"])
@@ -605,7 +606,7 @@ def assign(institute_id, case_name, user_id=None, inactivate=False):
605
606
  store.unassign(institute_obj, case_obj, user_obj, link, inactivate)
606
607
  else:
607
608
  store.assign(institute_obj, case_obj, user_obj, link)
608
- return redirect(request.referrer)
609
+ return safe_redirect_back(request)
609
610
 
610
611
 
611
612
  @cases_bp.route("/api/v1/cases", defaults={"institute_id": None})
@@ -688,7 +689,7 @@ def pin_variant(institute_id, case_name, variant_id):
688
689
  store.pin_variant(institute_obj, case_obj, user_obj, link, variant_obj)
689
690
  elif request.form["action"] == "DELETE":
690
691
  store.unpin_variant(institute_obj, case_obj, user_obj, link, variant_obj)
691
- return redirect(request.referrer or link)
692
+ return safe_redirect_back(request, request.referrer or link)
692
693
 
693
694
 
694
695
  @cases_bp.route("/<institute_id>/<case_name>/<variant_id>/validate", methods=["POST"])
@@ -705,7 +706,7 @@ def mark_validation(institute_id, case_name, variant_id):
705
706
  variant_id=variant_id,
706
707
  )
707
708
  store.validate(institute_obj, case_obj, user_obj, link, variant_obj, validate_type)
708
- return redirect(request.referrer or link)
709
+ return safe_redirect_back(request, request.referrer or link)
709
710
 
710
711
 
711
712
  @cases_bp.route(
@@ -748,8 +749,7 @@ def mark_causative(institute_id, case_name, variant_id, partial_causative=False)
748
749
  store.unmark_causative(institute_obj, case_obj, user_obj, link, variant_obj)
749
750
 
750
751
  # send the user back to the case that was marked as solved
751
- case_url = url_for(".case", institute_id=institute_id, case_name=case_name)
752
- return redirect(request.referrer)
752
+ return safe_redirect_back(request)
753
753
 
754
754
 
755
755
  @cases_bp.route("/<institute_id>/<case_name>/check-case", methods=["POST"])
@@ -761,7 +761,7 @@ def check_case(institute_id, case_name):
761
761
  store.case_collection.find_one_and_update(
762
762
  {"_id": case_obj["_id"]}, {"$set": {"needs_check": False}}
763
763
  )
764
- return redirect(request.referrer)
764
+ return safe_redirect_back(request)
765
765
 
766
766
 
767
767
  @cases_bp.route("/<institute_id>/<case_name>/report/<report_type>")
@@ -835,7 +835,7 @@ def share(institute_id, case_name):
835
835
  except ValueError as ex:
836
836
  flash(str(ex), "warning")
837
837
 
838
- return redirect(request.referrer)
838
+ return safe_redirect_back(request)
839
839
 
840
840
 
841
841
  @cases_bp.route("/<institute_id>/<case_name>/update_rerun_status")
@@ -846,7 +846,7 @@ def update_rerun_status(institute_id, case_name):
846
846
  link = url_for("cases.case", institute_id=institute_id, case_name=case_name)
847
847
 
848
848
  store.update_rerun_status(institute_obj, case_obj, user_obj, link)
849
- return redirect(link)
849
+ return safe_redirect_back(request, link)
850
850
 
851
851
 
852
852
  @cases_bp.route("/<institute_id>/<case_name>/monitor", methods=["POST"])
@@ -860,7 +860,7 @@ def rerun_monitor(institute_id, case_name):
860
860
  else:
861
861
  store.unmonitor(institute_obj, case_obj, user_obj, link)
862
862
 
863
- return redirect(request.referrer)
863
+ return safe_redirect_back(request)
864
864
 
865
865
 
866
866
  @cases_bp.route("/<institute_id>/<case_name>/reanalysis", methods=["POST"])
@@ -876,7 +876,7 @@ def reanalysis(institute_id, case_name):
876
876
  LOG.error(msg)
877
877
  flash(msg, "danger")
878
878
 
879
- return redirect(request.referrer)
879
+ return safe_redirect_back(request)
880
880
 
881
881
 
882
882
  @cases_bp.route("/<institute_id>/<case_name>/research", methods=["POST"])
@@ -886,7 +886,7 @@ def research(institute_id, case_name):
886
886
  user_obj = store.user(current_user.email)
887
887
  link = url_for(".case", institute_id=institute_id, case_name=case_name)
888
888
  store.open_research(institute_obj, case_obj, user_obj, link)
889
- return redirect(request.referrer)
889
+ return safe_redirect_back(request)
890
890
 
891
891
 
892
892
  @cases_bp.route("/<institute_id>/<case_name>/reset_research", methods=["GET"])
@@ -895,7 +895,7 @@ def reset_research(institute_id, case_name):
895
895
  user_obj = store.user(current_user.email)
896
896
  link = url_for(".case", institute_id=institute_id, case_name=case_name)
897
897
  store.reset_research(institute_obj, case_obj, user_obj, link)
898
- return redirect(request.referrer)
898
+ return safe_redirect_back(request)
899
899
 
900
900
 
901
901
  @cases_bp.route("/<institute_id>/<case_name>/cohorts", methods=["POST"])
@@ -909,7 +909,7 @@ def cohorts(institute_id, case_name):
909
909
  store.remove_cohort(institute_obj, case_obj, user_obj, link, cohort_tag)
910
910
  else:
911
911
  store.add_cohort(institute_obj, case_obj, user_obj, link, cohort_tag)
912
- return redirect("#".join([request.referrer, "cohorts"]))
912
+ return safe_redirect_back(request, "#".join([request.referrer, "cohorts"]))
913
913
 
914
914
 
915
915
  @cases_bp.route("/<institute_id>/<case_name>/default-panels", methods=["POST"])
@@ -917,7 +917,7 @@ def default_panels(institute_id, case_name):
917
917
  """Update default panels for a case."""
918
918
  panel_ids = request.form.getlist("panel_ids")
919
919
  controllers.update_default_panels(store, current_user, institute_id, case_name, panel_ids)
920
- return redirect(request.referrer)
920
+ return safe_redirect_back(request)
921
921
 
922
922
 
923
923
  @cases_bp.route("/<institute_id>/<case_name>/update-clinical-filter-hpo", methods=["POST"])
@@ -928,7 +928,7 @@ def update_clinical_filter_hpo(institute_id, case_name):
928
928
  controllers.update_clinical_filter_hpo(
929
929
  store, current_user, institute_obj, case_obj, hpo_clinical_filter
930
930
  )
931
- return redirect(request.referrer)
931
+ return safe_redirect_back(request)
932
932
 
933
933
 
934
934
  @cases_bp.route("/<institute_id>/<case_name>/add_case_group", methods=["GET", "POST"])
@@ -943,8 +943,7 @@ def add_case_group(institute_id, case_name):
943
943
  case_name = request.form.get("other_case_name")
944
944
 
945
945
  controllers.add_case_group(store, current_user, institute_id, case_name, group_id)
946
-
947
- return redirect(request.referrer + "#case_groups")
946
+ return safe_redirect_back(request, request.referrer + "#case_groups")
948
947
 
949
948
 
950
949
  @cases_bp.route("/<institute_id>/<case_name>/<case_group>/remove_case_group", methods=["GET"])
@@ -952,7 +951,7 @@ def remove_case_group(institute_id, case_name, case_group):
952
951
  """Unbind a case group from a case. Remove the group if it is no longer in use."""
953
952
  controllers.remove_case_group(store, current_user, institute_id, case_name, case_group)
954
953
 
955
- return redirect(request.referrer + "#case_groups")
954
+ return safe_redirect_back(request, request.referrer + "#case_groups")
956
955
 
957
956
 
958
957
  @cases_bp.route("/<case_group>/case_group_update_label", methods=["POST"])
@@ -962,7 +961,7 @@ def case_group_update_label(case_group):
962
961
 
963
962
  controllers.case_group_update_label(store, case_group, label)
964
963
 
965
- return redirect(request.referrer + "#case_groups")
964
+ return safe_redirect_back(request, request.referrer + "#case_groups")
966
965
 
967
966
 
968
967
  @cases_bp.route("/<institute_id>/<case_name>/download-hpo-genes/<category>", methods=["GET"])
@@ -19,6 +19,7 @@ from scout.constants.variant_tags import MANUAL_RANK_OPTIONS
19
19
  from scout.models.clinvar import clinvar_variant
20
20
  from scout.server.blueprints.variant.utils import add_gene_info
21
21
  from scout.server.extensions import clinvar_api, store
22
+ from scout.server.utils import get_case_genome_build
22
23
  from scout.utils.hgvs import validate_hgvs
23
24
  from scout.utils.scout_requests import fetch_refseq_version
24
25
 
@@ -30,7 +31,7 @@ LOG = logging.getLogger(__name__)
30
31
  def _get_var_tx_hgvs(case_obj: dict, variant_obj: dict) -> List[Tuple[str, str]]:
31
32
  """Retrieve all transcripts / HGVS for a given variant."""
32
33
 
33
- build = str(case_obj.get("genome_build", "37"))
34
+ build = get_case_genome_build(case_obj)
34
35
  tx_hgvs_list = [("", "Do not specify")]
35
36
  case_has_build_37 = "37" in case_obj.get("genome_build", "37")
36
37
 
@@ -40,33 +41,27 @@ def _get_var_tx_hgvs(case_obj: dict, variant_obj: dict) -> List[Tuple[str, str]]
40
41
  transcripts = gene.get("transcripts", [])
41
42
 
42
43
  for tx in transcripts:
43
-
44
44
  refseq_id = tx.get("refseq_id")
45
45
  coding_seq_name = tx.get("coding_sequence_name")
46
46
  if not (refseq_id and coding_seq_name):
47
47
  continue # Skip transcripts missing required fields
48
48
 
49
- mane_select = tx.get("mane_select_transcript")
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
58
-
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
- )
65
-
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 ''}"
67
-
49
+ if case_has_build_37:
50
+ for refseq in tx.get("refseq_identifiers", []):
51
+ refseq_version = fetch_refseq_version(refseq)
52
+ hgvs_simple = f"{refseq_version}:{coding_seq_name}"
53
+ validated = validate_hgvs(build, hgvs_simple)
54
+ label = f"{hgvs_simple}{'_validated_' if validated else ''}"
55
+ tx_hgvs_list.append((hgvs_simple, label))
56
+
57
+ else: # build 38, collect only MANE Select or MANE Plus Clinical
58
+ mane_select = tx.get("mane_select_transcript")
59
+ mane_plus_clinical = tx.get("mane_plus_clinical_transcript")
60
+ if mane_select is None and mane_plus_clinical is None:
61
+ continue
62
+ hgvs_simple = f"{mane_select or mane_plus_clinical}:{coding_seq_name}"
63
+ label = f"{hgvs_simple}{'_mane-select_' if mane_select else ''}{'_mane-plus-clinical_' if mane_plus_clinical else ''}"
68
64
  tx_hgvs_list.append((hgvs_simple, label))
69
-
70
65
  return tx_hgvs_list
71
66
 
72
67
 
@@ -405,7 +400,7 @@ def json_api_submission(submission_id):
405
400
 
406
401
  # Retrieve genome build for the case submitted
407
402
  case_obj = store.case(case_id=variant_data[0].get("case_id")) or {"genome_build": 37}
408
- extra_params["assembly"] = "GRCh37" if "37" in str(case_obj.get("genome_build")) else "GRCh38"
403
+ extra_params["assembly"] = "GRCh37" if "37" in get_case_genome_build(case_obj) else "GRCh38"
409
404
 
410
405
  def _write_file(afile, header, lines): # Write temp CSV file
411
406
  writes = csv.writer(afile, delimiter=",", quoting=csv.QUOTE_ALL)
@@ -154,8 +154,6 @@
154
154
  {% endfor %}
155
155
  </table>
156
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
-
159
157
  <br><br>
160
158
  <!-- dbSNP identifier -->
161
159
  {{variant_data.var_form.variations_ids.label(class="fw-bold, text-dark")}}
@@ -1,16 +1,13 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  from scout.adapter import MongoAdapter
4
+ from scout.constants import HPO_LINK_URL
4
5
  from scout.server.links import disease_link
5
6
 
6
7
 
7
- def disease_entry(store, disease_id) -> dict:
8
+ def disease_entry(store: MongoAdapter, disease_id: str) -> dict:
8
9
  """Retrieve specific info for a disease term
9
10
 
10
- Args:
11
- store(obj): an adapter to the scout database
12
- disease_id(str): a disease_id
13
-
14
11
  Returns:
15
12
  disease_obj(obj): a disease term containing description and genes
16
13
  """
@@ -21,6 +18,7 @@ def disease_entry(store, disease_id) -> dict:
21
18
  store.hpo_term(hpo_id) for hpo_id in disease_obj.get("hpo_terms", [])
22
19
  ]
23
20
  disease_obj["disease_link"] = disease_link(disease_id=disease_obj["disease_id"])
21
+ disease_obj["hpo_link_url"] = HPO_LINK_URL
24
22
  return disease_obj
25
23
 
26
24
 
@@ -43,6 +41,4 @@ def disease_terms(store: MongoAdapter, query: str, source: str) -> dict:
43
41
  )
44
42
  disease.update({"genes": gene_ids_symbols})
45
43
 
46
- data = {"terms": list(disease_data)}
47
-
48
- return data
44
+ return {"terms": list(disease_data)}
@@ -95,7 +95,7 @@
95
95
  </td>
96
96
  <td id="hpo-container">
97
97
  <span class="text-body">
98
- <a id="hpo-link" class="badge bg-secondary text-white m-1" href="https://hpo.jax.org/app/browse/term/{{term}}" target="_blank" rel="noopener" ></a>
98
+ <a id="hpo-link" class="badge bg-secondary text-white m-1" href="{{hpo_link_url}}{{term}}" target="_blank" rel="noopener" ></a>
99
99
  </span>
100
100
  </td>
101
101
  </tr>
@@ -47,7 +47,7 @@
47
47
  <ul class="list-group list-group-flush">
48
48
  {% for pheno in hpo_complete %}
49
49
  <li class="list-group-item">
50
- <a href="http://hpo.jax.org/app/browse/term/{{pheno.hpo_id}}" target="_blank">{{ pheno.hpo_id }}</a>
50
+ <a href="{{hpo_link_url}}{{pheno.hpo_id}}" target="_blank">{{ pheno.hpo_id }}</a>
51
51
  {{pheno.description}}
52
52
  </li>
53
53
  {% else %}
@@ -2,6 +2,7 @@ from typing import Union
2
2
 
3
3
  from flask import Blueprint, jsonify, request
4
4
 
5
+ from scout.constants import HPO_LINK_URL
5
6
  from scout.server.extensions import store
6
7
  from scout.server.utils import public_endpoint, templated
7
8
 
@@ -30,8 +31,7 @@ def diagnosis(disease_id):
30
31
  def count_diagnoses():
31
32
  """Display the diagnosis counts for each coding system available in database"""
32
33
 
33
- data = {"counts": store.disease_terminology_count()}
34
- return data
34
+ return {"counts": store.disease_terminology_count(), "hpo_link_url": HPO_LINK_URL}
35
35
 
36
36
 
37
37
  @omim_bp.route("/api/v1/diagnoses")