scout-browser 4.82.2__py3-none-any.whl → 4.84__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/__version__.py +1 -1
- scout/adapter/client.py +1 -0
- scout/adapter/mongo/base.py +0 -1
- scout/adapter/mongo/case.py +19 -37
- scout/adapter/mongo/case_events.py +98 -2
- scout/adapter/mongo/hgnc.py +39 -22
- scout/adapter/mongo/institute.py +3 -9
- scout/adapter/mongo/panel.py +2 -1
- scout/adapter/mongo/variant.py +12 -2
- scout/adapter/mongo/variant_loader.py +156 -141
- scout/build/genes/hgnc_gene.py +5 -134
- scout/commands/base.py +1 -0
- scout/commands/download/ensembl.py +1 -0
- scout/commands/download/everything.py +1 -0
- scout/commands/download/exac.py +1 -0
- scout/commands/download/hgnc.py +1 -0
- scout/commands/download/hpo.py +1 -0
- scout/commands/download/omim.py +1 -0
- scout/commands/export/database.py +1 -0
- scout/commands/load/panel.py +1 -0
- scout/commands/load/report.py +1 -0
- scout/commands/update/case.py +10 -10
- scout/commands/update/individual.py +6 -1
- scout/commands/update/omim.py +1 -0
- scout/commands/update/panelapp.py +1 -0
- scout/constants/file_types.py +86 -13
- scout/export/exon.py +1 -0
- scout/load/__init__.py +0 -1
- scout/load/all.py +8 -5
- scout/load/hgnc_gene.py +1 -1
- scout/load/panel.py +8 -4
- scout/load/setup.py +1 -0
- scout/models/case/case_loading_models.py +6 -16
- scout/models/hgnc_map.py +50 -87
- scout/models/phenotype_term.py +3 -3
- scout/parse/case.py +0 -1
- scout/parse/disease_terms.py +1 -0
- scout/parse/omim.py +1 -0
- scout/parse/orpha.py +1 -0
- scout/parse/panel.py +40 -15
- scout/parse/variant/conservation.py +1 -0
- scout/resources/__init__.py +3 -0
- scout/server/app.py +4 -50
- scout/server/blueprints/alignviewers/controllers.py +15 -17
- scout/server/blueprints/alignviewers/templates/alignviewers/igv_viewer.html +13 -3
- scout/server/blueprints/alignviewers/views.py +10 -15
- scout/server/blueprints/cases/controllers.py +70 -73
- scout/server/blueprints/cases/templates/cases/case.html +94 -71
- scout/server/blueprints/cases/templates/cases/collapsible_actionbar.html +1 -1
- scout/server/blueprints/cases/templates/cases/phenotype.html +8 -6
- scout/server/blueprints/cases/templates/cases/utils.html +3 -3
- scout/server/blueprints/cases/views.py +8 -6
- scout/server/blueprints/panels/forms.py +1 -0
- scout/server/blueprints/variant/controllers.py +14 -19
- scout/server/blueprints/variant/templates/variant/acmg.html +25 -16
- scout/server/blueprints/variant/templates/variant/components.html +11 -6
- scout/server/blueprints/variant/views.py +5 -2
- scout/server/blueprints/variants/controllers.py +12 -28
- scout/server/blueprints/variants/views.py +1 -1
- scout/server/config.py +16 -4
- scout/server/extensions/__init__.py +4 -2
- scout/server/extensions/beacon_extension.py +1 -0
- scout/server/extensions/bionano_extension.py +1 -0
- scout/server/extensions/chanjo_extension.py +59 -0
- scout/server/extensions/gens_extension.py +1 -0
- scout/server/extensions/ldap_extension.py +5 -3
- scout/server/extensions/loqus_extension.py +16 -14
- scout/server/extensions/matchmaker_extension.py +1 -0
- scout/server/extensions/mongo_extension.py +1 -0
- scout/server/extensions/phenopacket_extension.py +1 -0
- scout/server/extensions/rerunner_extension.py +1 -0
- scout/server/links.py +4 -4
- scout/server/static/bs_styles.css +20 -2
- scout/server/utils.py +16 -2
- scout/utils/acmg.py +33 -20
- scout/utils/ensembl_rest_clients.py +1 -0
- scout/utils/scout_requests.py +1 -0
- scout/utils/sort.py +21 -0
- scout/utils/track_resources.py +70 -0
- {scout_browser-4.82.2.dist-info → scout_browser-4.84.dist-info}/METADATA +2 -5
- {scout_browser-4.82.2.dist-info → scout_browser-4.84.dist-info}/RECORD +85 -84
- {scout_browser-4.82.2.dist-info → scout_browser-4.84.dist-info}/WHEEL +1 -1
- {scout_browser-4.82.2.dist-info → scout_browser-4.84.dist-info}/entry_points.txt +0 -1
- scout/load/case.py +0 -36
- scout/utils/cloud_resources.py +0 -61
- {scout_browser-4.82.2.dist-info → scout_browser-4.84.dist-info}/LICENSE +0 -0
- {scout_browser-4.82.2.dist-info → scout_browser-4.84.dist-info}/top_level.txt +0 -0
scout/__version__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "4.
|
1
|
+
__version__ = "4.84"
|
scout/adapter/client.py
CHANGED
scout/adapter/mongo/base.py
CHANGED
scout/adapter/mongo/case.py
CHANGED
@@ -10,10 +10,11 @@ import pymongo
|
|
10
10
|
from bson import ObjectId
|
11
11
|
|
12
12
|
from scout.build.case import build_case
|
13
|
-
from scout.constants import ACMG_MAP, ID_PROJECTION
|
13
|
+
from scout.constants import ACMG_MAP, FILE_TYPE_MAP, ID_PROJECTION
|
14
14
|
from scout.exceptions import ConfigError, IntegrityError
|
15
15
|
from scout.parse.variant.ids import parse_document_id
|
16
16
|
from scout.utils.algorithms import ui_score
|
17
|
+
from scout.utils.sort import get_load_priority
|
17
18
|
|
18
19
|
LOG = logging.getLogger(__name__)
|
19
20
|
|
@@ -883,44 +884,37 @@ class CaseHandler(object):
|
|
883
884
|
self.evaluated_variants(case_obj["_id"], case_obj["owner"])
|
884
885
|
)
|
885
886
|
|
887
|
+
# load from files
|
886
888
|
files = [
|
887
|
-
{"file_name": "vcf_snv", "variant_type": "clinical", "category": "snv"},
|
888
|
-
{"file_name": "vcf_sv", "variant_type": "clinical", "category": "sv"},
|
889
889
|
{
|
890
|
-
"file_name":
|
891
|
-
"variant_type": "
|
892
|
-
"category": "
|
893
|
-
}
|
894
|
-
|
895
|
-
|
896
|
-
"variant_type": "clinical",
|
897
|
-
"category": "cancer_sv",
|
898
|
-
},
|
899
|
-
{"file_name": "vcf_str", "variant_type": "clinical", "category": "str"},
|
900
|
-
{"file_name": "vcf_mei", "variant_type": "clinical", "category": "mei"},
|
901
|
-
{
|
902
|
-
"file_name": "vcf_fusion",
|
903
|
-
"variant_type": "clinical",
|
904
|
-
"category": "fusion",
|
905
|
-
},
|
890
|
+
"file_name": file_type,
|
891
|
+
"variant_type": FILE_TYPE_MAP[file_type]["variant_type"],
|
892
|
+
"category": FILE_TYPE_MAP[file_type]["category"],
|
893
|
+
}
|
894
|
+
for file_type in FILE_TYPE_MAP.keys()
|
895
|
+
if FILE_TYPE_MAP[file_type]["variant_type"] != "research"
|
906
896
|
]
|
907
897
|
|
898
|
+
# (type, category) tuples are not unique - eg SNV, SNV_MT
|
899
|
+
load_variants = set()
|
908
900
|
try:
|
909
901
|
for vcf_file in files:
|
910
|
-
# Check if file
|
902
|
+
# Check if any file of this kind is configured for case
|
911
903
|
if not case_obj["vcf_files"].get(vcf_file["file_name"]):
|
912
904
|
LOG.debug("didn't find {}, skipping".format(vcf_file["file_name"]))
|
913
905
|
continue
|
906
|
+
load_variants.add((vcf_file["variant_type"], vcf_file["category"]))
|
914
907
|
|
915
|
-
|
916
|
-
|
908
|
+
for variant_type, category in sorted(
|
909
|
+
load_variants,
|
910
|
+
key=lambda tup: get_load_priority(variant_type=tup[0], category=tup[1]),
|
911
|
+
):
|
917
912
|
if update:
|
918
913
|
self.delete_variants(
|
919
914
|
case_id=case_obj["_id"],
|
920
915
|
variant_type=variant_type,
|
921
916
|
category=category,
|
922
917
|
)
|
923
|
-
|
924
918
|
# add variants
|
925
919
|
self.load_variants(
|
926
920
|
case_obj=case_obj,
|
@@ -948,7 +942,7 @@ class CaseHandler(object):
|
|
948
942
|
force_update_case=True,
|
949
943
|
)
|
950
944
|
|
951
|
-
self.
|
945
|
+
self.update_case_cli(case_obj, institute_obj)
|
952
946
|
# update Sanger status for the new inserted variants
|
953
947
|
self.update_case_sanger_variants(institute_obj, case_obj, old_sanger_variants)
|
954
948
|
|
@@ -957,7 +951,7 @@ class CaseHandler(object):
|
|
957
951
|
|
958
952
|
else:
|
959
953
|
LOG.info("Loading case %s into database", case_obj["display_name"])
|
960
|
-
self.
|
954
|
+
self.add_case(case_obj, institute_obj)
|
961
955
|
|
962
956
|
return case_obj
|
963
957
|
|
@@ -972,18 +966,6 @@ class CaseHandler(object):
|
|
972
966
|
"custom_images"
|
973
967
|
].get(variant_category)
|
974
968
|
|
975
|
-
def _add_case(self, case_obj):
|
976
|
-
"""Add a case to the database
|
977
|
-
If the case already exists exception is raised
|
978
|
-
|
979
|
-
Args:
|
980
|
-
case_obj(Case)
|
981
|
-
"""
|
982
|
-
if self.case(case_obj["_id"], projection=ID_PROJECTION):
|
983
|
-
raise IntegrityError("Case %s already exists in database" % case_obj["_id"])
|
984
|
-
|
985
|
-
return self.case_collection.insert_one(case_obj)
|
986
|
-
|
987
969
|
def update_case(self, case_obj, keep_date=False):
|
988
970
|
"""Update a case in the database.
|
989
971
|
While updating the case, it compares the date of the latest analysis (case_obj["analysis_date"]) against
|
@@ -1,10 +1,12 @@
|
|
1
1
|
import logging
|
2
2
|
from collections import Counter
|
3
|
+
from os import getlogin
|
3
4
|
from typing import Dict, List, Optional
|
4
5
|
|
5
6
|
import pymongo
|
6
7
|
|
7
|
-
from scout.constants import CASE_STATUSES, CASE_TAGS
|
8
|
+
from scout.constants import CASE_STATUSES, CASE_TAGS, ID_PROJECTION
|
9
|
+
from scout.exceptions import IntegrityError
|
8
10
|
|
9
11
|
LOG = logging.getLogger(__name__)
|
10
12
|
|
@@ -12,6 +14,100 @@ LOG = logging.getLogger(__name__)
|
|
12
14
|
class CaseEventHandler(object):
|
13
15
|
"""Class to handle case events for the mongo adapter"""
|
14
16
|
|
17
|
+
def get_cli_user(self) -> dict:
|
18
|
+
"""
|
19
|
+
Return a faux CLI user with a login username from OS CLI if it is available.
|
20
|
+
"""
|
21
|
+
try:
|
22
|
+
cli_user_name = getlogin()
|
23
|
+
except OSError:
|
24
|
+
# no controlling terminal
|
25
|
+
cli_user_name = "CLI user"
|
26
|
+
|
27
|
+
return {"_id": "CLI", "name": cli_user_name}
|
28
|
+
|
29
|
+
def add_case(self, case_obj: dict, institute_obj: dict):
|
30
|
+
"""Add a case to the database
|
31
|
+
If the case already exists exception is raised.
|
32
|
+
Add case will only be called from CLI, or tests, so the user will be the faux CLI user with
|
33
|
+
a login username from OS CLI if available.
|
34
|
+
"""
|
35
|
+
if self.case(case_obj["_id"], projection=ID_PROJECTION):
|
36
|
+
raise IntegrityError("Case %s already exists in database" % case_obj["_id"])
|
37
|
+
link = f"/{case_obj['owner']}/{case_obj['display_name']}"
|
38
|
+
|
39
|
+
self.create_event(
|
40
|
+
institute=institute_obj,
|
41
|
+
case=case_obj,
|
42
|
+
user=self.get_cli_user(),
|
43
|
+
link=link,
|
44
|
+
category="case",
|
45
|
+
verb="add_case",
|
46
|
+
subject=case_obj["display_name"],
|
47
|
+
)
|
48
|
+
|
49
|
+
return self.case_collection.insert_one(case_obj)
|
50
|
+
|
51
|
+
def update_case_individual(
|
52
|
+
self, case_obj: dict, user_obj: dict, institute_obj: dict, link: str, keep_date: bool = True
|
53
|
+
):
|
54
|
+
"""Update case with new individual data (age and/or Tissue type) for a case
|
55
|
+
and create an associated event"""
|
56
|
+
self._update_case_component(
|
57
|
+
case_obj, user_obj, institute_obj, link, verb="update_individual", keep_date=keep_date
|
58
|
+
)
|
59
|
+
|
60
|
+
def update_case_sample(
|
61
|
+
self, case_obj: dict, user_obj: dict, institute_obj: dict, link: str, keep_date=True
|
62
|
+
):
|
63
|
+
"""Handle update of sample data data (tissue, tumor_type, tumor_purity) for a cancer case
|
64
|
+
and create an associated event"""
|
65
|
+
self._update_case_component(
|
66
|
+
case_obj, user_obj, institute_obj, link, verb="update_sample", keep_date=keep_date
|
67
|
+
)
|
68
|
+
|
69
|
+
def _update_case_component(
|
70
|
+
self,
|
71
|
+
case_obj: dict,
|
72
|
+
user_obj: Optional[dict],
|
73
|
+
institute_obj: dict,
|
74
|
+
link: str,
|
75
|
+
verb: str,
|
76
|
+
keep_date: bool = True,
|
77
|
+
):
|
78
|
+
"""Update case with new sample data, and create an associated event"""
|
79
|
+
self.update_case(case_obj, keep_date)
|
80
|
+
|
81
|
+
if not user_obj:
|
82
|
+
user_obj = self.get_cli_user()
|
83
|
+
|
84
|
+
self.create_event(
|
85
|
+
institute=institute_obj,
|
86
|
+
case=case_obj,
|
87
|
+
user=user_obj,
|
88
|
+
link=link,
|
89
|
+
category="case",
|
90
|
+
verb=verb,
|
91
|
+
subject=case_obj["display_name"],
|
92
|
+
)
|
93
|
+
|
94
|
+
def update_case_cli(self, case_obj: dict, institute_obj: dict):
|
95
|
+
"""Update case with new case obj, and create an associated CLI user event."""
|
96
|
+
|
97
|
+
link = f"/{case_obj['owner']}/{case_obj['display_name']}"
|
98
|
+
|
99
|
+
self.create_event(
|
100
|
+
institute=institute_obj,
|
101
|
+
case=case_obj,
|
102
|
+
user=self.get_cli_user(),
|
103
|
+
link=link,
|
104
|
+
category="case",
|
105
|
+
verb="update_case",
|
106
|
+
subject=case_obj["display_name"],
|
107
|
+
)
|
108
|
+
|
109
|
+
self.update_case(case_obj)
|
110
|
+
|
15
111
|
def assign(self, institute, case, user, link):
|
16
112
|
"""Assign a user to a case.
|
17
113
|
|
@@ -550,7 +646,7 @@ class CaseEventHandler(object):
|
|
550
646
|
updated_diagnoses = []
|
551
647
|
case_diagnoses = case.get("diagnosis_phenotypes") or []
|
552
648
|
|
553
|
-
if remove
|
649
|
+
if remove: # Remove term from case diagnoses list
|
554
650
|
for case_dia in case_diagnoses:
|
555
651
|
if case_dia.get("disease_id") == disease_id:
|
556
652
|
continue
|
scout/adapter/mongo/hgnc.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import logging
|
2
|
+
from typing import Dict
|
2
3
|
|
3
4
|
import intervaltree
|
4
5
|
from pymongo.errors import BulkWriteError, DuplicateKeyError
|
@@ -186,11 +187,11 @@ class GeneHandler(object):
|
|
186
187
|
if build == "GRCh38":
|
187
188
|
build = "38"
|
188
189
|
|
189
|
-
LOG.
|
190
|
+
LOG.debug("Fetching all genes")
|
190
191
|
|
191
192
|
hgnc_tx = {}
|
192
193
|
if add_transcripts:
|
193
|
-
LOG.
|
194
|
+
LOG.debug("Adding transcripts")
|
194
195
|
for tx in self.transcripts(build=str(build)):
|
195
196
|
hgnc_id = tx["hgnc_id"]
|
196
197
|
if not hgnc_id in hgnc_tx:
|
@@ -318,7 +319,7 @@ class GeneHandler(object):
|
|
318
319
|
res = self.hgnc_collection.find({"aliases": symbol, "build": str(build)})
|
319
320
|
return res
|
320
321
|
|
321
|
-
def genes_by_alias(self, build=
|
322
|
+
def genes_by_alias(self, build=None, genes=None):
|
322
323
|
"""Return a dictionary with hgnc symbols as keys and a list of hgnc ids
|
323
324
|
as value.
|
324
325
|
|
@@ -333,45 +334,61 @@ class GeneHandler(object):
|
|
333
334
|
Returns:
|
334
335
|
alias_genes(dict): {<hgnc_alias>: {'true': <hgnc_id>, 'ids': {<hgnc_id_1>, <hgnc_id_2>, ...}}}
|
335
336
|
"""
|
336
|
-
LOG.
|
337
|
+
LOG.debug("Fetching all genes by alias")
|
337
338
|
# Collect one entry for each alias symbol that exists
|
338
339
|
alias_genes = {}
|
339
|
-
|
340
|
-
if
|
341
|
-
|
340
|
+
|
341
|
+
if genes is None:
|
342
|
+
genes_query = {"build": str(build)} if build else {}
|
343
|
+
genes = self.hgnc_collection.find(
|
344
|
+
genes_query, projection={"hgnc_id": 1, "hgnc_symbol": 1, "aliases": 1}
|
345
|
+
)
|
342
346
|
|
343
347
|
for gene in genes:
|
344
|
-
# Collect the hgnc_id
|
345
348
|
hgnc_id = gene["hgnc_id"]
|
346
|
-
# Collect the true symbol given by hgnc
|
347
349
|
hgnc_symbol = gene["hgnc_symbol"]
|
348
|
-
|
350
|
+
|
349
351
|
for alias in gene["aliases"]:
|
350
|
-
|
351
|
-
|
352
|
+
if alias not in alias_genes:
|
353
|
+
alias_genes[alias] = {"true": None, "ids": set()}
|
354
|
+
|
355
|
+
alias_genes[alias]["ids"].add(hgnc_id)
|
352
356
|
if alias == hgnc_symbol:
|
353
|
-
|
354
|
-
# If the alias is already in the list we add the id
|
355
|
-
if alias in alias_genes:
|
356
|
-
alias_genes[alias]["ids"].add(hgnc_id)
|
357
|
-
if true_id:
|
358
|
-
alias_genes[alias]["true"] = hgnc_id
|
359
|
-
else:
|
360
|
-
alias_genes[alias] = {"true": hgnc_id, "ids": set([hgnc_id])}
|
357
|
+
alias_genes[alias]["true"] = hgnc_id
|
361
358
|
|
362
359
|
return alias_genes
|
363
360
|
|
364
|
-
def
|
361
|
+
def ensembl_to_hgnc_id_mapping(self) -> Dict[str, int]:
|
365
362
|
"""Return a dictionary with Ensembl ids as keys and hgnc_ids as values
|
366
363
|
|
367
364
|
Returns:
|
368
|
-
mapping(dict): {"ENSG00000121410":
|
365
|
+
mapping(dict): {"ENSG00000121410": 5, ...}
|
369
366
|
"""
|
370
367
|
pipeline = [{"$group": {"_id": {"ensembl_id": "$ensembl_id", "hgnc_id": "$hgnc_id"}}}]
|
371
368
|
result = self.hgnc_collection.aggregate(pipeline)
|
372
369
|
mapping = {res["_id"]["ensembl_id"]: res["_id"]["hgnc_id"] for res in result}
|
373
370
|
return mapping
|
374
371
|
|
372
|
+
def hgnc_symbol_ensembl_id_mapping(self) -> Dict[str, str]:
|
373
|
+
"""Return a dictionary with HGNC symbols as keys and Ensembl ids as values.
|
374
|
+
|
375
|
+
Returns:
|
376
|
+
mapping(dict): {"A1BG": "ENSG00000121410".}
|
377
|
+
"""
|
378
|
+
pipeline = [
|
379
|
+
{
|
380
|
+
"$group": {
|
381
|
+
"_id": {
|
382
|
+
"hgnc_symbol": "$hgnc_symbol",
|
383
|
+
"ensembl_id": "$ensembl_id",
|
384
|
+
}
|
385
|
+
}
|
386
|
+
}
|
387
|
+
]
|
388
|
+
result = self.hgnc_collection.aggregate(pipeline)
|
389
|
+
mapping = {res["_id"]["hgnc_symbol"]: res["_id"]["ensembl_id"] for res in result}
|
390
|
+
return mapping
|
391
|
+
|
375
392
|
def ensembl_genes(self, build=None, add_transcripts=False, id_transcripts=False):
|
376
393
|
"""Return a dictionary with ensembl ids as keys and gene objects as value.
|
377
394
|
|
scout/adapter/mongo/institute.py
CHANGED
@@ -158,15 +158,9 @@ class InstituteHandler(object):
|
|
158
158
|
|
159
159
|
return institute_obj
|
160
160
|
|
161
|
-
def safe_genes_filter(self, institute_id):
|
161
|
+
def safe_genes_filter(self, institute_id: str) -> List[int]:
|
162
162
|
"""Returns a list of "safe" HGNC IDs to filter variants with. These genes are retrieved from the institute.gene_panels_matching
|
163
|
-
Can be used to limit secondary findings when retrieving other causatives or matching managed variants
|
164
|
-
|
165
|
-
Args:
|
166
|
-
institute_id(str): _id of an institute
|
167
|
-
|
168
|
-
Returns:
|
169
|
-
safe_genes(list of HGNC ids)
|
163
|
+
Can be used to limit secondary findings when retrieving other causatives or matching managed variants.
|
170
164
|
"""
|
171
165
|
safe_genes = []
|
172
166
|
institute_obj = self.institute(institute_id)
|
@@ -174,7 +168,7 @@ class InstituteHandler(object):
|
|
174
168
|
return safe_genes # return an empty list
|
175
169
|
for panel_name in institute_obj.get("gene_panels_matching", {}).keys():
|
176
170
|
safe_genes += self.panel_to_genes(panel_name=panel_name, gene_format="hgnc_id")
|
177
|
-
return safe_genes
|
171
|
+
return list(set(safe_genes))
|
178
172
|
|
179
173
|
def institutes(self, institute_ids=None):
|
180
174
|
"""Fetch all institutes.
|
scout/adapter/mongo/panel.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
"""Code to handle panels in the mongo database"""
|
2
|
+
|
2
3
|
import datetime as dt
|
3
4
|
import logging
|
4
5
|
import math
|
@@ -244,7 +245,7 @@ class PanelHandler:
|
|
244
245
|
for panel in res:
|
245
246
|
return panel
|
246
247
|
|
247
|
-
LOG.
|
248
|
+
LOG.warning("Gene panel not found")
|
248
249
|
|
249
250
|
return None
|
250
251
|
|
scout/adapter/mongo/variant.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
# stdlib modules
|
3
3
|
import logging
|
4
4
|
import re
|
5
|
+
from typing import Any
|
5
6
|
|
6
7
|
# Third party modules
|
7
8
|
import pymongo
|
@@ -221,6 +222,14 @@ class VariantHandler(VariantLoader):
|
|
221
222
|
query = self.build_query(case_id, query=query, variant_ids=variant_ids, category=category)
|
222
223
|
return self.variant_collection.count_documents(query)
|
223
224
|
|
225
|
+
def variant_update_field(self, variant_id: str, field_name: str, field_value: Any) -> dict:
|
226
|
+
"""Updates the value of the given key(field_name) in the variant document in the database."""
|
227
|
+
return self.variant_collection.find_one_and_update(
|
228
|
+
{"_id": variant_id},
|
229
|
+
{"$set": {field_name: field_value}},
|
230
|
+
return_document=pymongo.ReturnDocument.AFTER,
|
231
|
+
)
|
232
|
+
|
224
233
|
def variant(
|
225
234
|
self,
|
226
235
|
document_id=None,
|
@@ -542,7 +551,8 @@ class VariantHandler(VariantLoader):
|
|
542
551
|
"institute": case_obj["owner"],
|
543
552
|
"verb": {"$in": ["mark_causative", "mark_partial_causative"]},
|
544
553
|
"category": "variant",
|
545
|
-
}
|
554
|
+
},
|
555
|
+
{"case": 1, "link": 1, "subject": 1},
|
546
556
|
)
|
547
557
|
|
548
558
|
positional_variant_ids = set()
|
@@ -553,7 +563,7 @@ class VariantHandler(VariantLoader):
|
|
553
563
|
|
554
564
|
other_case = self.case(var_event["case"], CASE_CAUSATIVES_PROJECTION)
|
555
565
|
if other_case is None:
|
556
|
-
# Other variant belongs to a case that
|
566
|
+
# Other variant belongs to a case that doesn't exist anymore
|
557
567
|
continue
|
558
568
|
other_link = var_event["link"]
|
559
569
|
# link contains other variant ID
|