From abb55d7e03bf207ebf00b4c71f1bbdd8f58a0ad3 Mon Sep 17 00:00:00 2001 From: Frederick Muriuki Muriithi Date: Mon, 12 Feb 2024 10:44:35 +0300 Subject: Check for errors in the 'phenose' file. --- qc_app/templates/rqtl2/rqtl2-qc-job-error.html | 8 ++++ qc_app/upload/rqtl2.py | 2 + r_qtl/r_qtl2_qc.py | 16 +++++++ scripts/qc_on_rqtl2_bundle.py | 59 ++++++++++++++++++-------- 4 files changed, 68 insertions(+), 17 deletions(-) diff --git a/qc_app/templates/rqtl2/rqtl2-qc-job-error.html b/qc_app/templates/rqtl2/rqtl2-qc-job-error.html index 1650a79..524282b 100644 --- a/qc_app/templates/rqtl2/rqtl2-qc-job-error.html +++ b/qc_app/templates/rqtl2/rqtl2-qc-job-error.html @@ -90,6 +90,14 @@ {{errors_table("tbl-errors-pheno", errorspheno[0:50])}} {%endif%} +{%if errorsphenose | length > 0%} +

Phenose Errors ({{errorsphenose | length}})

+
+ We found the following errors in the 'phenose' file in your R/qtl2 bundle: +
+{{errors_table("tbl-errors-phenose", errorsphenose[0:50])}} +{%endif%} + {%if errorsphenocovar | length > 0%}

Phenocovar Errors ({{errorsphenocovar | length}})

diff --git a/qc_app/upload/rqtl2.py b/qc_app/upload/rqtl2.py index c45952c..66b219d 100644 --- a/qc_app/upload/rqtl2.py +++ b/qc_app/upload/rqtl2.py @@ -211,6 +211,8 @@ def rqtl2_bundle_qc_status(jobid: UUID): thejob.get("errors-geno", "[]")), errorspheno=json.loads( thejob.get("errors-pheno", "[]")), + errorsphenose=json.loads( + thejob.get("errors-phenose", "[]")), errorsphenocovar=json.loads( thejob.get("errors-phenocovar", "[]")), messages=logmessages) diff --git a/r_qtl/r_qtl2_qc.py b/r_qtl/r_qtl2_qc.py index a41c442..f62f142 100644 --- a/r_qtl/r_qtl2_qc.py +++ b/r_qtl/r_qtl2_qc.py @@ -97,6 +97,22 @@ def pheno_errors(zfile: ZipFile) -> Iterator[Union[InvalidValue, MissingFile]]: zfile, "pheno", (__min_3_decimal_places__,)) if error is not None) +def phenose_errors(zfile: ZipFile) -> Iterator[Union[InvalidValue, MissingFile]]: + """Check for and retrieve phenose errors.""" + def __min_6_decimal_places__( + lineno: int, field: str, value: str) -> Optional[InvalidValue]: + if not (re.search(r"^([0-9]+\.[0-9]{6,}|[0-9]+\.?0*)$", value) + or re.search(r"^0\.0+$", value) + or re.search("^0+$", value)): + return InvalidValue(lineno, field, value, ( + f"Invalid value '{value}'. Expected numerical value " + "with at least 6 decimal places.")) + return None + return ( + error for error in retrieve_errors( + zfile, "phenose", (__min_6_decimal_places__,)) + if error is not None) + def retrieve_errors(zfile: ZipFile, filetype: str, checkers: tuple[Callable]) -> Iterator[ Union[InvalidValue, MissingFile]]: """Check for and retrieve errors from files of type `filetype`.""" diff --git a/scripts/qc_on_rqtl2_bundle.py b/scripts/qc_on_rqtl2_bundle.py index aea1baa..c3e8b66 100644 --- a/scripts/qc_on_rqtl2_bundle.py +++ b/scripts/qc_on_rqtl2_bundle.py @@ -14,6 +14,7 @@ from qc_app import jobs from qc_app.db_utils import database_connection from qc_app.check_connections import check_db, check_redis +from r_qtl import r_qtl2 as rqtl2 from r_qtl import r_qtl2_qc as rqc from r_qtl import fileerrors as rqfe @@ -59,31 +60,54 @@ def qc_missing_files(rconn: Redis, def qc_geno_errors(rconn, fqjobid, zfile, logger) -> bool: """Check for errors in `geno` file(s).""" logger.info("Checking for errors in the 'geno' file…") - gerrs = tuple(rqc.geno_errors(zfile)) - add_to_errors(rconn, fqjobid, "errors-generic", tuple( - err for err in gerrs if isinstance(err, rqfe.MissingFile))) - add_to_errors(rconn, fqjobid, "errors-geno", tuple( - err for err in gerrs if not isinstance(err, rqfe.MissingFile))) - if len(gerrs) > 0: - logger.error("The 'geno' file has errors.") - return True + cdata = rqtl2.control_data(zfile) + if "geno" in cdata: + gerrs = tuple(rqc.geno_errors(zfile)) + add_to_errors(rconn, fqjobid, "errors-generic", tuple( + err for err in gerrs if isinstance(err, rqfe.MissingFile))) + add_to_errors(rconn, fqjobid, "errors-geno", tuple( + err for err in gerrs if not isinstance(err, rqfe.MissingFile))) + if len(gerrs) > 0: + logger.error("The 'geno' file has errors.") + return True + logger.info("No errors found in the 'geno' file.") return False def qc_pheno_errors(rconn, fqjobid, zfile, logger) -> bool: """Check for errors in `pheno` file(s).""" - logger.info("Checking for errors in the 'pheno' file …") - perrs = tuple(rqc.pheno_errors(zfile)) - add_to_errors(rconn, fqjobid, "errors-generic", tuple( - err for err in perrs if isinstance(err, rqfe.MissingFile))) - add_to_errors(rconn, fqjobid, "errors-pheno", tuple( - err for err in perrs if not isinstance(err, rqfe.MissingFile))) - if len(perrs) > 0: - logger.error("The 'pheno' file has errors.") - return True + logger.info("Checking for errors in the 'pheno' file…") + cdata = rqtl2.control_data(zfile) + if "pheno" in cdata: + perrs = tuple(rqc.pheno_errors(zfile)) + add_to_errors(rconn, fqjobid, "errors-generic", tuple( + err for err in perrs if isinstance(err, rqfe.MissingFile))) + add_to_errors(rconn, fqjobid, "errors-pheno", tuple( + err for err in perrs if not isinstance(err, rqfe.MissingFile))) + if len(perrs) > 0: + logger.error("The 'pheno' file has errors.") + return True + logger.info("No errors found in the 'pheno' file.") return False +def qc_phenose_errors(rconn, fqjobid, zfile, logger) -> bool: + """Check for errors in `phenose` file(s).""" + logger.info("Checking for errors in the 'phenose' file…") + cdata = rqtl2.control_data(zfile) + if "phenose" in cdata: + perrs = tuple(rqc.phenose_errors(zfile)) + add_to_errors(rconn, fqjobid, "errors-generic", tuple( + err for err in perrs if isinstance(err, rqfe.MissingFile))) + add_to_errors(rconn, fqjobid, "errors-phenose", tuple( + err for err in perrs if not isinstance(err, rqfe.MissingFile))) + if len(perrs) > 0: + logger.error("The 'phenose' file has errors.") + return True + + logger.info("No errors found in the 'phenose' file.") + return False + def qc_phenocovar_errors(_rconn, _fqjobid, _zfile, _logger) -> bool: """Check for errors in `phenocovar` file(s).""" return False @@ -104,6 +128,7 @@ def run_qc(rconn: Redis, 1 if any(( qc_geno_errors(rconn, fqjobid, zfile, logger), qc_pheno_errors(rconn, fqjobid, zfile, logger), + qc_phenose_errors(rconn, fqjobid, zfile, logger), qc_phenocovar_errors(rconn, fqjobid, zfile, logger))) else 0) -- cgit v1.2.3