Skip to content

Commit

Permalink
Validate mapped rate
Browse files Browse the repository at this point in the history
  • Loading branch information
seallard committed Dec 11, 2023
1 parent 09830e6 commit 0c3aa9b
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 3 deletions.
1 change: 1 addition & 0 deletions cg/constants/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ class APIMethods(StrEnum):
class MicrosaltQC:
QC_PERCENT_THRESHOLD_MWX: float = 0.1
COVERAGE_10X_THRESHOLD: float = 0.75
MAPPED_RATE_THRESHOLD: float = 0.3
NEGATIVE_CONTROL_READS_THRESHOLD: float = 0.2
TARGET_READS: int = 6000000
TARGET_READS_FAIL_THRESHOLD: float = 0.7
Expand Down
10 changes: 8 additions & 2 deletions cg/meta/workflow/microsalt/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class MicrosaltSamtoolsStats(BaseModel):
coverage_100x: float


class Sample(BaseModel):
class SampleMetrics(BaseModel):
blast_pubmlst: BlastPubmlst
quast_assembly: QuastAssembly
blast_resfinder_resistence: List[str]
Expand All @@ -38,4 +38,10 @@ class Sample(BaseModel):


class QualityMetrics(BaseModel):
samples: Dict[str, Sample]
samples: Dict[str, SampleMetrics]


class QualityResult(BaseModel):
sample_id: str
passed: bool
fail_message: str | None = None
33 changes: 32 additions & 1 deletion cg/meta/workflow/microsalt/quality_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
from cg.io.json import read_json, write_json

from cg.constants.constants import MicrosaltAppTags, MicrosaltQC
from cg.meta.workflow.microsalt.utils import is_valid_total_reads, is_valid_total_reads_for_control
from cg.meta.workflow.microsalt.models import QualityMetrics, QualityResult, SampleMetrics
from cg.meta.workflow.microsalt.utils import (
is_valid_mapped_rate,
is_valid_total_reads,
is_valid_total_reads_for_control,
parse_quality_metrics,
)
from cg.models.orders.sample_base import ControlEnum
from cg.store.api.core import Store
from cg.store.models import Sample
Expand All @@ -16,6 +22,27 @@ class QualityChecker:
def __init__(self, status_db: Store):
self.status_db = status_db

def quality_control(self, run_dir_path: Path, lims_project: str):
metrics_file_path: Path = Path(run_dir_path, f"{lims_project}.json")
quality_metrics: QualityMetrics = parse_quality_metrics(metrics_file_path)

sample_results: list[QualityResult] = []

for sample_metrics in quality_metrics:
result = self.quality_control_sample(sample_metrics)
sample_results.append(result)

self.quality_control_case(sample_results)

def quality_control_sample(
self, sample_id: str, sample_metrics: SampleMetrics
) -> QualityResult:
reads_passes_qc: bool = self.is_valid_total_reads(sample_id)
mapped_rate_passes_qc: bool = self.is_valid_mapped_rate(sample_metrics)

def quality_control_case(self, sample_results: list[QualityResult]) -> bool:
pass

def microsalt_qc(self, case_id: str, run_dir_path: Path, lims_project: str) -> bool:
"""Check if given microSALT case passes QC check."""
failed_samples: dict = {}
Expand Down Expand Up @@ -131,3 +158,7 @@ def is_valid_total_reads(self, sample_id: str) -> bool:
sample_reads=sample_reads, target_reads=target_reads
)
return is_valid_total_reads(sample_reads=sample_reads, target_reads=target_reads)

def is_valid_mapped_rate(self, metrics: SampleMetrics) -> bool:
mapped_rate: float = metrics.microsalt_samtools_stats.mapped_rate
return is_valid_mapped_rate(mapped_rate)
13 changes: 13 additions & 0 deletions cg/meta/workflow/microsalt/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from pathlib import Path

from cg.constants.constants import MicrosaltQC
from cg.io.json import read_json
from cg.meta.workflow.microsalt.models import QualityMetrics


def is_valid_total_reads(sample_reads: int, target_reads: int) -> bool:
Expand All @@ -7,3 +11,12 @@ def is_valid_total_reads(sample_reads: int, target_reads: int) -> bool:

def is_valid_total_reads_for_control(sample_reads: int, target_reads: int) -> bool:
return sample_reads < target_reads * MicrosaltQC.NEGATIVE_CONTROL_READS_THRESHOLD


def is_valid_mapped_rate(sample_mapped_rate: float) -> bool:
return sample_mapped_rate > MicrosaltQC.MAPPED_RATE_THRESHOLD


def parse_quality_metrics(file_path: Path) -> QualityMetrics:
data = read_json(file_path)
return QualityMetrics.model_validate_json(data)

0 comments on commit 0c3aa9b

Please sign in to comment.