Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:30:18 +08:00
commit 74bee324ab
335 changed files with 147377 additions and 0 deletions

View File

@@ -0,0 +1,103 @@
#!/usr/bin/env python3
"""
Format adverse event data into tables for clinical trial reports.
Converts CSV or structured data into formatted AE summary tables.
Usage:
python format_adverse_events.py <ae_data.csv>
"""
import argparse
import csv
from collections import defaultdict
from pathlib import Path
def format_ae_summary_table(data: list) -> str:
"""Generate AE summary table in markdown format."""
# Group by treatment arm
arm_stats = defaultdict(lambda: {
'total': 0,
'any_ae': 0,
'related_ae': 0,
'sae': 0,
'deaths': 0,
'discontinuations': 0
})
for row in data:
arm = row.get('treatment_arm', 'Unknown')
arm_stats[arm]['total'] += 1
if row.get('any_ae', '').lower() == 'yes':
arm_stats[arm]['any_ae'] += 1
if row.get('related', '').lower() == 'yes':
arm_stats[arm]['related_ae'] += 1
if row.get('serious', '').lower() == 'yes':
arm_stats[arm]['sae'] += 1
if row.get('fatal', '').lower() == 'yes':
arm_stats[arm]['deaths'] += 1
if row.get('discontinuation', '').lower() == 'yes':
arm_stats[arm]['discontinuations'] += 1
# Generate table
table = "| Category | " + " | ".join(arm_stats.keys()) + " |\n"
table += "|----------|" + "|".join(["--------"] * len(arm_stats)) + "|\n"
categories = [
('Total N', 'total'),
('Any AE', 'any_ae'),
('Treatment-related AE', 'related_ae'),
('Serious AE', 'sae'),
('Deaths', 'deaths'),
('Discontinuation due to AE', 'discontinuations')
]
for cat_name, cat_key in categories:
row_data = [cat_name]
for arm_data in arm_stats.values():
count = arm_data[cat_key]
total = arm_data['total']
pct = (count / total * 100) if total > 0 and cat_key != 'total' else 0
value = f"{count}" if cat_key == 'total' else f"{count} ({pct:.1f}%)"
row_data.append(value)
table += "| " + " | ".join(row_data) + " |\n"
return table
def main():
"""Main entry point."""
parser = argparse.ArgumentParser(description="Format AE data into tables")
parser.add_argument("input_file", help="Path to AE data CSV")
parser.add_argument("--output", "-o", help="Output markdown file")
args = parser.parse_args()
try:
with open(args.input_file, 'r') as f:
reader = csv.DictReader(f)
data = list(reader)
table = format_ae_summary_table(data)
if args.output:
with open(args.output, 'w') as f:
f.write(table)
print(f"✓ Table saved to: {args.output}")
else:
print("\nAdverse Events Summary Table:\n")
print(table)
return 0
except Exception as e:
print(f"Error: {e}")
return 1
if __name__ == "__main__":
import sys
sys.exit(main())