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_pd_listing
from csrlite.pd.pd_listing import pd_listing_ard, pd_listing_rtf, pd_listing14 Protocol Deviation Listing
Objectives
This guide demonstrates Protocol Deviation (PD) listing showing detailed individual deviation records.
14.1 Setup
14.2 Protocol Deviation Listing
Shows detailed individual protocol deviations with categories and terms.
14.3 StudyPlan-Driven Workflow
try:
study_plan = load_plan("studies/xyz123/yaml/plan_xyz123.yaml")
# Filter for pd_listing analyses
study_plan.get_plan_df().filter(pl.col("analysis") == "pd_listing")
output_files = study_plan_to_pd_listing(study_plan)
except Exception as e:
print(f"Error loading plan or generating listing: {e}")
output_files = []2026-02-03 15:27:48,417 - csrlite.common.plan - INFO - Successfully loaded dataset 'adsl' from 'studies/xyz123/yaml/../../../data/adsl.parquet'
2026-02-03 15:27:48,420 - csrlite.common.plan - INFO - Successfully loaded dataset 'adae' from 'studies/xyz123/yaml/../../../data/adae.parquet'
2026-02-03 15:27:48,422 - csrlite.common.plan - INFO - Successfully loaded dataset 'adie' from 'studies/xyz123/yaml/../../../data/adie.parquet'
2026-02-03 15:27:48,423 - csrlite.common.plan - INFO - Successfully loaded dataset 'adpd' from 'studies/xyz123/yaml/../../../data/adpd.parquet'
studies/xyz123/rtf/pd_listing_itt_pd_major.rtf
studies/xyz123/rtf/pd_listing_apat.rtf
14.3.1 pd_listing_itt_pd_major
14.3.2 pd_listing_apat
14.4 Complete Pipeline
data_path = Path("data") if Path("data").exists() else Path("../data")
adsl = pl.read_parquet(data_path / "adsl.parquet")
adpd = pl.read_parquet(data_path / "adpd.parquet")
pd_listing(
population=adsl,
observation=adpd,
population_filter="ITTFL = 'Y'",
observation_filter="DVCAT = 'Major'",
id=("USUBJID", "Subject ID"),
title=[
"Listing of Major Protocol Deviations",
"(Intent-to-Treat Population)"
],
footnote=["Protocol deviations are sorted by treatment and subject ID."],
source=["Source: ADSL and ADPD datasets"],
output_file="studies/xyz123/rtf/pd_listing_manual.rtf",
population_columns=[
("TRT01A", "Treatment")
],
observation_columns=[
("DVCAT", "Category"),
("DVTERM", "Term"),
("DVDECOD", "Coded Term")
],
sort_columns=["TRT01A", "USUBJID", "DVCAT", "DVTERM"],
group_by=["USUBJID"],
page_by=["TRT01A"],
)studies/xyz123/rtf/pd_listing_manual.rtf
'studies/xyz123/rtf/pd_listing_manual.rtf'
14.5 Step-by-Step Pipeline
14.5.1 Step 1: Generate ARD
_ard = pd_listing_ard(
population=adsl,
observation=adpd,
population_filter="ITTFL = 'Y'",
observation_filter="DVCAT = 'Major'",
id=("USUBJID", "Subject ID"),
population_columns=[("TRT01A", "Treatment")],
observation_columns=[
("DVCAT", "Category"),
("DVTERM", "Term"),
("DVDECOD", "Coded Term")
],
sort_columns=["TRT01A", "USUBJID", "DVCAT", "DVTERM"],
page_by=["TRT01A"]
)
_ard.head(5)
shape: (3, 5)
| __index__ | USUBJID | DVCAT | DVTERM | DVDECOD |
|---|---|---|---|---|
| str | str | str | str | str |
| "Treatment = Xanomeline Low Dos… | "01-701-1097" | "Major" | "HbA1c > 9% at screening" | "Inclusion/Exclusion Criteria" |
| "Treatment = Xanomeline Low Dos… | "01-701-1115" | "Major" | "Administered 10mg instead of 5… | "Study Drug Handling/Dosing" |
| "Treatment = Xanomeline Low Dos… | "01-701-1115" | "Major" | "ICF signed after lab draw" | "Informed Consent Procedure" |
14.5.2 Step 2: Generate RTF Output
pd_listing_rtf(
_ard.head(10),
column_labels={
"USUBJID": "Subject ID",
"TRT01A": "Treatment",
"DVCAT": "Category",
"DVTERM": "Term",
"DVDECOD": "Coded Term",
"__index__": ""
},
title=[
"Listing of Major Protocol Deviations",
"(Intent-to-Treat Population)"
],
footnote=["Protocol deviations are sorted by treatment and subject ID."],
source=["Source: ADSL and ADPD datasets"],
group_by=["USUBJID"],
page_by=["__index__"]
).write_rtf("studies/xyz123/rtf/pd_listing_step.rtf")studies/xyz123/rtf/pd_listing_step.rtf