Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-21 07:54:29

0001 #!/usr/bin/env python3
0002 """Validate that simg4ox saves run-wide hit arrays for a multi-event run."""
0003 
0004 import argparse
0005 import re
0006 from pathlib import Path
0007 
0008 import numpy as np
0009 
0010 
0011 EVENT_PATTERNS = {
0012     "GPU": re.compile(r"Collected GPU hits:\s*(\d+)"),
0013     "G4": re.compile(r"Collected G4\s+hits:\s*(\d+)"),
0014 }
0015 TOTAL_PATTERNS = {
0016     "GPU": re.compile(r"Total GPU hits:\s*(\d+)"),
0017     "G4": re.compile(r"Total G4\s+hits:\s*(\d+)"),
0018 }
0019 
0020 
0021 def parse_counts(log_text, label, events):
0022     event_counts = [int(value) for value in EVENT_PATTERNS[label].findall(log_text)]
0023     total_matches = TOTAL_PATTERNS[label].findall(log_text)
0024 
0025     if len(event_counts) != events:
0026         raise AssertionError(f"Expected {events} {label} event counts, found {len(event_counts)}")
0027     if len(total_matches) != 1:
0028         raise AssertionError(f"Expected one {label} run total, found {len(total_matches)}")
0029 
0030     total = int(total_matches[0])
0031     if total != sum(event_counts):
0032         raise AssertionError(f"{label} run total {total} != per-event sum {sum(event_counts)}")
0033     if total == 0:
0034         raise AssertionError(f"Expected non-empty {label} hits")
0035 
0036     return event_counts, total
0037 
0038 
0039 def check_array(path, expected_rows):
0040     if not path.is_file():
0041         raise FileNotFoundError(f"Missing run hit array: {path}")
0042 
0043     hits = np.load(path)
0044     expected_shape = (expected_rows, 4, 4)
0045     if hits.shape != expected_shape:
0046         raise AssertionError(f"{path.name} shape {hits.shape} != {expected_shape}")
0047     if hits.dtype != np.float32:
0048         raise AssertionError(f"{path.name} dtype {hits.dtype} != float32")
0049 
0050     return hits
0051 
0052 
0053 def main():
0054     parser = argparse.ArgumentParser(description=__doc__)
0055     parser.add_argument("--log", type=Path, required=True)
0056     parser.add_argument("--output-dir", type=Path, required=True)
0057     parser.add_argument("--events", type=int, default=5)
0058     args = parser.parse_args()
0059 
0060     log_text = args.log.read_text()
0061     gpu_event_counts, gpu_total = parse_counts(log_text, "GPU", args.events)
0062     g4_event_counts, g4_total = parse_counts(log_text, "G4", args.events)
0063 
0064     gpu_hits = check_array(args.output_dir / "s_hits.npy", gpu_total)
0065     g4_hits = check_array(args.output_dir / "g_hits.npy", g4_total)
0066 
0067     print(f"GPU_EVENT_COUNTS={gpu_event_counts}")
0068     print(f"G4_EVENT_COUNTS={g4_event_counts}")
0069     print(f"S_HITS_SHAPE={gpu_hits.shape}")
0070     print(f"G_HITS_SHAPE={g4_hits.shape}")
0071 
0072 
0073 if __name__ == "__main__":
0074     main()