Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 1 addition & 1 deletion src/mavedb/lib/csv/namespaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class CsvNamespace(StrEnum):
CsvNamespace.CLINGEN: ("ClinGen allele ID", CsvNamespaceGroup.ANNOTATION),
CsvNamespace.REFERENCE_HGVS: ("Reference-frame HGVS", CsvNamespaceGroup.ANNOTATION),
CsvNamespace.VEP: ("VEP consequence", CsvNamespaceGroup.ANNOTATION),
CsvNamespace.GNOMAD: ("gnomAD allele frequency", CsvNamespaceGroup.ANNOTATION),
CsvNamespace.GNOMAD: ("gnomAD population frequency", CsvNamespaceGroup.ANNOTATION),
CsvNamespace.SCORE_SET: ("Score set and target gene", CsvNamespaceGroup.PROVENANCE),
CsvNamespace.RELATIONSHIP: ("Relationship to the requested variant", CsvNamespaceGroup.PROVENANCE),
}
Expand Down
10 changes: 9 additions & 1 deletion src/mavedb/lib/csv/specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,15 @@ def _optional(getter: Callable) -> Callable:
),
CsvNamespace.GNOMAD: CsvNamespaceSpec(
source=RowSource.GNOMAD,
resolvers={"gnomad_af": _optional(lambda gnomad: gnomad.allele_frequency)},
resolvers={
"gnomad_af": _optional(attrgetter("allele_frequency")),
"gnomad_ac": _optional(attrgetter("allele_count")),
"gnomad_an": _optional(attrgetter("allele_number")),
"gnomad_faf95_max": _optional(attrgetter("faf95_max")),
"gnomad_faf95_max_ancestry": _optional(attrgetter("faf95_max_ancestry")),
"gnomad_id": _optional(attrgetter("db_identifier")),
"gnomad_version": _optional(attrgetter("db_version")),
},
needs_mappings=True,
needs_gnomad=True,
),
Expand Down
8 changes: 7 additions & 1 deletion src/mavedb/scripts/resources/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,13 @@ Columns are grouped by a namespace prefix. The groups below always appear:
| `mavedb.post_mapped_hgvs_at_assay_level` | Post-mapped HGVS at the assay reference level (transcript or protein) |
| `mavedb.post_mapped_vrs_id` | GA4GH VRS identifier for the post-mapped allele (e.g. `ga4gh:VA.n9ax-9x6gOC0OEt73VMYqCBfqfxG1XUH`) |
| `vep.vep_functional_consequence` | VEP functional consequence term (e.g. `missense_variant`) |
| `gnomad.gnomad_af` | gnomAD v4.1 allele frequency |
| `gnomad.gnomad_af` | gnomAD allele frequency (allele count ÷ allele number) |
| `gnomad.gnomad_ac` | gnomAD allele count — chromosomes observed carrying the allele |
| `gnomad.gnomad_an` | gnomAD allele number — total chromosomes sampled |
| `gnomad.gnomad_faf95_max` | Maximum filtering allele frequency at 95% confidence across genetic ancestry groups |
| `gnomad.gnomad_faf95_max_ancestry` | Genetic ancestry group attaining `gnomad_faf95_max` |
| `gnomad.gnomad_id` | gnomAD variant identifier (`chrom-pos-ref-alt`), e.g. `17-43092919-G-A` |
| `gnomad.gnomad_version` | gnomAD release the frequencies were drawn from (e.g. `v4.1`) |
| `clingen.clingen_allele_id` | ClinGen Allele Registry CA identifier (e.g. `CA12345`) |

Two further groups vary by score set, because they exist only where MaveDB holds the underlying data.
Expand Down
17 changes: 16 additions & 1 deletion tests/lib/csv/test_columns.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,22 @@ def test_quotes_values_containing_commas(self):
{},
),
(["vep"], {"core", "vep"}, {"vep": ["vep_functional_consequence"]}, {}),
(["gnomad"], {"core", "gnomad"}, {"gnomad": ["gnomad_af"]}, {}),
(
["gnomad"],
{"core", "gnomad"},
{
"gnomad": [
"gnomad_af",
"gnomad_ac",
"gnomad_an",
"gnomad_faf95_max",
"gnomad_faf95_max_ancestry",
"gnomad_id",
"gnomad_version",
]
},
{},
),
(["clingen"], {"core", "clingen"}, {"clingen": ["clingen_allele_id"]}, {}),
(["scores", "mavedb"], {"core", "scores", "mavedb"}, {"scores": ["score"]}, {}),
(["clinvar.2024_01"], {"core", "clinvar.2024_01"}, {}, {"clinvar.2024_01": "01_2024"}),
Expand Down
47 changes: 43 additions & 4 deletions tests/lib/csv/test_variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,45 @@ def test_post_mapped_vrs_id_is_never_synthesized_from_digest(self, session, setu

assert rows[0]["mavedb.post_mapped_vrs_id"] == "NA"

def test_gnomad_namespace_reports_the_whole_frequency_record(self, session, setup_lib_db_with_mapped_variant):
"""AF alone cannot be linked out from or judged for sampling depth; the namespace carries the record."""
mapped_variant = setup_lib_db_with_mapped_variant
mapped_variant.gnomad_variants.append(GnomADVariant(**TEST_GNOMAD_VARIANT))
session.add(mapped_variant)
session.commit()

with patch("mavedb.lib.csv.fetch.GNOMAD_DATA_VERSION", TEST_GNOMAD_DATA_VERSION):
csv_text = get_variant_csv(session, mapped_variant.variant.urn)
rows = _parse_csv(csv_text)

assert [column for column in rows[0].keys() if column.startswith("gnomad.")] == [
"gnomad.gnomad_af",
"gnomad.gnomad_ac",
"gnomad.gnomad_an",
"gnomad.gnomad_faf95_max",
"gnomad.gnomad_faf95_max_ancestry",
"gnomad.gnomad_id",
"gnomad.gnomad_version",
]
assert rows[0]["gnomad.gnomad_af"] == str(TEST_GNOMAD_VARIANT["allele_frequency"])
assert rows[0]["gnomad.gnomad_ac"] == str(TEST_GNOMAD_VARIANT["allele_count"])
assert rows[0]["gnomad.gnomad_an"] == str(TEST_GNOMAD_VARIANT["allele_number"])
assert rows[0]["gnomad.gnomad_faf95_max"] == str(TEST_GNOMAD_VARIANT["faf95_max"])
assert rows[0]["gnomad.gnomad_faf95_max_ancestry"] == str(TEST_GNOMAD_VARIANT["faf95_max_ancestry"])
assert rows[0]["gnomad.gnomad_id"] == str(TEST_GNOMAD_VARIANT["db_identifier"])
assert rows[0]["gnomad.gnomad_version"] == TEST_GNOMAD_DATA_VERSION

def test_gnomad_record_absent_leaves_every_column_na(self, session, setup_lib_db_with_mapped_variant):
"""A variant with no gnomAD record reports NA across the namespace, never a zero frequency."""
mapped_variant = setup_lib_db_with_mapped_variant

with patch("mavedb.lib.csv.fetch.GNOMAD_DATA_VERSION", TEST_GNOMAD_DATA_VERSION):
rows = _parse_csv(get_variant_csv(session, mapped_variant.variant.urn))

gnomad_values = {key: value for key, value in rows[0].items() if key.startswith("gnomad.")}
assert len(gnomad_values) == 7
assert set(gnomad_values.values()) == {"NA"}

def test_gnomad_variant_from_another_version_is_not_reported(self, session, setup_lib_db_with_mapped_variant):
mapped_variant = setup_lib_db_with_mapped_variant
mapped_variant.gnomad_variants.append(GnomADVariant(**TEST_GNOMAD_VARIANT))
Expand Down Expand Up @@ -673,9 +712,9 @@ def record(conn, cursor, statement, parameters, context, executemany):
for statement in statements
if "score_calibrations" in statement and " variants" in statement.replace("\n", " ")
]
assert (
calibration_scans == []
), "calibration discovery joined the variants table; it should filter on score_set_id"
assert calibration_scans == [], (
"calibration discovery joined the variants table; it should filter on score_set_id"
)

def test_base_namespaces_are_all_present_by_default(self, session, setup_lib_db_with_mapped_variant):
variant = setup_lib_db_with_mapped_variant.variant
Expand Down Expand Up @@ -877,7 +916,7 @@ def test_entries_are_labeled_for_a_picker(self, session, setup_lib_db_with_mappe
# A ClinVar release is named by its date.
assert by_namespace["clinvar.2024_11"].label == "ClinVar significance (November 2024)"
assert by_namespace["clinvar.2024_11"].group == "annotation"
assert by_namespace["gnomad"].label == "gnomAD allele frequency"
assert by_namespace["gnomad"].label == "gnomAD population frequency"
assert by_namespace["score_set"].group == "provenance"


Expand Down
2 changes: 1 addition & 1 deletion tests/routers/test_variant.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ def test_score_set_namespaces_are_labeled_and_grouped(
by_namespace = {entry["namespace"]: entry for entry in entries}
assert {"scores", "score_set", "vep", "gnomad", "clingen"} <= set(by_namespace)
assert "relationship" not in by_namespace
assert by_namespace["gnomad"]["label"] == "gnomAD allele frequency"
assert by_namespace["gnomad"]["label"] == "gnomAD population frequency"
assert by_namespace["gnomad"]["group"] == "annotation"
# Every entry is renderable without the client inventing labels.
assert all(entry["label"] and entry["group"] for entry in entries)
Expand Down
Loading