9  CM Summary

Objectives

This guide demonstrates Concomitant Medications (CM) summary analysis.

9.1 Setup

import os
import sys
import polars as pl
from pathlib import Path

sys.path.insert(0, 'src')

from rtflite import LibreOfficeConverter
try:
    converter = LibreOfficeConverter()
except Exception:
    converter = None
    print("WARNING: LibreOffice not found. PDF conversion will be skipped.")

from csrlite import load_plan, study_plan_to_cm_summary
from csrlite.cm.cm_summary import cm_summary

9.2 Concomitant Medications Summary

Summarizes the number and percentage of participants with concomitant medications.

9.3 StudyPlan-Driven Workflow

study_plan = load_plan("studies/xyz123/yaml/plan_xyz123.yaml")
study_plan.get_plan_df().filter(pl.col("analysis") == "cm_summary")
2026-02-03 15:27:07,200 - csrlite.common.plan - INFO - Successfully loaded dataset 'adsl' from 'studies/xyz123/yaml/../../../data/adsl.parquet'
2026-02-03 15:27:07,203 - csrlite.common.plan - INFO - Successfully loaded dataset 'adae' from 'studies/xyz123/yaml/../../../data/adae.parquet'
2026-02-03 15:27:07,204 - csrlite.common.plan - INFO - Successfully loaded dataset 'adie' from 'studies/xyz123/yaml/../../../data/adie.parquet'
2026-02-03 15:27:07,206 - csrlite.common.plan - INFO - Successfully loaded dataset 'adpd' from 'studies/xyz123/yaml/../../../data/adpd.parquet'
shape: (0, 5)
analysis population observation parameter group
str str str str str
output_files = study_plan_to_cm_summary(study_plan)

9.4 Complete Pipeline

# Load data
data_path = Path("data") if Path("data").exists() else Path("../data")
adsl = pl.read_parquet(data_path / "adsl.parquet")
adcm = pl.read_parquet(data_path / "adcm.parquet")

# Define output path for summary
output_summary_rtf = "studies/xyz123/rtf/cm_summary_saffl_cm_ontrt.rtf"
# Ensure directory exists
Path(output_summary_rtf).parent.mkdir(parents=True, exist_ok=True)

summary_path = cm_summary(
    population=adsl,
    observation=adcm,
    population_filter="SAFFL = 'Y'",
    observation_filter="CONFL = 'Y'", # On-treatment
    id=("USUBJID", "Subject ID"),
    group=("TRT01A", "Treatment"),
    variables=[
        ("1=1", "Participants with one or more medications")
    ],
    title=[
        "Summary of Concomitant Medications",
        "(Safety Population)"
    ],
    footnote=["Every participant is counted a single time for each applicable row and column."],
    source=["Source: ADSL and ADCM datasets"],
    output_file=output_summary_rtf,
)
print(f"Generated: {summary_path}")
studies/xyz123/rtf/cm_summary_saffl_cm_ontrt.rtf
Generated: studies/xyz123/rtf/cm_summary_saffl_cm_ontrt.rtf