scout-browser 4.95.0__py3-none-any.whl → 4.97.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.
- scout/adapter/mongo/case.py +75 -70
- scout/adapter/mongo/filter.py +28 -11
- scout/adapter/mongo/institute.py +2 -0
- scout/adapter/mongo/omics_variant.py +20 -5
- scout/adapter/mongo/query.py +104 -95
- scout/adapter/mongo/variant.py +0 -5
- scout/adapter/mongo/variant_loader.py +10 -12
- scout/build/case.py +3 -1
- scout/build/individual.py +3 -11
- scout/commands/delete/delete_command.py +87 -49
- scout/commands/load/research.py +4 -4
- scout/commands/load/variants.py +25 -8
- scout/commands/setup/setup_scout.py +1 -1
- scout/commands/update/case.py +12 -0
- scout/commands/update/individual.py +1 -2
- scout/constants/__init__.py +7 -2
- scout/constants/acmg.py +25 -18
- scout/constants/file_types.py +68 -119
- scout/constants/filters.py +2 -1
- scout/constants/gene_tags.py +3 -3
- scout/constants/igv_tracks.py +7 -11
- scout/constants/query_terms.py +2 -2
- scout/demo/643594.config.yaml +6 -0
- scout/demo/643594.peddy.ped +1 -1
- scout/demo/643594.somalier.ancestry.tsv +4 -0
- scout/demo/643594.somalier.pairs.tsv +4 -0
- scout/demo/643594.somalier.samples.tsv +4 -0
- scout/demo/cancer.load_config.yaml +2 -3
- scout/demo/resources/__init__.py +1 -1
- scout/demo/resources/gnomad.v4.1.constraint_metrics_reduced.tsv +3755 -0
- scout/demo/rnafusion.load_config.yaml +1 -0
- scout/exceptions/database.py +1 -1
- scout/load/all.py +8 -16
- scout/models/case/case.py +1 -0
- scout/models/case/case_loading_models.py +15 -5
- scout/models/managed_variant.py +3 -3
- scout/models/omics_variant.py +3 -3
- scout/parse/case.py +113 -5
- scout/parse/pedqc.py +127 -0
- scout/parse/variant/frequency.py +9 -6
- scout/parse/variant/variant.py +71 -39
- scout/server/app.py +14 -0
- scout/server/blueprints/alignviewers/controllers.py +2 -0
- scout/server/blueprints/alignviewers/templates/alignviewers/igv_viewer.html +3 -0
- scout/server/blueprints/alignviewers/templates/alignviewers/utils.html +1 -1
- scout/server/blueprints/cases/controllers.py +25 -3
- scout/server/blueprints/cases/templates/cases/case.html +3 -0
- scout/server/blueprints/cases/templates/cases/case_report.html +28 -2
- scout/server/blueprints/cases/templates/cases/chanjo2_form.html +2 -2
- scout/server/blueprints/cases/templates/cases/collapsible_actionbar.html +12 -0
- scout/server/blueprints/cases/templates/cases/gene_panel.html +9 -3
- scout/server/blueprints/cases/templates/cases/individuals_table.html +4 -1
- scout/server/blueprints/cases/templates/cases/utils.html +23 -19
- scout/server/blueprints/cases/views.py +5 -9
- scout/server/blueprints/clinvar/controllers.py +12 -11
- scout/server/blueprints/clinvar/templates/clinvar/clinvar_submissions.html +10 -14
- scout/server/blueprints/clinvar/templates/clinvar/multistep_add_variant.html +15 -7
- scout/server/blueprints/clinvar/views.py +18 -31
- scout/server/blueprints/institutes/controllers.py +20 -1
- scout/server/blueprints/institutes/forms.py +5 -1
- scout/server/blueprints/institutes/templates/overview/institute_settings.html +7 -0
- scout/server/blueprints/institutes/templates/overview/utils.html +20 -1
- scout/server/blueprints/omics_variants/templates/omics_variants/outliers.html +9 -2
- scout/server/blueprints/omics_variants/views.py +8 -10
- scout/server/blueprints/variant/controllers.py +30 -1
- scout/server/blueprints/variant/templates/variant/cancer-variant.html +21 -5
- scout/server/blueprints/variant/templates/variant/components.html +26 -9
- scout/server/blueprints/variant/templates/variant/variant.html +4 -2
- scout/server/blueprints/variant/templates/variant/variant_details.html +1 -1
- scout/server/blueprints/variant/utils.py +2 -0
- scout/server/blueprints/variant/views.py +10 -3
- scout/server/blueprints/variants/controllers.py +29 -3
- scout/server/blueprints/variants/forms.py +37 -10
- scout/server/blueprints/variants/templates/variants/cancer-variants.html +5 -4
- scout/server/blueprints/variants/templates/variants/components.html +12 -10
- scout/server/blueprints/variants/templates/variants/str-variants.html +13 -9
- scout/server/blueprints/variants/templates/variants/utils.html +59 -36
- scout/server/blueprints/variants/views.py +45 -60
- scout/server/extensions/beacon_extension.py +1 -1
- scout/server/extensions/bionano_extension.py +5 -5
- scout/server/extensions/chanjo2_extension.py +40 -1
- scout/server/extensions/chanjo_extension.py +1 -1
- scout/server/extensions/clinvar_extension.py +56 -2
- scout/server/extensions/matchmaker_extension.py +1 -1
- scout/server/links.py +0 -14
- scout/server/static/bs_styles.css +2 -0
- scout/server/templates/layout.html +1 -0
- scout/server/utils.py +5 -0
- scout/utils/acmg.py +5 -5
- scout/utils/ensembl_biomart_clients.py +2 -11
- scout/utils/scout_requests.py +1 -1
- {scout_browser-4.95.0.dist-info → scout_browser-4.97.0.dist-info}/METADATA +1 -1
- {scout_browser-4.95.0.dist-info → scout_browser-4.97.0.dist-info}/RECORD +96 -94
- scout/demo/resources/gnomad.v4.0.constraint_metrics_reduced.tsv +0 -3755
- scout/parse/peddy.py +0 -149
- scout/utils/sort.py +0 -21
- {scout_browser-4.95.0.dist-info → scout_browser-4.97.0.dist-info}/WHEEL +0 -0
- {scout_browser-4.95.0.dist-info → scout_browser-4.97.0.dist-info}/entry_points.txt +0 -0
- {scout_browser-4.95.0.dist-info → scout_browser-4.97.0.dist-info}/licenses/LICENSE +0 -0
scout/adapter/mongo/query.py
CHANGED
@@ -12,7 +12,12 @@ from scout.constants import (
|
|
12
12
|
TRUSTED_REVSTAT_LEVEL,
|
13
13
|
)
|
14
14
|
|
15
|
+
CLNSIG_NOT_EXISTS = {"clnsig": {"$exists": False}}
|
16
|
+
CLNSIG_NULL = {"clnsig": {"$eq": None}}
|
15
17
|
CRITERION_EXCLUDE_OPERATOR = {False: "$in", True: "$nin"}
|
18
|
+
EXISTS = {"$exists": True}
|
19
|
+
NOT_EXISTS = {"$exists": False}
|
20
|
+
EXISTS_NOT_NULL = {"$exists": True, "$ne": None}
|
16
21
|
|
17
22
|
LOG = logging.getLogger(__name__)
|
18
23
|
|
@@ -43,18 +48,16 @@ class QueryHandler(object):
|
|
43
48
|
return case_query
|
44
49
|
|
45
50
|
def delete_variants_query(
|
46
|
-
self,
|
51
|
+
self,
|
52
|
+
case_id: str,
|
53
|
+
variants_to_keep: List[str] = [],
|
54
|
+
min_rank_threshold: Optional[int] = None,
|
55
|
+
keep_ctg: List[str] = [],
|
47
56
|
) -> dict:
|
48
|
-
"""Build a query to delete variants from a case
|
49
|
-
|
50
|
-
Args:
|
51
|
-
case_id(str): id of a case
|
52
|
-
variants_to_keep(list): a list of variant ids
|
53
|
-
min_rank_threshold(int): remove variants with rank lower than this number
|
54
|
-
keep_ctg(list): exclude one of more variants categories from deletion. Example ["cancer", "cancer_sv"]
|
57
|
+
"""Build a query to delete variants from a case (variant collection).
|
55
58
|
|
56
|
-
|
57
|
-
|
59
|
+
Removes variants with rank lower than `min_rank_threshold`.
|
60
|
+
Retains variants in categories `keep_ctg` by excluding them from deletion - eg `["cancer", "cancer_sv"]`.
|
58
61
|
"""
|
59
62
|
variants_query = {}
|
60
63
|
case_subquery = {"case_id": case_id}
|
@@ -202,14 +205,15 @@ class QueryHandler(object):
|
|
202
205
|
'region_annotations': list,
|
203
206
|
'functional_annotations': list,
|
204
207
|
'clinsig': list,
|
205
|
-
'
|
208
|
+
'clinvar_trusted_revstat': boolean,
|
209
|
+
'clinsig_exclude': bool,
|
206
210
|
'variant_type': str(('research', 'clinical')),
|
207
211
|
'chrom': str or list of str,
|
208
212
|
'start': int,
|
209
213
|
'end': int,
|
210
214
|
'svtype': list,
|
211
215
|
'size': int,
|
212
|
-
'
|
216
|
+
'size_selector': str,
|
213
217
|
'gene_panels': list(str),
|
214
218
|
'mvl_tag": boolean,
|
215
219
|
'clinvar_tag': boolean,
|
@@ -305,6 +309,9 @@ class QueryHandler(object):
|
|
305
309
|
if criterion == "show_unaffected" and query.get(criterion) is False:
|
306
310
|
self.affected_inds_query(mongo_query, case_id, gt_query)
|
307
311
|
|
312
|
+
if criterion == "show_soft_filtered" and query.get(criterion) is False:
|
313
|
+
self.soft_filters_query(query=query, mongo_query=mongo_query)
|
314
|
+
|
308
315
|
##### end of fundamental query params
|
309
316
|
|
310
317
|
##### start of the custom query params
|
@@ -319,18 +326,21 @@ class QueryHandler(object):
|
|
319
326
|
for term in PRIMARY_CRITERIA:
|
320
327
|
if query.get(term):
|
321
328
|
primary_terms = True
|
329
|
+
break
|
322
330
|
|
323
331
|
# check if any of the secondary criteria was specified in the query:
|
324
332
|
for term in SECONDARY_CRITERIA:
|
325
333
|
if query.get(term):
|
326
334
|
secondary_terms = True
|
335
|
+
break
|
327
336
|
|
328
337
|
if primary_terms is True:
|
329
|
-
clinsign_filter = self.
|
338
|
+
clinsign_filter: dict = self.set_and_get_clinsig_query(query, mongo_query)
|
330
339
|
|
331
340
|
# Secondary, excluding filter criteria will hide variants in general,
|
332
341
|
# but can be overridden by an including, major filter criteria
|
333
342
|
# such as a Pathogenic ClinSig.
|
343
|
+
|
334
344
|
if secondary_terms is True:
|
335
345
|
secondary_filter = self.secondary_query(query, mongo_query)
|
336
346
|
# If there are no primary criteria given, all secondary criteria are added as a
|
@@ -338,26 +348,35 @@ class QueryHandler(object):
|
|
338
348
|
if secondary_filter and primary_terms is False:
|
339
349
|
mongo_query["$and"] = secondary_filter
|
340
350
|
|
341
|
-
#
|
342
|
-
#
|
343
|
-
|
344
|
-
|
345
|
-
if primary_terms is True: # clinsig is specified
|
346
|
-
# Given a request to always return confident clinical variants,
|
347
|
-
# add the clnsig query as a major criteria, but only
|
348
|
-
# trust clnsig entries with trusted revstat levels.
|
349
|
-
if query.get("clinsig_confident_always_returned") is True:
|
351
|
+
# if prioritise_clinvar checkbox is checked, then clinical_filter will be applied in alternative to the secondary_filter ("$or")
|
352
|
+
# This will happen when the search for ClinVar annotated variants is supposed to be more relaxed compared to other filter constraints, for instance when applying the clinical filter
|
353
|
+
if primary_terms is True:
|
354
|
+
if query.get("prioritise_clinvar") is True:
|
350
355
|
mongo_query["$or"] = [
|
351
356
|
{"$and": secondary_filter},
|
352
357
|
clinsign_filter,
|
353
358
|
]
|
354
|
-
else: #
|
359
|
+
else: # clinical_filter will be applied at the same level as the other secondary filters ("$and")
|
360
|
+
if query.get("clinsig_exclude"):
|
361
|
+
clinsign_filter = {
|
362
|
+
"$or": [
|
363
|
+
clinsign_filter,
|
364
|
+
CLNSIG_NOT_EXISTS,
|
365
|
+
CLNSIG_NULL,
|
366
|
+
]
|
367
|
+
}
|
355
368
|
secondary_filter.append(clinsign_filter)
|
356
369
|
mongo_query["$and"] = secondary_filter
|
357
370
|
|
358
371
|
elif primary_terms is True: # clisig is provided without secondary terms query
|
359
|
-
|
360
|
-
|
372
|
+
if query.get("clinsig_exclude"):
|
373
|
+
mongo_query["$or"] = [
|
374
|
+
clinsign_filter,
|
375
|
+
CLNSIG_NOT_EXISTS,
|
376
|
+
CLNSIG_NULL,
|
377
|
+
]
|
378
|
+
else:
|
379
|
+
mongo_query["clnsig"] = clinsign_filter["clnsig"]
|
361
380
|
|
362
381
|
# if chromosome coordinates exist in query, add them as first element of the mongo_query['$and']
|
363
382
|
if coordinate_query:
|
@@ -368,6 +387,11 @@ class QueryHandler(object):
|
|
368
387
|
|
369
388
|
return mongo_query
|
370
389
|
|
390
|
+
def soft_filters_query(self, query: dict, mongo_query: dict):
|
391
|
+
"""Adds info to variants query to exclude variants flagged by specific filters."""
|
392
|
+
if query.get("institute_soft_filters"):
|
393
|
+
mongo_query["filters"] = {"$nin": query["institute_soft_filters"].split(",")}
|
394
|
+
|
371
395
|
def affected_inds_query(self, mongo_query, case_id, gt_query):
|
372
396
|
"""Add info to variants query to filter out variants which are only in unaffected individuals
|
373
397
|
|
@@ -393,7 +417,10 @@ class QueryHandler(object):
|
|
393
417
|
for ind in case_inds:
|
394
418
|
if ind["phenotype"] in [1, "unaffected"]: # 1=unaffected, 2=affected
|
395
419
|
continue
|
396
|
-
affected_match = {
|
420
|
+
affected_match = {
|
421
|
+
"sample_id": ind["individual_id"],
|
422
|
+
"genotype_call": gt_query,
|
423
|
+
}
|
397
424
|
affected_query["$elemMatch"]["$or"].append(affected_match)
|
398
425
|
|
399
426
|
if affected_query["$elemMatch"][
|
@@ -401,65 +428,52 @@ class QueryHandler(object):
|
|
401
428
|
]: # Consider situation where all individuals are unaffected
|
402
429
|
mongo_query["samples"] = affected_query
|
403
430
|
|
404
|
-
def
|
405
|
-
"""Add clinsig filter values to the mongo query object
|
431
|
+
def set_and_get_clinsig_query(self, query: dict, mongo_query: dict) -> dict:
|
432
|
+
"""Add clinsig filter values to the mongo query object. if clinvar_tag esists in query then only results with ClinVar annotation are returned."""
|
406
433
|
|
407
|
-
|
408
|
-
query(dict): a dictionary of query filters specified by the users
|
409
|
-
mongo_query(dict): the query that is going to be submitted to the database
|
434
|
+
clnsig_query = {"clnsig": {}}
|
410
435
|
|
411
|
-
|
412
|
-
|
436
|
+
if query.get("clinsig"): # If any ClinVar significance was selected in the form multiselect
|
437
|
+
rank = []
|
438
|
+
str_rank = []
|
439
|
+
for item in query["clinsig"]:
|
440
|
+
rank.append(int(item))
|
441
|
+
# search for human readable clinsig values in newer cases
|
442
|
+
rank.append(CLINSIG_MAP[int(item)])
|
443
|
+
str_rank.append(CLINSIG_MAP[int(item)])
|
413
444
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
if query.get("clinsig_confident_always_returned") is True:
|
428
|
-
LOG.debug("add CLINSIG filter with trusted_revision_level")
|
429
|
-
|
430
|
-
clnsig_query = {
|
431
|
-
"clnsig": {
|
445
|
+
elem_match = [
|
446
|
+
{"value": {"$in": rank}},
|
447
|
+
{"value": re.compile("|".join(str_rank))},
|
448
|
+
]
|
449
|
+
|
450
|
+
if query.get("clinsig_exclude"):
|
451
|
+
elem_match_or = {"$nor": elem_match}
|
452
|
+
else:
|
453
|
+
elem_match_or = {"$or": elem_match}
|
454
|
+
|
455
|
+
if query.get("clinvar_trusted_revstat") is True:
|
456
|
+
clnsig_query["clnsig"] = {
|
432
457
|
"$elemMatch": {
|
433
458
|
"$and": [
|
434
|
-
|
435
|
-
|
436
|
-
{"value": {"$in": rank}},
|
437
|
-
{"value": re.compile("|".join(str_rank))},
|
438
|
-
]
|
439
|
-
},
|
440
|
-
{"revstat": re.compile("|".join(trusted_revision_level))},
|
459
|
+
elem_match_or,
|
460
|
+
{"revstat": re.compile("|".join(TRUSTED_REVSTAT_LEVEL))},
|
441
461
|
]
|
442
462
|
}
|
443
463
|
}
|
444
|
-
|
445
|
-
|
446
|
-
|
464
|
+
else:
|
465
|
+
clnsig_query["clnsig"] = {"$elemMatch": elem_match_or}
|
466
|
+
|
467
|
+
if query.get("clinvar_tag"):
|
468
|
+
mongo_query["clnsig"] = EXISTS_NOT_NULL # Used when query has secondary terms
|
469
|
+
clnsig_query["clnsig"]["$exists"] = True
|
470
|
+
clnsig_query["clnsig"]["$ne"] = None
|
447
471
|
|
448
|
-
clnsig_query = {
|
449
|
-
"clnsig": {
|
450
|
-
"$elemMatch": {
|
451
|
-
"$or": [
|
452
|
-
{"value": {"$in": rank}},
|
453
|
-
{"value": re.compile("|".join(str_rank))},
|
454
|
-
]
|
455
|
-
}
|
456
|
-
}
|
457
|
-
}
|
458
472
|
return clnsig_query
|
459
473
|
|
460
474
|
def coordinate_filter(self, query, mongo_query):
|
461
475
|
"""Adds genomic coordinated-related filters to the query object
|
462
|
-
This method is called to
|
476
|
+
This method is called to build coordinate query for non-sv variants
|
463
477
|
|
464
478
|
Args:
|
465
479
|
query(dict): a dictionary of query filters specified by the users
|
@@ -618,7 +632,7 @@ class QueryHandler(object):
|
|
618
632
|
{
|
619
633
|
"$or": [
|
620
634
|
{"gnomad_frequency": {"$lt": float(gnomad)}},
|
621
|
-
{"gnomad_frequency":
|
635
|
+
{"gnomad_frequency": NOT_EXISTS},
|
622
636
|
]
|
623
637
|
}
|
624
638
|
)
|
@@ -656,7 +670,7 @@ class QueryHandler(object):
|
|
656
670
|
{
|
657
671
|
"$or": [
|
658
672
|
{"swegen_mei_max": {"$lt": float(swegen)}},
|
659
|
-
{"swegen_mei_max":
|
673
|
+
{"swegen_mei_max": NOT_EXISTS},
|
660
674
|
]
|
661
675
|
}
|
662
676
|
)
|
@@ -665,7 +679,7 @@ class QueryHandler(object):
|
|
665
679
|
mongo_secondary_query.append(
|
666
680
|
{
|
667
681
|
"$or": [
|
668
|
-
{criterion:
|
682
|
+
{criterion: NOT_EXISTS},
|
669
683
|
{criterion: {"$lt": query[criterion] + 1}},
|
670
684
|
]
|
671
685
|
}
|
@@ -677,7 +691,7 @@ class QueryHandler(object):
|
|
677
691
|
|
678
692
|
spidex_query_or_part = []
|
679
693
|
if "not_reported" in spidex_human:
|
680
|
-
spidex_query_or_part.append({"spidex":
|
694
|
+
spidex_query_or_part.append({"spidex": NOT_EXISTS})
|
681
695
|
|
682
696
|
for spidex_level in SPIDEX_HUMAN:
|
683
697
|
if spidex_level in spidex_human:
|
@@ -721,7 +735,7 @@ class QueryHandler(object):
|
|
721
735
|
if criterion == "revel":
|
722
736
|
revel = query["revel"]
|
723
737
|
revel_query = {"revel": {"$gt": float(revel)}}
|
724
|
-
revel_query = {"$or": [revel_query, {"revel":
|
738
|
+
revel_query = {"$or": [revel_query, {"revel": NOT_EXISTS}]}
|
725
739
|
|
726
740
|
mongo_secondary_query.append(revel_query)
|
727
741
|
|
@@ -729,7 +743,7 @@ class QueryHandler(object):
|
|
729
743
|
rank_score_query = {
|
730
744
|
"$or": [
|
731
745
|
{"rank_score": {"$gte": float(query["rank_score"])}},
|
732
|
-
{"rank_score":
|
746
|
+
{"rank_score": NOT_EXISTS},
|
733
747
|
]
|
734
748
|
}
|
735
749
|
mongo_secondary_query.append(rank_score_query)
|
@@ -739,7 +753,7 @@ class QueryHandler(object):
|
|
739
753
|
cadd_query = {"cadd_score": {"$gt": float(cadd)}}
|
740
754
|
|
741
755
|
if query.get("cadd_inclusive") is True:
|
742
|
-
cadd_query = {"$or": [cadd_query, {"cadd_score":
|
756
|
+
cadd_query = {"$or": [cadd_query, {"cadd_score": NOT_EXISTS}]}
|
743
757
|
|
744
758
|
mongo_secondary_query.append(cadd_query)
|
745
759
|
|
@@ -763,15 +777,14 @@ class QueryHandler(object):
|
|
763
777
|
|
764
778
|
if criterion == "size":
|
765
779
|
size = query["size"]
|
766
|
-
|
780
|
+
size_selector = query.get("size_selector")
|
767
781
|
|
768
|
-
|
769
|
-
|
770
|
-
"$
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
}
|
782
|
+
size_query = {
|
783
|
+
"$or": [
|
784
|
+
{"$expr": {size_selector: [{"$abs": "$length"}, size]}},
|
785
|
+
{"length": NOT_EXISTS}, # Include documents where 'length' is missing
|
786
|
+
]
|
787
|
+
}
|
775
788
|
|
776
789
|
mongo_secondary_query.append(size_query)
|
777
790
|
|
@@ -780,7 +793,7 @@ class QueryHandler(object):
|
|
780
793
|
mongo_secondary_query.append({"sub_category": {"$in": svtype}})
|
781
794
|
|
782
795
|
if criterion == "decipher":
|
783
|
-
mongo_query["decipher"] =
|
796
|
+
mongo_query["decipher"] = EXISTS
|
784
797
|
|
785
798
|
if criterion == "depth":
|
786
799
|
mongo_secondary_query.append({"tumor.read_depth": {"$gt": query.get("depth")}})
|
@@ -793,7 +806,7 @@ class QueryHandler(object):
|
|
793
806
|
{
|
794
807
|
"$or": [
|
795
808
|
{"somatic_score": {"$gt": query.get("somatic_score")}},
|
796
|
-
{"somatic_score":
|
809
|
+
{"somatic_score": NOT_EXISTS},
|
797
810
|
]
|
798
811
|
}
|
799
812
|
)
|
@@ -809,14 +822,10 @@ class QueryHandler(object):
|
|
809
822
|
)
|
810
823
|
|
811
824
|
if criterion == "mvl_tag":
|
812
|
-
mongo_secondary_query.append({"mvl_tag":
|
813
|
-
|
814
|
-
if criterion == "clinvar_tag":
|
815
|
-
mongo_secondary_query.append({"clnsig": {"$exists": True}})
|
816
|
-
mongo_secondary_query.append({"clnsig": {"$ne": None}})
|
825
|
+
mongo_secondary_query.append({"mvl_tag": EXISTS})
|
817
826
|
|
818
827
|
if criterion == "cosmic_tag":
|
819
|
-
mongo_secondary_query.append({"cosmic_ids":
|
828
|
+
mongo_secondary_query.append({"cosmic_ids": EXISTS})
|
820
829
|
mongo_secondary_query.append({"cosmic_ids": {"$ne": None}})
|
821
830
|
|
822
831
|
if criterion == "fusion_score":
|
scout/adapter/mongo/variant.py
CHANGED
@@ -877,11 +877,6 @@ class VariantHandler(VariantLoader):
|
|
877
877
|
}
|
878
878
|
}
|
879
879
|
"""
|
880
|
-
LOG.info(
|
881
|
-
"Retrieving variants by category for case: {0}, institute: {1}".format(
|
882
|
-
case_id, institute_id
|
883
|
-
)
|
884
|
-
)
|
885
880
|
|
886
881
|
case_obj = self.case(case_id=case_id)
|
887
882
|
variants_stats = case_obj.get("variants_stats") or {}
|
@@ -12,7 +12,7 @@ from intervaltree import IntervalTree
|
|
12
12
|
from pymongo.errors import BulkWriteError, DuplicateKeyError
|
13
13
|
|
14
14
|
from scout.build import build_variant
|
15
|
-
from scout.constants import CHROMOSOMES,
|
15
|
+
from scout.constants import CHROMOSOMES, ORDERED_FILE_TYPE_MAP
|
16
16
|
from scout.exceptions import IntegrityError
|
17
17
|
from scout.parse.variant import parse_variant
|
18
18
|
from scout.parse.variant.clnsig import is_pathogenic
|
@@ -27,7 +27,6 @@ from scout.parse.variant.headers import (
|
|
27
27
|
from scout.parse.variant.ids import parse_simple_id
|
28
28
|
from scout.parse.variant.managed_variant import parse_managed_variant_id
|
29
29
|
from scout.parse.variant.rank_score import parse_rank_score
|
30
|
-
from scout.utils.sort import get_load_priority
|
31
30
|
|
32
31
|
LOG = logging.getLogger(__name__)
|
33
32
|
|
@@ -205,8 +204,11 @@ class VariantLoader(object):
|
|
205
204
|
# Cancer SVs, in particular, and keep a consistent variant_id collision resolution order.
|
206
205
|
# Possible variant types are 'clinical', 'research'.
|
207
206
|
load_variants = {
|
208
|
-
(
|
209
|
-
|
207
|
+
(
|
208
|
+
ORDERED_FILE_TYPE_MAP[file_type]["variant_type"],
|
209
|
+
ORDERED_FILE_TYPE_MAP[file_type]["category"],
|
210
|
+
)
|
211
|
+
for file_type in ORDERED_FILE_TYPE_MAP
|
210
212
|
if case_obj.get("vcf_files", {}).get(file_type)
|
211
213
|
}
|
212
214
|
|
@@ -214,16 +216,12 @@ class VariantLoader(object):
|
|
214
216
|
# Loop over all intervals
|
215
217
|
for chrom in CHROMOSOMES:
|
216
218
|
intervals = coding_intervals.get(chrom, IntervalTree())
|
217
|
-
for var_type, category in
|
218
|
-
list(load_variants),
|
219
|
-
key=lambda tup: get_load_priority(variant_type=tup[0], category=tup[1]),
|
220
|
-
):
|
219
|
+
for var_type, category in load_variants:
|
221
220
|
LOG.info(
|
222
221
|
"Updating compounds on chromosome:{0}, type:{1}, category:{2} for case:{3}".format(
|
223
222
|
chrom, var_type, category, case_id
|
224
223
|
)
|
225
224
|
)
|
226
|
-
|
227
225
|
# Fetch all variants from a chromosome
|
228
226
|
query = {"variant_type": var_type, "chrom": chrom}
|
229
227
|
|
@@ -660,10 +658,10 @@ class VariantLoader(object):
|
|
660
658
|
nr_inserted = 0
|
661
659
|
|
662
660
|
variant_files = []
|
663
|
-
for vcf_file_key in
|
664
|
-
if
|
661
|
+
for vcf_file_key, vcf_dict in ORDERED_FILE_TYPE_MAP.items():
|
662
|
+
if vcf_dict["variant_type"] != variant_type:
|
665
663
|
continue
|
666
|
-
if
|
664
|
+
if vcf_dict["category"] != category:
|
667
665
|
continue
|
668
666
|
|
669
667
|
LOG.debug("Attempt to load %s %s VCF.", variant_type, category.upper())
|
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/build/individual.py
CHANGED
@@ -116,17 +116,9 @@ def build_individual(ind: dict) -> dict:
|
|
116
116
|
raise PedigreeError("Analysis type %s not allowed", analysis_type)
|
117
117
|
ind_obj["analysis_type"] = analysis_type
|
118
118
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
if "msi" in ind:
|
123
|
-
ind_obj["msi"] = ind["msi"]
|
124
|
-
|
125
|
-
if "tumor_purity" in ind:
|
126
|
-
ind_obj["tumor_purity"] = ind["tumor_purity"]
|
127
|
-
|
128
|
-
if "tumor_type" in ind:
|
129
|
-
ind_obj["tumor_type"] = ind["tumor_type"]
|
119
|
+
for optional_ind_key in ["hrd", "msi", "tmb", "tumor_purity", "tumor_type"]:
|
120
|
+
if optional_ind_key in ind:
|
121
|
+
ind_obj[optional_ind_key] = ind[optional_ind_key]
|
130
122
|
|
131
123
|
ind_obj["tissue_type"] = ind.get("tissue_type", "unknown")
|
132
124
|
|