Exclude variants that fail quality controls.
Applies two sequential checks to each variant:
- The FILTER field must be
"PASS" or "." (missing/not-applied).
- The QUAL score must be present and at least
min_qual.
Variants that fail either check are silently dropped from the output
stream, except when QUAL is missing. In that case a
MissingDataWarning is emitted via Python's warnings module before
the variant is excluded.
Parameters
config : QualityFilterConfig
Filtering parameters. The min_qual field specifies the minimum
acceptable QUAL score (default 20.0, valid range [0, 1_000_000]).
Raises
ValueError
If config.min_qual is outside [0, 1_000_000]. This is enforced by
QualityFilterConfig.__post_init__ at config construction time.
Examples
from vartriage.models.config import QualityFilterConfig
from vartriage.models.variant import Variant
cfg = QualityFilterConfig(min_qual=30.0)
qf = QualityFilter(cfg)
variants = [
... Variant(chrom="chr1", pos=100, id=None, ref="A", alt="T",
... qual=50.0, filter_status="PASS"),
... Variant(chrom="chr1", pos=200, id=None, ref="G", alt="C",
... qual=10.0, filter_status="PASS"),
... ]
list(qf.apply(iter(variants))) # only first variant passes
[Variant(chrom='chr1', pos=100, ...)]
Source code in vartriage/filter/quality_filter.py
| class QualityFilter:
"""Exclude variants that fail quality controls.
Applies two sequential checks to each variant:
1. The FILTER field must be ``"PASS"`` or ``"."`` (missing/not-applied).
2. The QUAL score must be present and at least ``min_qual``.
Variants that fail either check are silently dropped from the output
stream, except when QUAL is missing. In that case a
``MissingDataWarning`` is emitted via Python's ``warnings`` module before
the variant is excluded.
Parameters
----------
config : QualityFilterConfig
Filtering parameters. The ``min_qual`` field specifies the minimum
acceptable QUAL score (default 20.0, valid range [0, 1_000_000]).
Raises
------
ValueError
If ``config.min_qual`` is outside [0, 1_000_000]. This is enforced by
``QualityFilterConfig.__post_init__`` at config construction time.
Examples
--------
>>> from vartriage.models.config import QualityFilterConfig
>>> from vartriage.models.variant import Variant
>>> cfg = QualityFilterConfig(min_qual=30.0)
>>> qf = QualityFilter(cfg)
>>> variants = [
... Variant(chrom="chr1", pos=100, id=None, ref="A", alt="T",
... qual=50.0, filter_status="PASS"),
... Variant(chrom="chr1", pos=200, id=None, ref="G", alt="C",
... qual=10.0, filter_status="PASS"),
... ]
>>> list(qf.apply(iter(variants))) # only first variant passes
[Variant(chrom='chr1', pos=100, ...)]
"""
def __init__(self, config: QualityFilterConfig | None = None) -> None:
if config is None:
config = QualityFilterConfig()
self._min_qual = config.min_qual
def apply(self, variants: Iterator[Variant]) -> Iterator[Variant]:
"""Filter variants by FILTER field and QUAL score.
Parameters
----------
variants : Iterator[Variant]
Input stream of variant records. May be empty.
Yields
------
Variant
Variants that pass both the FILTER and QUAL checks, in the same
relative order they appeared in the input.
Warns
-----
MissingDataWarning
When a variant has ``qual=None``. The warning message includes
the chromosome and position to aid debugging.
"""
min_qual = self._min_qual
for variant in variants:
if variant.filter_status not in _PASSING_FILTER_VALUES:
continue
if variant.qual is None:
reason = (
f"Missing QUAL score for variant at {variant.chrom}:{variant.pos}"
)
warning_data = MissingDataWarning(
chrom=variant.chrom,
pos=variant.pos,
ref=variant.ref,
alt=variant.alt,
source="QUAL",
reason=reason,
)
warnings.warn(
UserWarning(warning_data),
stacklevel=2,
)
continue
if variant.qual < min_qual:
continue
yield variant
|
apply(variants)
Filter variants by FILTER field and QUAL score.
Parameters
variants : Iterator[Variant]
Input stream of variant records. May be empty.
Yields
Variant
Variants that pass both the FILTER and QUAL checks, in the same
relative order they appeared in the input.
Warns
MissingDataWarning
When a variant has qual=None. The warning message includes
the chromosome and position to aid debugging.
Source code in vartriage/filter/quality_filter.py
| def apply(self, variants: Iterator[Variant]) -> Iterator[Variant]:
"""Filter variants by FILTER field and QUAL score.
Parameters
----------
variants : Iterator[Variant]
Input stream of variant records. May be empty.
Yields
------
Variant
Variants that pass both the FILTER and QUAL checks, in the same
relative order they appeared in the input.
Warns
-----
MissingDataWarning
When a variant has ``qual=None``. The warning message includes
the chromosome and position to aid debugging.
"""
min_qual = self._min_qual
for variant in variants:
if variant.filter_status not in _PASSING_FILTER_VALUES:
continue
if variant.qual is None:
reason = (
f"Missing QUAL score for variant at {variant.chrom}:{variant.pos}"
)
warning_data = MissingDataWarning(
chrom=variant.chrom,
pos=variant.pos,
ref=variant.ref,
alt=variant.alt,
source="QUAL",
reason=reason,
)
warnings.warn(
UserWarning(warning_data),
stacklevel=2,
)
continue
if variant.qual < min_qual:
continue
yield variant
|