Skip to content

Commit

Permalink
fix: lift over orphaned variant annotations (#1124)
Browse files Browse the repository at this point in the history
  • Loading branch information
stolpeo committed Sep 11, 2023
1 parent ed0652a commit d97358b
Show file tree
Hide file tree
Showing 8 changed files with 449 additions and 512 deletions.
38 changes: 19 additions & 19 deletions maintenance/management/commands/generate_result_set.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Django command for generating query result sets."""
import json

from django.core.exceptions import ValidationError
from django.core.management.base import BaseCommand
from django.db import transaction
Expand Down Expand Up @@ -63,42 +65,38 @@ def handle(self, *args, **options):
msg = "Creating query set for all cases."

self.stdout.write(self.style.NOTICE(msg))
msg_warning = None
msg_warning = ""
msg_orphans = ""

if options["async"]:
count, fill_count = create_queryresultset(
count, fill_count, orphans = create_queryresultset(
options["case_uuid"], options["project_uuid"], options["all"]
)
msg = "Done creating result sets:"
if (
count["smallvariantqueryresultset"]
or count["svqueryresultset"]
or fill_count["small_variants"]
or fill_count["structural_variants"]
or fill_count["small_variant_annotations"]
or fill_count["structural_variant_annotations"]
):
msg += f"""
- SmallVariantQueryResultSets created: {count['smallvariantqueryresultset']}
- SvQueryResultSets created: {count['svqueryresultset']}
- User annotations added to SmallVariantQueryResultSets: {fill_count['small_variants']}
- User annotations added to SvQueryResultSets: {fill_count['structural_variants']}"""
- User annotations added to SmallVariantQueryResultSets: {fill_count['small_variant_annotations']}
- User annotations added to SvQueryResultSets: {fill_count['structural_variant_annotations']}"""
else:
msg += "\n- Nothing to do."
if (
fill_count["small_variants_orphaned"]
or fill_count["structural_variants_orphaned"]
or fill_count["small_variants_no_query_result_set"]
or fill_count["structural_variants_no_query_result_set"]
or fill_count["small_variants_no_case_result_set"]
or fill_count["structural_variants_no_case_result_set"]
fill_count["small_variant_annotations_orphaned"]
or fill_count["structural_variant_annotations_orphaned"]
):
msg_warning = f"""
WARNING! There are orphaned user annotations or cases or queries without result set:
- Orphaned small variant user annotations: {fill_count['small_variants_orphaned']}
- Small variant queries without result set: {fill_count['small_variants_no_query_result_set']}
- Cases without small variant query result set: {fill_count['small_variants_no_case_result_set']}
- Orphaned structural variant user annotations: {fill_count['structural_variants_orphaned']}
- Structural variant queries without result set: {fill_count['structural_variants_no_query_result_set']}
- Cases without structural variant query result set: {fill_count['structural_variants_no_case_result_set']}""".lstrip()
WARNING! There are orphaned user annotations:
- Orphaned small variant user annotations: {fill_count['small_variant_annotations_orphaned']}
- Orphaned structural variant user annotations: {fill_count['structural_variant_annotations_orphaned']}""".lstrip()
msg_orphans = json.dumps(orphans, indent=1)
with open("orphans.json", "w") as f:
json.dump(orphans, f, indent=1)
else:
task_create_queryresultset.delay(
options["case_uuid"], options["project_uuid"], options["all"]
Expand All @@ -108,3 +106,5 @@ def handle(self, *args, **options):
self.stdout.write(self.style.SUCCESS(msg))
if msg_warning:
self.stdout.write(self.style.WARNING(msg_warning))
if msg_orphans:
self.stdout.write(self.style.NOTICE(msg_orphans))
41 changes: 41 additions & 0 deletions utils/kickoff_orphaned_annotation_query.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import json
import sys

import requests

BASE_URL = "http://"
TOKEN = "XXX"
SETTINGS_URL = f"{BASE_URL}/variants/api/query-case/query-settings-shortcut"
QUERY_URL = f"{BASE_URL}/variants/api/query/list-create"


headers = {"Authorization": "TOKEN " + TOKEN}


def read_file(file):
with open(file, "r") as f:
return json.load(f)


def main():
orphans = read_file(sys.argv[1])
for case_uuid, case_orphans in orphans.items():
if not case_orphans["small_variants"]:
continue
response = requests.get(f"{SETTINGS_URL}/{case_uuid}/", headers=headers)
if response.status_code != 200:
print(f"Error: {response.status_code} ({case_uuid})")
continue
response = response.json()
response["query_settings"]["selected_variants"] = case_orphans["small_variants"]
response = requests.post(f"{QUERY_URL}/{case_uuid}/", headers=headers, json=response)
print(
f"Query created for case {case_uuid}, {len(case_orphans['small_variants'])} orphans, status code: {response.status_code}"
)


if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: kickoff_orphaned_annotation_query.py <orphans.json>")
sys.exit(1)
main()
22 changes: 22 additions & 0 deletions variants/queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -1567,6 +1567,27 @@ def extend_selectable(self, query_parts):
)


class ExtendQueryPartsSelectVariants(ExtendQueryPartsBase):
def extend_conditions(self, _query_parts):
condition = []

if not self.kwargs.get("selected_variants"):
return []

for variant in self.kwargs["selected_variants"]:
release, chromosome, start, reference, alternative = variant.split("-")
condition.append(
and_(
SmallVariant.sa.release == release,
SmallVariant.sa.chromosome == chromosome,
SmallVariant.sa.start == start,
SmallVariant.sa.reference == reference,
SmallVariant.sa.alternative == alternative,
)
)
return [or_(*condition)]


#: QueryPartsBuilderExtender classes list for cases.
extender_classes_base = [
ExtendQueryPartsCaseJoinAndFilter,
Expand Down Expand Up @@ -1640,6 +1661,7 @@ def get_qp_extender_classes(self):
ExtendQueryPartsGeneSymbolJoin,
ExtendQueryPartsAcmgJoin,
ExtendQueryPartsMgiJoin,
ExtendQueryPartsSelectVariants,
]


Expand Down
3 changes: 3 additions & 0 deletions variants/query_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ class CaseQueryV1:
quality: typing.Dict[str, QualitySettingsV1]
genotype: typing.Dict[str, typing.Optional[GenotypeChoiceV1]]

selected_variants: typing.Optional[typing.List[str]] = None

transcripts_coding: bool = True
transcripts_noncoding: bool = False

Expand Down Expand Up @@ -296,6 +298,7 @@ class QueryJsonToFormConverter:

def convert(self, case: Case, query: CaseQueryV1) -> typing.Dict[str, typing.Any]:
result = {
"selected_variants": query.selected_variants,
"database_select": query.database,
"var_type_snv": query.var_type_snv,
"var_type_mnv": query.var_type_mnv,
Expand Down
18 changes: 18 additions & 0 deletions variants/schemas/case-query-v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@
"genotype"
],
"properties": {
"selected_variants": {
"anyOf": [
{
"type": "null"
},
{
"$id": "#/properties/selected_variants",
"type": "array",
"title": "The selected_variants schema",
"description": "Limit query to specified variants",
"default": [],
"examples": [
"GRCh37-1-1000000-A-G",
"GRCh37-1-1000001-T-C"
]
}
]
},
"database": {
"$id": "#/properties/database",
"type": "string",
Expand Down
4 changes: 2 additions & 2 deletions variants/tests/data/query_settings.py
Git LFS file not shown
Loading

0 comments on commit d97358b

Please sign in to comment.