Download scripts/run_rqmodified.py from Qianhui19/iHARP: direct link, hf CLI and curl.
- Browser
- Download file 5.48 kB
-
https://huggingface.co/Qianhui19/iHARP/resolve/main/scripts/run_rqmodified.py
- Command line
-
hf download hf://Qianhui19/iHARP/scripts/run_rqmodified.py
-
curl -L -o run_rqmodified.py https://huggingface.co/Qianhui19/iHARP/resolve/main/scripts/run_rqmodified.py
5.48 kB
| #!/usr/bin/env python3 | |
| """iHARP ER/AhR RQmodified deterministic calculation entry point (self-contained, runnable standalone). | |
| Does not depend on the project-root core/ engine; directly calls the self-contained | |
| calculation modules `er_rqmodified.py` / `ahr_rqmodified.py` in the same directory. | |
| Usage: | |
| python run_rqmodified.py --pathway er --input <endpoint_details.csv> \ | |
| [--reference <reference.csv>] [--output-dir <output_dir>] | |
| python run_rqmodified.py --pathway ahr --input <endpoint_details.csv> \ | |
| [--reference <reference.csv>] [--output-dir <output_dir>] | |
| If --reference is not passed, the reference files bundled under assets/ are used by default: | |
| assets/er_reference_endpoint_details.csv | |
| assets/ahr_reference_endpoint_details.csv | |
| Output files (written to output-dir, default current directory): | |
| <pathway>_detail.csv -- compound-level detail results | |
| <pathway>_summary.csv -- SUM_RQmodified aggregate | |
| <pathway>_warnings.txt -- warning log | |
| stdout prints a JSON summary for upstream auditing. | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import csv | |
| import json | |
| import sys | |
| from pathlib import Path | |
| from typing import Any | |
| # self-contained calculation modules in the same directory | |
| import ahr_rqmodified | |
| import er_rqmodified | |
| RULE_VERSION = "iharp_skill_v1" | |
| # reference files bundled with this skill (relative to this script -> skill root -> assets) | |
| _ASSETS_DIR = Path(__file__).resolve().parent.parent / "assets" | |
| DEFAULT_ER_REFERENCE = _ASSETS_DIR / "er_reference_endpoint_details.csv" | |
| DEFAULT_AHR_REFERENCE = _ASSETS_DIR / "ahr_reference_endpoint_details.csv" | |
| def format_number(value: float) -> str: | |
| if abs(value) < 1e-15: | |
| value = 0.0 | |
| return f"{value:.12g}" | |
| def format_value(value: Any) -> str: | |
| if value is None: | |
| return "" | |
| if isinstance(value, str): | |
| return value | |
| if isinstance(value, (int, float)): | |
| return format_number(float(value)) | |
| return str(value) | |
| def write_csv(path: Path, rows: list[dict[str, Any]], columns: list[str]) -> None: | |
| with path.open("w", newline="", encoding="utf-8") as f: | |
| writer = csv.DictWriter(f, fieldnames=columns) | |
| writer.writeheader() | |
| for row in rows: | |
| writer.writerow({col: format_value(row.get(col)) for col in columns}) | |
| def _emit_error(message: str) -> int: | |
| print(json.dumps({"ok": False, "error": message}, ensure_ascii=False)) | |
| return 1 | |
| def main() -> int: | |
| parser = argparse.ArgumentParser( | |
| description="iHARP ER/AhR RQmodified calculation entry point (self-contained)" | |
| ) | |
| parser.add_argument("--pathway", required=True, choices=["er", "ahr"], help="pathway (er or ahr)") | |
| parser.add_argument("--input", required=True, help="endpoint details CSV path") | |
| parser.add_argument("--reference", help="reference endpoint CSV path; defaults to the bundled assets/ file") | |
| parser.add_argument("--output-dir", default=".", help="output directory (default current directory)") | |
| parser.add_argument("--pnec-e2", type=float, default=er_rqmodified.DEFAULT_PNEC_E2) | |
| parser.add_argument("--pnec-4oht", type=float, default=er_rqmodified.DEFAULT_PNEC_4OHT) | |
| parser.add_argument("--pnec-k", type=float, default=ahr_rqmodified.DEFAULT_PNEC_K) | |
| args = parser.parse_args() | |
| input_path = Path(args.input) | |
| if not input_path.is_file(): | |
| return _emit_error(f"input file not found: {input_path}") | |
| if args.reference: | |
| reference_path = Path(args.reference) | |
| elif args.pathway == "er": | |
| reference_path = DEFAULT_ER_REFERENCE | |
| else: | |
| reference_path = DEFAULT_AHR_REFERENCE | |
| if not reference_path.is_file(): | |
| return _emit_error(f"reference file not found: {reference_path}") | |
| output_dir = Path(args.output_dir) | |
| output_dir.mkdir(parents=True, exist_ok=True) | |
| if args.pathway == "er": | |
| rows, warnings, totals = er_rqmodified.calculate_rqmodified( | |
| er_rqmodified.read_csv(input_path), | |
| er_rqmodified.read_csv(reference_path), | |
| pnec_e2=args.pnec_e2, | |
| pnec_4oht=args.pnec_4oht, | |
| ) | |
| detail_columns = er_rqmodified.DETAIL_COLUMNS | |
| summary_columns = er_rqmodified.SUMMARY_COLUMNS | |
| else: | |
| rows, warnings, totals = ahr_rqmodified.calculate_ahrrqmodified( | |
| ahr_rqmodified.read_csv(input_path), | |
| ahr_rqmodified.read_csv(reference_path), | |
| pnec_k=args.pnec_k, | |
| ) | |
| detail_columns = ahr_rqmodified.DETAIL_COLUMNS | |
| summary_columns = ahr_rqmodified.SUMMARY_COLUMNS | |
| detail_path = output_dir / f"{args.pathway}_detail.csv" | |
| summary_path = output_dir / f"{args.pathway}_summary.csv" | |
| warning_path = output_dir / f"{args.pathway}_warnings.txt" | |
| write_csv(detail_path, rows, detail_columns) | |
| write_csv(summary_path, [{col: totals.get(col) for col in summary_columns}], summary_columns) | |
| warning_path.write_text("\n".join(warnings) + ("\n" if warnings else ""), encoding="utf-8") | |
| summary_out = { | |
| "ok": True, | |
| "pathway": args.pathway.upper(), | |
| "rule_version": RULE_VERSION, | |
| "files": { | |
| "detail": str(detail_path), | |
| "summary": str(summary_path), | |
| "warnings": str(warning_path), | |
| }, | |
| "totals": totals, | |
| "warning_count": len(warnings), | |
| } | |
| print(json.dumps(summary_out, ensure_ascii=False, indent=2)) | |
| return 0 | |
| if __name__ == "__main__": | |
| raise SystemExit(main()) | |