Skip to content
Draft
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
102 changes: 102 additions & 0 deletions .github/scripts/filter_core_ids_by_standard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env python3
"""Filter Published CORE rule IDs by Authorities.Standards.Name."""

from __future__ import annotations

import argparse
import sys
from pathlib import Path

import yaml


def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Return space-separated CORE IDs for Published rules matching standards."
)
parser.add_argument(
"--rules-root",
required=True,
help="Repository root containing Published/",
)
parser.add_argument(
"--standards",
nargs="+",
required=True,
help="Standards to match from Authorities[].Standards[].Name",
)
parser.add_argument(
"--core-ids",
default="",
help="Optional space-separated CORE IDs to intersect with the standard filter.",
)
return parser.parse_args()


def iter_published_rule_files(rules_root: Path) -> list[Path]:
published_dir = rules_root / "Published"
files: list[Path] = []
for pattern in ("**/rule.yml", "**/rule.yaml"):
files.extend(published_dir.glob(pattern))
return sorted(set(files))


def rule_matches_standard(rule: dict, target_standards: set[str]) -> bool:
for authority in rule.get("Authorities") or []:
if not isinstance(authority, dict):
continue
for standard in authority.get("Standards") or []:
if not isinstance(standard, dict):
continue
standard_name = str(standard.get("Name") or "").strip().upper()
if standard_name in target_standards:
return True
return False


def collect_filtered_core_ids(rules_root: Path, standards: list[str]) -> list[str]:
target_standards = {name.strip().upper() for name in standards if name.strip()}
core_ids: list[str] = []

for rule_file in iter_published_rule_files(rules_root):
with rule_file.open("r", encoding="utf-8") as handle:
rule = yaml.safe_load(handle) or {}
if not isinstance(rule, dict):
continue
if not rule_matches_standard(rule, target_standards):
continue

core = rule.get("Core") or {}
if not isinstance(core, dict):
continue
core_id = str(core.get("Id") or "").strip()
if core_id:
core_ids.append(core_id)
return core_ids


def intersect_with_requested(core_ids: list[str], requested_core_ids: str) -> list[str]:
requested = requested_core_ids.split()
if not requested:
return core_ids

allowed = set(core_ids)
return [core_id for core_id in requested if core_id in allowed]


def main() -> int:
args = parse_args()
rules_root = Path(args.rules_root)
if not rules_root.is_dir():
print(f"rules-root does not exist: {rules_root}", file=sys.stderr)
return 1

filtered_core_ids = collect_filtered_core_ids(rules_root, args.standards)
output_core_ids = intersect_with_requested(filtered_core_ids, args.core_ids)
print(" ".join(filtered_core_ids))
print(" ".join(output_core_ids))
return 0


if __name__ == "__main__":
raise SystemExit(main())
28 changes: 23 additions & 5 deletions .github/workflows/update-published-results.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,20 +79,38 @@ jobs:
run: venv/bin/pip install tabulate jmespath pyyaml ruamel.yaml

# -----------------------------------------------------------------------
# 4. Run the engine for every Published rule, writing actual results.csv
# directly into each case's results/ directory (overwriting the old baseline)
# 4. Run the engine for Published rules filtered by Authorities.Standards.Name,
# writing actual results.csv directly into each case's results/ directory
# (overwriting the old baseline)
# -----------------------------------------------------------------------
- name: Run engine and write results
id: run_engine
continue-on-error: true
run: |
chmod +x .github/scripts/run_validation.sh
FILTER_STANDARDS=("USDM" "TIG")
mapfile -t FILTER_RESULT < <(venv/bin/python .github/scripts/filter_core_ids_by_standard.py \
--rules-root "$(pwd)" \
--standards "${FILTER_STANDARDS[@]}" \
--core-ids "${{ inputs.core_ids }}")
FILTERED_CORE_IDS="${FILTER_RESULT[0]}"
CORE_IDS_TO_RUN="${FILTER_RESULT[1]}"

if [ -z "$FILTERED_CORE_IDS" ]; then
echo "No Published rules found for standards: ${FILTER_STANDARDS[*]}"
exit 0
fi

CORE_IDS_ARG=""
if [ -n "${{ inputs.core_ids }}" ]; then
CORE_IDS_ARG="--core-ids ${{ inputs.core_ids }}"
if [ -z "$CORE_IDS_TO_RUN" ]; then
echo "No requested core_ids matched Published rules for standards: ${FILTER_STANDARDS[*]}"
exit 0
fi

echo "Running validation for standards: ${FILTER_STANDARDS[*]}"
echo "Rule count: $(echo "$CORE_IDS_TO_RUN" | wc -w | tr -d ' ')"

CORE_IDS_ARG="--core-ids $CORE_IDS_TO_RUN"

ENGINE_DIR_OVERRIDE="$(pwd)/engine" \
venv/bin/python engine/scripts/validate_published_rules.py \
--rules-root "$(pwd)" \
Expand Down
2 changes: 0 additions & 2 deletions Published/CORE-000007/negative/01/results/results.csv
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
Dataset,Record,Variable,Value
DM,3,DTHDTC,2018-06-10
DM,3,DTHFL,
DM,3,USUBJID,015246-099-0000-00002
DM,4,DTHDTC,2018-09-04
DM,4,DTHFL,N
DM,4,USUBJID,015246-099-0000-00003
4 changes: 2 additions & 2 deletions Published/CORE-000007/negative/02/results/results.csv
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Dataset,Record,Variable,Value
DM,4,DTHDTC,2018-12-11
DM,4,DTHFL,
DM,3,DTHDTC,2018-12-11
DM,3,DTHFL,
14 changes: 1 addition & 13 deletions Published/CORE-000013/negative/01/results/results.csv
Original file line number Diff line number Diff line change
@@ -1,14 +1,2 @@
Dataset,Record,Variable,Value
AE,1,AESTAT,NOT DONE
AE,2,AESTAT,NOT DONE
AE,3,AESTAT,NOT DONE
AE,4,AESTAT,NOT DONE
AE,5,AESTAT,
AE,6,AESTAT,
AE,7,AESTAT,NOT DONE
AE,8,AESTAT,
AE,9,AESTAT,
AE,10,AESTAT,
AE,11,AESTAT,NOT DONE
AE,12,AESTAT,
AE,13,AESTAT,
AE,,AESTAT,NOT DONE
14 changes: 1 addition & 13 deletions Published/CORE-000013/negative/02/results/results.csv
Original file line number Diff line number Diff line change
@@ -1,14 +1,2 @@
Dataset,Record,Variable,Value
AE,1,AESTAT,
AE,2,AESTAT,
AE,3,AESTAT,
AE,4,AESTAT,
AE,5,AESTAT,
AE,6,AESTAT,
AE,7,AESTAT,NOT DONE
AE,8,AESTAT,
AE,9,AESTAT,
AE,10,AESTAT,
AE,11,AESTAT,
AE,12,AESTAT,
AE,13,AESTAT,
AE,,AESTAT,
2 changes: 2 additions & 0 deletions Published/CORE-000014/negative/01/results/results.csv
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,10 @@ EC,1,ECPRESP,
EC,1,ECSTAT,Not in dataset
EC,2,ECOCCUR,N
EC,2,ECPRESP,
EC,2,ECSTAT,Not in dataset
EC,3,ECOCCUR,Y
EC,3,ECPRESP,
EC,3,ECSTAT,Not in dataset
HO,1,HOOCCUR,Y
HO,1,HOPRESP,
HO,1,HOSTAT,
Expand Down
3 changes: 0 additions & 3 deletions Published/CORE-000014/positive/02/results/results.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
Dataset,Record,Variable,Value
SU,1,SUOCCUR,
SU,1,SUPRESP,N
SU,1,SUSTAT,NOT DONE
65 changes: 20 additions & 45 deletions Published/CORE-000015/negative/01/results/results.csv
Original file line number Diff line number Diff line change
@@ -1,46 +1,21 @@
Dataset,Record,Variable,Value
AG,1,AGOCCUR,
AG,1,AGPRESP,Not in dataset
AG,2,AGOCCUR,
AG,3,AGOCCUR,
BE,1,BEOCCUR,
BE,1,BEPRESP,Not in dataset
BE,2,BEOCCUR,
BE,3,BEOCCUR,
BE,4,BEOCCUR,
CE,1,CEOCCUR,
CE,1,CEPRESP,Not in dataset
CE,2,CEOCCUR,
CE,3,CEOCCUR,
CE,4,CEOCCUR,
CM,1,CMOCCUR,
CM,1,CMPRESP,Not in dataset
CM,2,CMOCCUR,
CM,3,CMOCCUR,
EC,1,ECOCCUR,
EC,1,ECPRESP,Not in dataset
EC,2,ECOCCUR,
EC,3,ECOCCUR,
EC,4,ECOCCUR,
HO,1,HOOCCUR,
HO,1,HOPRESP,Not in dataset
HO,2,HOOCCUR,
HO,3,HOOCCUR,
HO,4,HOOCCUR,
MH,1,MHOCCUR,
MH,1,MHPRESP,Not in dataset
MH,2,MHOCCUR,
MH,3,MHOCCUR,
MH,4,MHOCCUR,
ML,1,MLOCCUR,
ML,1,MLPRESP,Not in dataset
ML,2,MLOCCUR,
ML,3,MLOCCUR,
PR,1,PROCCUR,
PR,1,PRPRESP,Not in dataset
PR,2,PROCCUR,
PR,3,PROCCUR,
SU,1,SUOCCUR,
SU,1,SUPRESP,Not in dataset
SU,2,SUOCCUR,
SU,3,SUOCCUR,
AG,,AGOCCUR,
AG,,AGPRESP,Not in dataset
BE,,BEOCCUR,
BE,,BEPRESP,Not in dataset
CE,,CEOCCUR,
CE,,CEPRESP,Not in dataset
CM,,CMOCCUR,
CM,,CMPRESP,Not in dataset
EC,,ECOCCUR,
EC,,ECPRESP,Not in dataset
HO,,HOOCCUR,
HO,,HOPRESP,Not in dataset
MH,,MHOCCUR,
MH,,MHPRESP,Not in dataset
ML,,MLOCCUR,
ML,,MLPRESP,Not in dataset
PR,,PROCCUR,
PR,,PRPRESP,Not in dataset
SU,,SUOCCUR,
SU,,SUPRESP,Not in dataset
65 changes: 65 additions & 0 deletions Published/CORE-000016/negative/03/results/results.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
Dataset,Record,Variable,Value
AG,1,AGOCCUR,Y
AG,1,AGPRESP,Not in dataset
AG,2,AGOCCUR,N
AG,2,AGPRESP,Not in dataset
AG,3,AGOCCUR,Y
AG,3,AGPRESP,Not in dataset
BE,1,BEOCCUR,Y
BE,1,BEPRESP,
BE,2,BEOCCUR,N
BE,2,BEPRESP,
BE,3,BEOCCUR,Y
BE,3,BEPRESP,
BE,4,BEOCCUR,N
BE,4,BEPRESP,
CE,1,CEOCCUR,Y
CE,1,CEPRESP,
CE,2,CEOCCUR,Y
CE,2,CEPRESP,
CE,3,CEOCCUR,Y
CE,3,CEPRESP,
CE,4,CEOCCUR,N
CE,4,CEPRESP,
CM,3,CMOCCUR,Y
CM,3,CMPRESP,
EC,1,ECOCCUR,Y
EC,1,ECPRESP,
EC,2,ECOCCUR,N
EC,2,ECPRESP,
EC,3,ECOCCUR,Y
EC,3,ECPRESP,
HO,1,HOOCCUR,Y
HO,1,HOPRESP,
HO,2,HOOCCUR,Y
HO,2,HOPRESP,
HO,3,HOOCCUR,Y
HO,3,HOPRESP,
HO,4,HOOCCUR,N
HO,4,HOPRESP,
MH,1,MHOCCUR,Y
MH,1,MHPRESP,
MH,2,MHOCCUR,Y
MH,2,MHPRESP,
MH,3,MHOCCUR,Y
MH,3,MHPRESP,
MH,4,MHOCCUR,N
MH,4,MHPRESP,
ML,1,MLOCCUR,Y
ML,1,MLPRESP,
ML,2,MLOCCUR,N
ML,2,MLPRESP,
ML,3,MLOCCUR,Y
ML,3,MLPRESP,
PR,1,PROCCUR,Y
PR,1,PRPRESP,
PR,2,PROCCUR,N
PR,2,PRPRESP,
PR,3,PROCCUR,Y
PR,3,PRPRESP,
SU,1,SUOCCUR,Y
SU,1,SUPRESP,
SU,2,SUOCCUR,N
SU,2,SUPRESP,
SU,3,SUOCCUR,N
SU,3,SUPRESP,
1 change: 0 additions & 1 deletion Published/CORE-000016/positive/03/results/results.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
Dataset,Record,Variable,Value
EC,,,
1 change: 0 additions & 1 deletion Published/CORE-000017/positive/02/results/results.csv
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
Dataset,Record,Variable,Value
CO,,,
Loading
Loading