Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better ClinVar tooltips and added exclude clinsig status for SNVs filter #4993

Draft
wants to merge 37 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
2afc0f6
Added negation checkbox
Nov 4, 2024
5b08005
Exclude filter ok
Nov 4, 2024
e36e008
Remove some debug messages
Nov 4, 2024
33271bb
Improve clinsig tooltips
Nov 4, 2024
ed63fcf
Fix query
Nov 4, 2024
7776960
Updated changelog
Nov 4, 2024
eabadd4
Better changelog
Nov 4, 2024
95f0066
Expand test
Nov 4, 2024
7fa5b45
Merge branch 'main' into refactor_clinvar_filter
dnil Nov 5, 2024
98c8ac0
Update CHANGELOG.md
northwestwitch Nov 5, 2024
1b410b1
partial fix exclude searcg
Nov 5, 2024
ce79510
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 5, 2024
2ba5853
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 5, 2024
74a10fa
Merge branch 'main' into refactor_clinvar_filter
dnil Nov 12, 2024
4fff660
Merge branch 'main' into refactor_clinvar_filter
dnil Nov 12, 2024
8bbfe5b
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 12, 2024
bc3b922
Merge branch 'main' into refactor_clinvar_filter
dnil Nov 12, 2024
46e5143
Merge branch 'main' into refactor_clinvar_filter
dnil Nov 13, 2024
9d30a8b
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 13, 2024
64dfaef
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 13, 2024
09b4393
Merge branch 'main' into refactor_clinvar_filter
dnil Nov 14, 2024
91fb257
Merge branch 'main' into refactor_clinvar_filter
dnil Nov 15, 2024
5602c6c
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 15, 2024
eadcf24
Merge branch 'main' into refactor_clinvar_filter
dnil Nov 15, 2024
27a7a72
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 18, 2024
d13c58d
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 18, 2024
4f0c1cb
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 19, 2024
7979ead
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 19, 2024
abd27ac
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 19, 2024
1106ed2
Merge branch 'main' into refactor_clinvar_filter
dnil Nov 19, 2024
80f495f
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 20, 2024
f3eb44b
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 20, 2024
c278238
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 20, 2024
114b4b5
Merge branch 'main' into refactor_clinvar_filter
northwestwitch Nov 20, 2024
b3c4fe0
Merge branch 'main' into refactor_clinvar_filter
dnil Nov 22, 2024
c1b8a90
Merge branch 'main' into refactor_clinvar_filter
dnil Nov 22, 2024
f888651
Merge branch 'main' into refactor_clinvar_filter
dnil Nov 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ About changelog [here](https://keepachangelog.com/en/1.0.0/)
- Export variant type and callers-related info fields when exporting variants from variantS pages
- Cases advanced search on the dashboard page
- Possibility to use only signed off panels when building the PanelApp GREEN panel
- Option to exclude ClinVar significance status in SNVs filters form
### Changed
- On genes panel page and gene panel PDF export, it's more evident which genes were newly introduced into the panel
- WTS outlier position copy button on WTS outliers page
Expand All @@ -34,6 +35,7 @@ About changelog [here](https://keepachangelog.com/en/1.0.0/)
- Refactor the loading of PanelApp panels to use the maintained API - Customised PanelApp GREEN panels
- Better layout for Consequence cell on cancer SNVs page
- Merged `Qual` and `Callers` cell on cancer SNVs page
- Improved tooltips for ClinVar filter in SNVs filter form
### Fixed
- Empty custom_images dicts in case load config do not crash
- Tracks missing alignment files are skipped on generating IGV views
Expand Down
58 changes: 24 additions & 34 deletions scout/adapter/mongo/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ def build_query(
'region_annotations': list,
'functional_annotations': list,
'clinsig': list,
'clinsig_exclude': bool,
'clinsig_confident_always_returned': boolean,
'variant_type': str(('research', 'clinical')),
'chrom': str or list of str,
Expand Down Expand Up @@ -322,14 +323,16 @@ def build_query(
for term in PRIMARY_CRITERIA:
if query.get(term):
primary_terms = True
break
northwestwitch marked this conversation as resolved.
Show resolved Hide resolved

# check if any of the secondary criteria was specified in the query:
for term in SECONDARY_CRITERIA:
if query.get(term):
secondary_terms = True
break

if primary_terms is True:
clinsign_filter = self.clinsig_query(query, mongo_query)
clinsign_filter = self.clinsig_query(query)

# Secondary, excluding filter criteria will hide variants in general,
# but can be overridden by an including, major filter criteria
Expand Down Expand Up @@ -358,9 +361,15 @@ def build_query(
secondary_filter.append(clinsign_filter)
mongo_query["$and"] = secondary_filter

elif primary_terms is True: # clisig is provided without secondary terms query
elif primary_terms is True: # clnsig is provided without secondary terms query
# use implicit and
mongo_query["clnsig"] = clinsign_filter["clnsig"]
if query.get("clinsig_exclude"):
mongo_query["$or"] = [
{"clnsig": {"$exists": False}},
{"clnsig": {"$not": clinsign_filter["clnsig"]}},
]
else:
mongo_query["clnsig"] = clinsign_filter["clnsig"]

# if chromosome coordinates exist in query, add them as first element of the mongo_query['$and']
if coordinate_query:
Expand All @@ -369,6 +378,7 @@ def build_query(
else:
mongo_query["$and"] = coordinate_query

LOG.warning(mongo_query)
return mongo_query

def affected_inds_query(self, mongo_query, case_id, gt_query):
Expand Down Expand Up @@ -404,60 +414,40 @@ def affected_inds_query(self, mongo_query, case_id, gt_query):
]: # Consider situation where all individuals are unaffected
mongo_query["samples"] = affected_query

def clinsig_query(self, query, mongo_query):
"""Add clinsig filter values to the mongo query object

Args:
query(dict): a dictionary of query filters specified by the users
mongo_query(dict): the query that is going to be submitted to the database

Returns:
clinsig_query(dict): a dictionary with clinsig key-values
def clinsig_query(self, query: dict) -> dict:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is only refactored, but it returns the same dict as before

"""Add clinsig filter values to the mongo query object"""

"""
LOG.debug("clinsig is a query parameter")
trusted_revision_level = TRUSTED_REVSTAT_LEVEL
rank = []
str_rank = []
clnsig_query = {}

for item in query["clinsig"]:
rank.append(int(item))
# search for human readable clinsig values in newer cases
rank.append(CLINSIG_MAP[int(item)])
str_rank.append(CLINSIG_MAP[int(item)])

if query.get("clinsig_confident_always_returned") is True:
LOG.debug("add CLINSIG filter with trusted_revision_level")
elem_match_value = {
"$or": [
{"value": {"$in": rank}},
{"value": re.compile("|".join(str_rank))},
]
}

if query.get("clinsig_confident_always_returned") is True:
clnsig_query = {
"clnsig": {
"$elemMatch": {
"$and": [
{
"$or": [
{"value": {"$in": rank}},
{"value": re.compile("|".join(str_rank))},
]
},
elem_match_value,
{"revstat": re.compile("|".join(trusted_revision_level))},
]
}
}
}
else:
LOG.debug("add CLINSIG filter for rank: %s" % ", ".join(str(query["clinsig"])))
clnsig_query = {"clnsig": {"$elemMatch": elem_match_value}}

clnsig_query = {
"clnsig": {
"$elemMatch": {
"$or": [
{"value": {"$in": rank}},
{"value": re.compile("|".join(str_rank))},
]
}
}
}
return clnsig_query

def coordinate_filter(self, query, mongo_query):
Expand Down
1 change: 1 addition & 0 deletions scout/server/blueprints/variants/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ class VariantFiltersForm(FlaskForm):
compound_follow_filter = BooleanField("Compounds follow filter")
cadd_inclusive = BooleanField("CADD inclusive")
clinsig = NonValidatingSelectMultipleField("ClinVar CLINSIG", choices=CLINSIG_OPTIONS)
clinsig_exclude = BooleanField("Exclude significance")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optionally drop "significance"; should be as clear from context and tooltip.


gnomad_frequency = BetterDecimalField("gnomadAF", validators=[validators.Optional()])
local_obs_old = IntegerField("Local obs. (archive)", validators=[validators.Optional()])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -308,16 +308,17 @@
{{ form.spidex_human(class="selectpicker", data_style="btn-secondary") }}
</div>
<div class="col-2">
{{ form.clinsig.label(class="control-label") }}
<span>{{ form.clinsig.label(class="control-label") }}</span>
<span style="float:right;">{{ form.clinsig_exclude.label(class="control-label", data_bs_toggle="tooltip", data_bs_placement="left", title="Exclude variants with clinical significance among the selected categories.") }} {{form.clinsig_exclude}}</span>
{{ form.clinsig(class="selectpicker", data_style="btn-secondary") }}
</div>
<div class="col-1">
{{ form.clinsig_confident_always_returned.label(class="control-label", data_bs_toggle="tooltip", data_bs_placement="top", title="Always show selected CLINSIG entries with trusted revision status levels.") }}
<div>{{ form.clinsig_confident_always_returned() }}</div>
<span>{{ form.clinsig_confident_always_returned.label(class="control-label", data_bs_toggle="tooltip", data_bs_placement="top", title="Limit search to variants with trusted ClinVar revision status levels: mult, multiple_submitters, single, single_submitter, exp, reviewed_by_expert_panel, guideline, practice_guideline.") }}</span>
northwestwitch marked this conversation as resolved.
Show resolved Hide resolved
<span>{{ form.clinsig_confident_always_returned() }}</span>
</div>
<div class="col-1">
{{ form.clinvar_tag.label(class="control-label", data_bs_toggle="tooltip", data_bs_placement="top", title="Return only variants with annotated ClinVar significance.") }}
{{ form.clinvar_tag() }}
{{ form.clinvar_tag.label(class="ms-2") }}
</div>
</div>
<div class="row mb-2">
Expand Down
10 changes: 7 additions & 3 deletions tests/adapter/mongo/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ def test_build_clinsig(adapter):


def test_build_clinsig_filter(real_variant_database):
"""Test building a variants query with ClinVar status."""
adapter = real_variant_database
case_id = "cust000"
clinsig_items = [4, 5]
Expand Down Expand Up @@ -349,7 +350,7 @@ def test_build_clinsig_filter(real_variant_database):
{"$set": {"clnsig.0.value": "Pathogenic, Likely pathogenic"}},
)

# One variant has multiple clssig now:
# One variant has multiple clinsig now:
northwestwitch marked this conversation as resolved.
Show resolved Hide resolved
res = adapter.variant_collection.find({"clnsig.value": "Pathogenic, Likely pathogenic"})
assert sum(1 for _ in res) == 1

Expand Down Expand Up @@ -384,7 +385,8 @@ def test_build_clinsig_filter(real_variant_database):
assert n_results_raw_query == n_filtered_variants


def test_build_clinsig_always(real_variant_database):
def test_build_clinsig_high_confidence_plus_region_and_gnomad(real_variant_database):
"""Test building a variants query with ClinVar status and high confidence."""
adapter = real_variant_database
case_id = "cust000"
clinsig_confident_always_returned = True
Expand Down Expand Up @@ -545,7 +547,8 @@ def test_build_has_cosmic_ids(
assert {"cosmic_ids": {"$ne": None}} in mongo_query["$and"]


def test_build_clinsig_always_only(adapter):
def test_build_clinsig_high_confidence(adapter):
"""Test building a variants query with high confidence of ClinVar status."""
case_id = "cust000"
clinsig_confident_always_returned = True
trusted_revstat_lev = TRUSTED_REVSTAT_LEVEL
Expand All @@ -557,6 +560,7 @@ def test_build_clinsig_always_only(adapter):
all_clinsig.append(CLINSIG_MAP[item])
clinsig_mapped_items.append(CLINSIG_MAP[item])

# Testing with INCLUDE ClinVar terms criterion
query = {
"clinsig": clinsig_items,
"clinsig_confident_always_returned": clinsig_confident_always_returned,
Expand Down
Loading