Define safety pharmacology discussion origin, concept and Importance of safety pharmacology Give procedure in flow wise pdf format
safety pharmacology definition origin ICH S7A S7B guidelines concept importance
https://www.altasciences.com/resource-center/blog/nonclinica…
mkdir -p /tmp/workspace/safety-pharmacology && ls /tmp/workspace/safety-pharmacology/
~/safety-pharmacology/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, ListFlowable, ListItem
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus.flowables import KeepTogether
from reportlab.graphics.shapes import Drawing, Rect, String, Arrow, Line
from reportlab.graphics import renderPDF
from reportlab.lib.colors import HexColor
OUTPUT = "/tmp/workspace/safety-pharmacology/Safety_Pharmacology.pdf"
# ── Colour palette ──────────────────────────────────────────────────────────
DARK_BLUE = HexColor("#1B3A6B")
MID_BLUE = HexColor("#2563A8")
LIGHT_BLUE = HexColor("#DBEAFE")
ACCENT_TEAL = HexColor("#0D9488")
LIGHT_TEAL = HexColor("#CCFBF1")
ORANGE = HexColor("#EA580C")
LIGHT_ORANGE = HexColor("#FED7AA")
GREY_BG = HexColor("#F1F5F9")
DARK_TEXT = HexColor("#1E293B")
WHITE = colors.white
doc = SimpleDocTemplate(
OUTPUT, pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2.5*cm, bottomMargin=2.5*cm,
title="Safety Pharmacology",
author="Orris AI"
)
W, H = A4
styles = getSampleStyleSheet()
# ── Custom styles ────────────────────────────────────────────────────────────
def make_style(name, parent="Normal", **kw):
s = ParagraphStyle(name, parent=styles[parent], **kw)
return s
cover_title = make_style("CoverTitle", fontSize=30, textColor=WHITE, alignment=TA_CENTER, leading=36, fontName="Helvetica-Bold")
cover_sub = make_style("CoverSub", fontSize=14, textColor=LIGHT_BLUE, alignment=TA_CENTER, leading=20)
cover_info = make_style("CoverInfo", fontSize=10, textColor=LIGHT_BLUE, alignment=TA_CENTER)
chap_head = make_style("ChapHead", fontSize=18, textColor=WHITE, alignment=TA_CENTER, leading=24, fontName="Helvetica-Bold")
sec_head = make_style("SecHead", fontSize=13, textColor=DARK_BLUE, leading=18, fontName="Helvetica-Bold", spaceBefore=10, spaceAfter=4)
sub_head = make_style("SubHead", fontSize=11, textColor=ACCENT_TEAL, leading=15, fontName="Helvetica-Bold", spaceBefore=6, spaceAfter=3)
body = make_style("Body", fontSize=10, textColor=DARK_TEXT, leading=15, alignment=TA_JUSTIFY, spaceAfter=4)
bullet_style = make_style("Bullet", fontSize=10, textColor=DARK_TEXT, leading=14, leftIndent=14, bulletIndent=4)
caption = make_style("Caption", fontSize=8, textColor=colors.grey, alignment=TA_CENTER, italic=True)
flow_step = make_style("FlowStep", fontSize=10, textColor=WHITE, alignment=TA_CENTER, fontName="Helvetica-Bold", leading=14)
flow_desc = make_style("FlowDesc", fontSize=9, textColor=DARK_TEXT, alignment=TA_CENTER, leading=13)
table_head = make_style("TableHead", fontSize=10, textColor=WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER)
table_cell = make_style("TableCell", fontSize=9, textColor=DARK_TEXT, alignment=TA_LEFT, leading=13)
note_style = make_style("Note", fontSize=9, textColor=HexColor("#4B5563"), leading=13, leftIndent=8)
story = []
# ═══════════════════════════════════════════════════════════════════════════
# COVER PAGE
# ═══════════════════════════════════════════════════════════════════════════
def cover_page(canvas, doc):
canvas.saveState()
# dark blue background
canvas.setFillColor(DARK_BLUE)
canvas.rect(0, 0, W, H, fill=1, stroke=0)
# decorative accent bar
canvas.setFillColor(ACCENT_TEAL)
canvas.rect(0, H*0.62, W, 6, fill=1, stroke=0)
canvas.setFillColor(ORANGE)
canvas.rect(0, H*0.62+6, W, 3, fill=1, stroke=0)
# bottom band
canvas.setFillColor(MID_BLUE)
canvas.rect(0, 0, W, H*0.18, fill=1, stroke=0)
canvas.restoreState()
# We'll draw cover content as a first-page frame with background drawn via onFirstPage
class CoverBackground:
def wrap(self, w, h): return w, 0
def draw(self): pass
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate
# Build cover as styled paragraphs placed on a coloured background via onPage
def first_page(canvas, doc):
canvas.saveState()
canvas.setFillColor(DARK_BLUE)
canvas.rect(0, 0, W, H, fill=1, stroke=0)
canvas.setFillColor(ACCENT_TEAL)
canvas.rect(0, H-7*cm, W, 4, fill=1, stroke=0)
canvas.setFillColor(ORANGE)
canvas.rect(0, H-7*cm+4, W, 2, fill=1, stroke=0)
canvas.setFillColor(MID_BLUE)
canvas.rect(0, 0, W, 3*cm, fill=1, stroke=0)
# Title text
canvas.setFont("Helvetica-Bold", 32)
canvas.setFillColor(WHITE)
canvas.drawCentredString(W/2, H-4*cm, "SAFETY PHARMACOLOGY")
canvas.setFont("Helvetica-Bold", 18)
canvas.setFillColor(LIGHT_BLUE)
canvas.drawCentredString(W/2, H-5.2*cm, "Definition, Origin, Concept,")
canvas.drawCentredString(W/2, H-6.2*cm, "Importance & Procedure")
# Subtitle band text
canvas.setFont("Helvetica", 11)
canvas.setFillColor(LIGHT_BLUE)
canvas.drawCentredString(W/2, H-8*cm, "A Comprehensive Reference Guide for Preclinical Drug Development")
# Regulatory badges
badges = ["ICH S7A (2000)", "ICH S7B (2005)", "ICH M3", "ICH S6"]
bw = 3.5*cm
start_x = W/2 - (len(badges)*bw + (len(badges)-1)*0.4*cm)/2
for i, b in enumerate(badges):
bx = start_x + i*(bw+0.4*cm)
by = H-11*cm
canvas.setFillColor(MID_BLUE)
canvas.roundRect(bx, by, bw, 0.7*cm, 3, fill=1, stroke=0)
canvas.setFillColor(WHITE)
canvas.setFont("Helvetica-Bold", 8)
canvas.drawCentredString(bx+bw/2, by+0.2*cm, b)
# Bottom info
canvas.setFont("Helvetica", 9)
canvas.setFillColor(LIGHT_BLUE)
canvas.drawCentredString(W/2, 2*cm, "Prepared by Orris AI | July 2026")
canvas.drawCentredString(W/2, 1.4*cm, "Based on ICH Guidelines, Regulatory Sources & Pharmacology Literature")
canvas.restoreState()
def later_pages(canvas, doc):
canvas.saveState()
# header bar
canvas.setFillColor(DARK_BLUE)
canvas.rect(0, H-1.4*cm, W, 1.4*cm, fill=1, stroke=0)
canvas.setFillColor(ACCENT_TEAL)
canvas.rect(0, H-1.4*cm-3, W, 3, fill=1, stroke=0)
canvas.setFont("Helvetica-Bold", 9)
canvas.setFillColor(WHITE)
canvas.drawString(2*cm, H-0.9*cm, "SAFETY PHARMACOLOGY")
canvas.setFont("Helvetica", 8)
canvas.setFillColor(LIGHT_BLUE)
canvas.drawRightString(W-2*cm, H-0.9*cm, "Preclinical Drug Development Guide")
# footer
canvas.setFillColor(GREY_BG)
canvas.rect(0, 0, W, 1.2*cm, fill=1, stroke=0)
canvas.setFillColor(ACCENT_TEAL)
canvas.rect(0, 1.2*cm, W, 2, fill=1, stroke=0)
canvas.setFont("Helvetica", 8)
canvas.setFillColor(HexColor("#6B7280"))
canvas.drawString(2*cm, 0.45*cm, "ICH S7A/S7B Guidelines | Safety Pharmacology")
canvas.drawRightString(W-2*cm, 0.45*cm, f"Page {doc.page}")
canvas.restoreState()
# ── Utility helpers ──────────────────────────────────────────────────────────
def chapter_banner(text, color=DARK_BLUE):
"""Returns a banner table for chapter headings."""
t = Table([[Paragraph(text, chap_head)]], colWidths=[W-4*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 12),
("RIGHTPADDING", (0,0), (-1,-1), 12),
("ROUNDEDCORNERS", [4]),
]))
return t
def info_box(text, bg=LIGHT_BLUE, border=MID_BLUE):
t = Table([[Paragraph(text, body)]], colWidths=[W-4*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("BOX", (0,0), (-1,-1), 1.5, border),
("ROUNDEDCORNERS", [4]),
]))
return t
def bullet(text):
return Paragraph(f"<bullet>•</bullet> {text}", bullet_style)
def section_rule():
return HRFlowable(width="100%", thickness=1, color=LIGHT_BLUE, spaceAfter=4, spaceBefore=4)
# ─────────────────────────────────────────────────────────────────────────────
# PAGE 1 – COVER (empty body, background drawn by first_page callback)
# ─────────────────────────────────────────────────────────────────────────────
story.append(Spacer(1, H-4*cm)) # push to fill cover
story.append(PageBreak())
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 1 – INTRODUCTION & DEFINITION
# ─────────────────────────────────────────────────────────────────────────────
story.append(chapter_banner("1. Introduction & Definition", DARK_BLUE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("What is Safety Pharmacology?", sec_head))
story.append(section_rule())
story.append(Paragraph(
"Safety pharmacology is a scientific discipline dedicated to evaluating the <b>potential adverse functional effects</b> of a pharmaceutical substance on critical physiological organ systems — primarily cardiovascular, central nervous system (CNS), and respiratory — at exposures within and above the therapeutic range. It forms an essential pillar of nonclinical drug safety evaluation, complementing toxicology and efficacy studies.",
body))
story.append(Spacer(1, 0.2*cm))
story.append(info_box(
"<b>ICH S7A Definition (2000):</b> Safety pharmacology studies are those studies that investigate the potential undesirable pharmacodynamic effects of a substance on physiological functions in relation to exposure in the therapeutic range and above.",
LIGHT_BLUE, MID_BLUE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Key Distinctions", sub_head))
dist_data = [
[Paragraph("<b>Aspect</b>", table_head), Paragraph("<b>Safety Pharmacology</b>", table_head), Paragraph("<b>General Toxicology</b>", table_head)],
[Paragraph("Focus", table_cell), Paragraph("Functional organ effects", table_cell), Paragraph("Structural/morphological changes", table_cell)],
[Paragraph("Endpoints", table_cell), Paragraph("Physiological (ECG, BP, EEG, SpO2)", table_cell), Paragraph("Histopathology, biochemistry", table_cell)],
[Paragraph("Timing", table_cell), Paragraph("Before first-in-human trials", table_cell), Paragraph("Parallel to development stages", table_cell)],
[Paragraph("Key Organ Systems", table_cell), Paragraph("CVS, CNS, Respiratory (core battery)", table_cell), Paragraph("All organs, liver, kidney, bone marrow", table_cell)],
]
dist_table = Table(dist_data, colWidths=[3*cm, 6*cm, 6*cm])
dist_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("BACKGROUND", (0,1), (-1,1), LIGHT_BLUE),
("BACKGROUND", (0,3), (-1,3), LIGHT_BLUE),
("GRID", (0,0), (-1,-1), 0.5, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("ROWBACKGROUNDS",(0,0), (-1,-1), [None, LIGHT_BLUE, WHITE, LIGHT_BLUE, WHITE]),
]))
story.append(dist_table)
story.append(Spacer(1, 0.4*cm))
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 2 – ORIGIN & HISTORICAL BACKGROUND
# ─────────────────────────────────────────────────────────────────────────────
story.append(chapter_banner("2. Origin & Historical Background", MID_BLUE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Historical Timeline", sec_head))
story.append(section_rule())
timeline_data = [
[Paragraph("<b>Era / Year</b>", table_head), Paragraph("<b>Event / Milestone</b>", table_head), Paragraph("<b>Significance</b>", table_head)],
[Paragraph("Pre-1960s", table_cell),
Paragraph("Secondary pharmacology testing conducted informally", table_cell),
Paragraph("No formal guidelines; organ function testing ad hoc", table_cell)],
[Paragraph("1960s – Thalidomide Crisis", table_cell),
Paragraph("Thalidomide causes severe teratogenicity; drug withdrawn", table_cell),
Paragraph("Prompted global reassessment of preclinical safety testing", table_cell)],
[Paragraph("1970s", table_cell),
Paragraph("Japan issues first formal safety pharmacology guidelines (1975)", table_cell),
Paragraph("First regulatory mandate to assess organ function for drug candidates", table_cell)],
[Paragraph("1980s–1990s", table_cell),
Paragraph("Drug-induced QT prolongation and TdP cases increase; drugs withdrawn (terfenadine, cisapride, astemizole)", table_cell),
Paragraph("Highlighted cardiac repolarization as a critical safety signal; drove urgent need for standardization", table_cell)],
[Paragraph("Late 1990s", table_cell),
Paragraph("Term 'safety pharmacology' coined in early ICH drafts (M3, S6)", table_cell),
Paragraph("International consensus begins on definitions and scope", table_cell)],
[Paragraph("2000 – ICH S7A", table_cell),
Paragraph("ICH S7A Guideline finalized and adopted internationally", table_cell),
Paragraph("First globally harmonized safety pharmacology framework; defines core battery", table_cell)],
[Paragraph("2005 – ICH S7B", table_cell),
Paragraph("ICH S7B Guideline adopted; focuses on QT/QTc prolongation assessment", table_cell),
Paragraph("Established hERG assay and in vivo QT study as standard practice", table_cell)],
[Paragraph("2006 – TGN1412 Incident", table_cell),
Paragraph("Phase I clinical trial causes cytokine storm in all 6 volunteers", table_cell),
Paragraph("Demonstrated limits of standard testing; reinforced value of functional safety assessment", table_cell)],
[Paragraph("2010s–Present", table_cell),
Paragraph("Integration of in vitro, in silico, and organ-on-chip models; CiPA initiative", table_cell),
Paragraph("Moving toward mechanism-based, human-relevant safety pharmacology", table_cell)],
[Paragraph("2025–2026", table_cell),
Paragraph("ICH S7A 25-year review; proposals to modernize and unify S7A+S7B", table_cell),
Paragraph("Adapting guidelines to novel therapeutic modalities and new technologies", table_cell)],
]
tl_table = Table(timeline_data, colWidths=[3.5*cm, 6.5*cm, 5*cm])
tl_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("GRID", (0,0), (-1,-1), 0.5, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_BG]),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(tl_table)
story.append(Spacer(1, 0.4*cm))
story.append(Paragraph("Drivers Behind Safety Pharmacology's Emergence", sub_head))
drivers = [
"Limitations of traditional toxicology in detecting functional/off-target effects",
"High-profile drug withdrawals due to QT prolongation (terfenadine, cisapride)",
"International recognition that structural histopathology alone misses critical safety signals",
"Need to protect first-in-human (FIH) trial participants from unexpected physiological harm",
"Japan's 1975 precedent providing a model for international regulatory action",
]
for d in drivers:
story.append(bullet(d))
story.append(Spacer(1, 0.4*cm))
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 3 – CONCEPT
# ─────────────────────────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(chapter_banner("3. Concept of Safety Pharmacology", ACCENT_TEAL))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Conceptual Framework", sec_head))
story.append(section_rule())
story.append(Paragraph(
"The concept of safety pharmacology rests on the premise that a drug's interaction with off-target receptors or ion channels can cause <b>functional disturbances</b> in vital organ systems at or near therapeutic concentrations. These effects may not produce visible structural changes detectable by histopathology, yet can be life-threatening (e.g., fatal arrhythmia, respiratory depression, seizures).",
body))
story.append(Spacer(1, 0.2*cm))
# Three pillars
pillars = [
("Primary\nPharmacodynamics", "Desired therapeutic effect on the intended target", MID_BLUE),
("Secondary\nPharmacodynamics", "Effects on off-target molecules unrelated to therapeutic goal", ACCENT_TEAL),
("Safety\nPharmacology", "Adverse functional effects on vital organ systems (CVS, CNS, Resp)", ORANGE),
]
p_cells = []
for title, desc, color in pillars:
cell_content = [
[Paragraph(title, ParagraphStyle("ph", fontSize=10, textColor=WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER, leading=14))],
[Paragraph(desc, ParagraphStyle("pd", fontSize=8.5, textColor=DARK_TEXT, alignment=TA_CENTER, leading=12))],
]
inner = Table(cell_content, colWidths=[4.5*cm])
inner.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), color),
("BACKGROUND", (0,1), (-1,1), WHITE),
("TOPPADDING", (0,0), (-1,0), 8),
("BOTTOMPADDING", (0,0), (-1,0), 8),
("TOPPADDING", (0,1), (-1,1), 6),
("BOTTOMPADDING", (0,1), (-1,1), 6),
("BOX", (0,0), (-1,-1), 1.5, color),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
]))
p_cells.append(inner)
pillars_table = Table([p_cells], colWidths=[4.9*cm, 4.9*cm, 4.9*cm])
pillars_table.setStyle(TableStyle([
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(pillars_table)
story.append(Paragraph("The three pillars of pharmacological evaluation — relationships and scope", caption))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Core Battery — Three Vital Systems", sub_head))
core_data = [
[Paragraph("<b>System</b>", table_head), Paragraph("<b>Parameters Assessed</b>", table_head), Paragraph("<b>Guideline Reference</b>", table_head)],
[Paragraph("Cardiovascular (CVS)", table_cell),
Paragraph("Heart rate, blood pressure, ECG (QRS, PR, QT/QTc, ST), hERG channel inhibition, cardiac contractility", table_cell),
Paragraph("ICH S7A, S7B", table_cell)],
[Paragraph("Central Nervous System (CNS)", table_cell),
Paragraph("Motor activity, behavioral changes, coordination (rotarod), body temperature, EEG (seizure threshold), sensorimotor reflexes", table_cell),
Paragraph("ICH S7A", table_cell)],
[Paragraph("Respiratory", table_cell),
Paragraph("Respiratory rate, tidal volume, minute ventilation, SpO2, pulmonary resistance", table_cell),
Paragraph("ICH S7A", table_cell)],
]
core_table = Table(core_data, colWidths=[3.5*cm, 8*cm, 3.5*cm])
core_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("GRID", (0,0), (-1,-1), 0.5, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHT_BLUE, LIGHT_TEAL, LIGHT_ORANGE]),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(core_table)
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Follow-Up / Supplemental Studies", sub_head))
followup = [
"<b>Renal system:</b> urinary volume, osmolality, electrolytes, creatinine",
"<b>Autonomic nervous system:</b> baroreceptor reflex, pressor/depressor agents",
"<b>Gastrointestinal:</b> gastric motility, secretion, intestinal transit",
"<b>Reproductive / endocrine:</b> hormone levels, fertility markers (when indicated)",
"<b>Ocular:</b> pupillometry, intraocular pressure (when CNS effects flagged)",
]
for f in followup:
story.append(bullet(f))
story.append(Spacer(1, 0.4*cm))
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 4 – IMPORTANCE
# ─────────────────────────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(chapter_banner("4. Importance of Safety Pharmacology", ORANGE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Why Safety Pharmacology Matters", sec_head))
story.append(section_rule())
importance_points = [
("Patient & Subject Protection",
"Ensures that life-threatening functional toxicity (e.g., fatal arrhythmia, seizures, respiratory arrest) is detected before first-in-human trials. ICH S7A's primary objective is to protect clinical trial participants."),
("Early Identification of Safety Risks",
"Identifies organ system liabilities early in development, allowing medicinal chemists to optimize lead compounds before costly late-stage failures."),
("Reduction of Late-Stage Attrition",
"Safety-related attrition and withdrawals during late clinical development and post-approval remain a major industry problem. Early safety pharmacology data directly reduce this risk."),
("Regulatory Compliance",
"Safety pharmacology studies are mandatory before Phase I trials for all new chemical entities (NCEs) and biopharmaceuticals. Non-compliance prevents INDs and CTAs from being approved."),
("Inform Clinical Monitoring",
"Safety pharmacology data guide the design of first-in-human studies — informing ECG monitoring protocols, dose escalation rules, and stopping criteria."),
("Risk-Benefit Decision Making",
"Provides quantitative safety margins (e.g., hERG IC50 vs. therapeutic concentration) enabling informed risk-benefit decisions for compounds with marginal profiles."),
("3R Alignment (Replace, Reduce, Refine)",
"Integration of in vitro (hERG, AMES) and in silico models reduces animal use while increasing throughput and mechanistic understanding."),
("Public Health & Post-Market Surveillance",
"Can be applied to marketed products when new adverse events, patient populations, or routes of administration raise safety concerns not previously characterized."),
]
imp_data = [[Paragraph(f"<b>{t}</b>", table_head), Paragraph(d, table_cell)] for t,d in importance_points]
imp_data.insert(0, [Paragraph("<b>Importance Area</b>", table_head), Paragraph("<b>Details</b>", table_head)])
imp_table = Table(imp_data, colWidths=[5.5*cm, 9.5*cm])
imp_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("GRID", (0,0), (-1,-1), 0.5, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "TOP"),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_BG]),
("BACKGROUND", (0,1), (0,-1), LIGHT_TEAL),
]))
story.append(imp_table)
story.append(Spacer(1, 0.4*cm))
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 5 – PROCEDURE (FLOWCHART)
# ─────────────────────────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(chapter_banner("5. Procedure — Step-by-Step Workflow", MID_BLUE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph(
"The following flow describes the standard procedure for conducting safety pharmacology studies for a new pharmaceutical, aligned with ICH S7A/S7B and OECD guidelines.",
body))
story.append(Spacer(1, 0.2*cm))
# ── Flow steps ──────────────────────────────────────────────────────────────
steps = [
("STEP 1", "CANDIDATE SELECTION & TRIGGER",
MID_BLUE,
["New chemical entity (NCE) or biopharmaceutical identified",
"Compound progresses through lead optimization",
"Decision to advance to IND/CTA filing",
"Trigger: Pre-IND safety package required by FDA/EMA/PMDA"]),
("STEP 2", "STUDY PLANNING & REGULATORY ALIGNMENT",
ACCENT_TEAL,
["Review ICH S7A (core battery) and S7B (cardiac repolarization)",
"Define testing strategy: standalone vs. integrated studies",
"Select species (rat, dog, non-human primate, guinea pig)",
"Determine dose levels (low, mid, high — typically 10x, 30x, 100x therapeutic)",
"Prepare study protocol; obtain IACUC/ethics approval",
"Identify GLP requirements (core battery must be GLP-compliant)"]),
("STEP 3", "IN VITRO SCREENING (EARLY FILTERS)",
ORANGE,
["hERG channel assay (patch clamp) — cardiac repolarization liability",
"Nav1.5 (sodium channel) and Cav1.2 (calcium channel) electrophysiology",
"Radioligand binding panels (off-target receptor screening)",
"In vitro cytotoxicity screens",
"CNS receptor/transporter binding profiles"]),
("STEP 4", "IN VIVO CORE BATTERY STUDIES",
MID_BLUE,
["<b>4A — CNS Studies (Modified Irwin Test / FOB):</b>",
" Species: Rat (conscious, unrestrained); route: therapeutic route",
" Parameters: locomotor activity, posture, grip strength, reflexes, body temperature, seizure assessment",
" Timing: single-dose; observe at multiple time-points (0.5, 1, 2, 4, 8 h)",
"<b>4B — Cardiovascular Studies:</b>",
" Species: Conscious telemetered dog (preferred) or rat",
" Parameters: HR, BP (systolic/diastolic/MAP), ECG (QRS, PR, QT, QTc)",
" Telemetry implants provide continuous, undisturbed recordings",
" Must include hERG in vitro + in vivo QT assessment per ICH S7B",
"<b>4C — Respiratory Studies:</b>",
" Species: Conscious rat (whole-body plethysmography)",
" Parameters: RR, TV, MV, peak flow, SpO2"]),
("STEP 5", "SUPPLEMENTAL / FOLLOW-UP STUDIES (IF INDICATED)",
ACCENT_TEAL,
["Triggered by: signals from core battery, pharmacological class, adverse clinical events",
"Renal: urine volume, electrolytes, creatinine clearance (conscious rat)",
"GI: gastric emptying (charcoal meal), intestinal transit",
"Autonomic NS: baroreceptor sensitivity, pupillometry",
"Abuse potential / dependence: self-administration, conditioned place preference",
"Ocular: slit-lamp biomicroscopy, tonometry"]),
("STEP 6", "DATA COLLECTION & QUALITY ASSURANCE",
DARK_BLUE,
["All core battery studies conducted under GLP (21 CFR Part 58 / OECD GLP)",
"Raw data captured electronically; audit trail maintained",
"Calibration records for all equipment (telemetry, plethysmography)",
"QA audits during and after study conduct",
"Statistical analysis: mean ± SEM; ANOVA with post-hoc tests; NOAEL determination"]),
("STEP 7", "DATA ANALYSIS & SAFETY MARGIN CALCULATION",
MID_BLUE,
["Calculate safety margins: NOAEL / therapeutic Cmax or AUC",
"Interpret QT findings: delta QTc, concentration-QTc relationship",
"Identify NOAEL (No Observed Adverse Effect Level)",
"Compare to therapeutic and anticipated clinical concentrations",
"Benchmark against known compounds in the same class",
"Flag any findings for clinical trial monitoring design"]),
("STEP 8", "REPORT WRITING & REGULATORY SUBMISSION",
ACCENT_TEAL,
["Individual study reports written per GLP format",
"Integrated Safety Pharmacology Summary prepared (ICH M4S CTD format)",
"Included in IND Module 4 (Non-clinical study reports)",
"Submitted to FDA (IND), EMA (CTA), PMDA, CDSCO as applicable",
"Reviewed by regulatory agencies before first-in-human approval"]),
("STEP 9", "INTEGRATION WITH CLINICAL TRIAL DESIGN",
ORANGE,
["Safety pharmacology findings directly inform:",
" Phase I dose escalation stopping rules",
" ECG monitoring frequency and criteria",
" Vital sign monitoring schedules",
" Eligibility criteria (exclude patients with QTc > 450 ms if hERG signal present)",
"TQT (Thorough QT) study design for Phase II based on preclinical data"]),
("STEP 10", "CONTINUOUS MONITORING & POST-APPROVAL",
DARK_BLUE,
["Pharmacovigilance: monitor adverse events in post-marketing for new safety signals",
"Additional safety pharmacology studies triggered if new signals emerge",
"New populations (pediatric, renal impairment): supplemental safety data",
"ICH E14 clinical QT guidance applied throughout lifecycle",
"Regulatory agencies may request additional studies based on clinical signals"]),
]
arrow_style = ParagraphStyle("arrow", fontSize=18, textColor=ACCENT_TEAL, alignment=TA_CENTER, leading=20)
for i, (step_num, step_title, color, points) in enumerate(steps):
# Step box
header_cell = Table([[
Paragraph(step_num, ParagraphStyle("sn", fontSize=9, textColor=WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER)),
Paragraph(step_title, ParagraphStyle("st", fontSize=11, textColor=WHITE, fontName="Helvetica-Bold", leading=15)),
]], colWidths=[2*cm, 13*cm])
header_cell.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("LINEAFTER", (0,0), (0,-1), 1, WHITE),
]))
points_cell_content = []
for p in points:
points_cell_content.append([Paragraph(f"{'• ' if not p.startswith(' ') and not p.startswith('<b>') else ''} {p}",
ParagraphStyle("pc", fontSize=9, textColor=DARK_TEXT, leading=13, leftIndent=6))])
points_table = Table(points_cell_content, colWidths=[14.5*cm])
points_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), GREY_BG if color != DARK_BLUE else HexColor("#E8EDF5")),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("BOX", (0,0), (-1,-1), 1, color),
]))
step_block = KeepTogether([header_cell, points_table, Spacer(1, 0.1*cm)])
story.append(step_block)
if i < len(steps) - 1:
story.append(Paragraph("▼", arrow_style)) # down arrow
story.append(Spacer(1, 0.4*cm))
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 6 – REGULATORY GUIDELINES SUMMARY
# ─────────────────────────────────────────────────────────────────────────────
story.append(PageBreak())
story.append(chapter_banner("6. Regulatory Framework Summary", DARK_BLUE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Key International Guidelines", sec_head))
story.append(section_rule())
reg_data = [
[Paragraph("<b>Guideline</b>", table_head), Paragraph("<b>Issuing Body</b>", table_head), Paragraph("<b>Year</b>", table_head), Paragraph("<b>Scope</b>", table_head)],
[Paragraph("ICH S7A", table_cell), Paragraph("ICH", table_cell), Paragraph("2000", table_cell),
Paragraph("Core battery definition, study design, species selection, GLP requirements for all NCEs", table_cell)],
[Paragraph("ICH S7B", table_cell), Paragraph("ICH", table_cell), Paragraph("2005", table_cell),
Paragraph("hERG in vitro, in vivo QT/QTc assessment; proarrhythmia risk (delayed ventricular repolarization)", table_cell)],
[Paragraph("ICH M3(R2)", table_cell), Paragraph("ICH", table_cell), Paragraph("2009", table_cell),
Paragraph("Timing of safety pharmacology studies relative to clinical trial phases", table_cell)],
[Paragraph("ICH S6(R1)", table_cell), Paragraph("ICH", table_cell), Paragraph("2011", table_cell),
Paragraph("Safety pharmacology for biotechnology-derived products (biologics)", table_cell)],
[Paragraph("ICH E14", table_cell), Paragraph("ICH", table_cell), Paragraph("2005", table_cell),
Paragraph("Clinical (TQT) evaluation of QT/QTc interval prolongation in human trials", table_cell)],
[Paragraph("OECD GLP", table_cell), Paragraph("OECD", table_cell), Paragraph("Various", table_cell),
Paragraph("Good Laboratory Practice principles applicable to safety pharmacology studies", table_cell)],
[Paragraph("Japan (MHW) 1975", table_cell), Paragraph("PMDA/MHW", table_cell), Paragraph("1975", table_cell),
Paragraph("First formal national safety pharmacology requirements — the historical origin", table_cell)],
]
reg_table = Table(reg_data, colWidths=[2.5*cm, 2.5*cm, 1.5*cm, 8.5*cm])
reg_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("GRID", (0,0), (-1,-1), 0.5, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_BG]),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(reg_table)
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("The CiPA Initiative (Comprehensive in vitro Proarrhythmia Assay)", sub_head))
story.append(Paragraph(
"Launched around 2013, CiPA is a paradigm shift away from the hERG-centric approach toward a mechanism-based, multi-ion-channel assessment combined with human stem cell-derived cardiomyocyte (hiPSC-CM) assays and in silico cardiac action potential modeling. It aims to better predict proarrhythmic risk and reduce false positives that led to unnecessary drug withdrawals.",
body))
story.append(Spacer(1, 0.4*cm))
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 7 – KEY TERMS GLOSSARY
# ─────────────────────────────────────────────────────────────────────────────
story.append(chapter_banner("7. Key Terms & Glossary", ACCENT_TEAL))
story.append(Spacer(1, 0.3*cm))
glossary = [
("NOAEL", "No Observed Adverse Effect Level — highest dose at which no adverse effects are detected"),
("hERG", "Human Ether-a-go-go Related Gene — potassium channel critical for cardiac repolarization; drug blockade causes QT prolongation"),
("QTc", "Corrected QT interval — QT interval corrected for heart rate (Fridericia or Bazett formula)"),
("TdP", "Torsades de Pointes — potentially fatal ventricular arrhythmia associated with QT prolongation"),
("FOB", "Functional Observational Battery — standardized CNS behavioral assessment in rodents"),
("Telemetry", "Radiofrequency/implanted transmitter-based continuous monitoring of cardiovascular parameters in conscious, freely-moving animals"),
("GLP", "Good Laboratory Practice — quality system for regulatory preclinical studies ensuring data integrity and reproducibility"),
("ICH", "International Council for Harmonisation of Technical Requirements for Pharmaceuticals for Human Use"),
("IND", "Investigational New Drug application — US FDA filing required before human clinical trials"),
("CTA", "Clinical Trial Authorisation — EMA equivalent of IND"),
("Core Battery", "The mandatory set of safety pharmacology studies (CVS, CNS, Respiratory) required before first-in-human trials per ICH S7A"),
("Secondary Pharmacology", "Pharmacological effects on molecular targets other than the intended therapeutic target"),
("TQT Study", "Thorough QT/QTc study — Phase I/II human clinical trial designed to precisely quantify drug effect on QT interval per ICH E14"),
("CiPA", "Comprehensive in vitro Proarrhythmia Assay — next-generation multi-channel cardiac safety platform"),
("hiPSC-CM", "Human induced Pluripotent Stem Cell-derived Cardiomyocytes — human-relevant cardiac cells used in CiPA framework"),
]
gl_data = [[Paragraph(f"<b>{t}</b>", ParagraphStyle("gt", fontSize=9, textColor=DARK_BLUE, fontName="Helvetica-Bold", leading=13)),
Paragraph(d, ParagraphStyle("gd", fontSize=9, textColor=DARK_TEXT, leading=13))]
for t, d in glossary]
gl_data.insert(0, [Paragraph("<b>Term</b>", table_head), Paragraph("<b>Definition</b>", table_head)])
gl_table = Table(gl_data, colWidths=[3.5*cm, 11.5*cm])
gl_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("GRID", (0,0), (-1,-1), 0.5, colors.lightgrey),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY_BG]),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(gl_table)
story.append(Spacer(1, 0.4*cm))
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 8 – REFERENCES
# ─────────────────────────────────────────────────────────────────────────────
story.append(chapter_banner("8. Key References", DARK_BLUE))
story.append(Spacer(1, 0.2*cm))
refs = [
"ICH S7A: Safety Pharmacology Studies for Human Pharmaceuticals. International Council for Harmonisation. November 8, 2000.",
"ICH S7B: The Non-Clinical Evaluation of the Potential for Delayed Ventricular Repolarization (QT Interval Prolongation) by Human Pharmaceuticals. ICH. May 12, 2005.",
"ICH M3(R2): Guidance on Nonclinical Safety Studies for the Conduct of Human Clinical Trials and Marketing Authorisation for Pharmaceuticals. ICH. 2009.",
"ICH E14: The Clinical Evaluation of QT/QTc Interval Prolongation and Proarrhythmic Potential for Non-Antiarrhythmic Drugs. ICH. 2005.",
"Bass A, Kinter L, Williams P. Origins, practices and future of safety pharmacology. Journal of Pharmacological and Toxicological Methods. 2004;49(3):145-151.",
"Valentin JP et al. Revisiting ICH S7A after 25 years: Outcomes of a multi-stakeholder workshop. Regulatory Toxicology and Pharmacology. 2026;169:106096.",
"Altasciences. Nonclinical Safety Pharmacology Programs: What You Need to Know. Available at: altasciences.com. Accessed July 2026.",
"Goodman & Gilman's The Pharmacological Basis of Therapeutics, 14th Edition. McGraw-Hill. 2023.",
"Katzung BG (ed). Basic and Clinical Pharmacology, 16th Edition. McGraw-Hill. 2023.",
]
for r in refs:
story.append(Paragraph(f"• {r}", ParagraphStyle("ref", fontSize=9, textColor=DARK_TEXT, leading=13, leftIndent=12, spaceAfter=3)))
story.append(Spacer(1, 1*cm))
story.append(info_box(
"<b>Disclaimer:</b> This document is prepared for educational reference purposes. Always consult current ICH guidelines, national regulatory authority requirements, and institutional SOPs for actual study conduct. Guidelines are subject to revision.",
LIGHT_ORANGE, ORANGE))
# ─────────────────────────────────────────────────────────────────────────────
# BUILD
# ─────────────────────────────────────────────────────────────────────────────
doc.build(
story,
onFirstPage=first_page,
onLaterPages=later_pages,
)
print(f"PDF created: {OUTPUT}")
cd /tmp/workspace/safety-pharmacology && python generate_pdf.py 2>&1
~/safety-pharmacology/generate_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/safety-pharmacology/generate_pdf.py'
cd /tmp/workspace/safety-pharmacology && python generate_pdf.py 2>&1
~/safety-pharmacology/generate_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/safety-pharmacology/generate_pdf.py'
cd /tmp/workspace/safety-pharmacology && python generate_pdf.py 2>&1
Safety Pharmacology
PDF Document · PDF
ICH S7A (2000) definition: "Studies that investigate the potential undesirable pharmacodynamic effects of a substance on physiological functions in relation to exposure in the therapeutic range and above."
| Era | Event |
|---|---|
| Pre-1960s | Informal "secondary pharmacology" testing; no global standards |
| 1960s | Thalidomide crisis - drove global reassessment of preclinical safety |
| 1975 | Japan (MHW) issues first formal safety pharmacology regulatory guidelines - the true historical origin |
| 1980s-90s | Drug-induced QT prolongation causes fatal arrhythmias; terfenadine, cisapride, astemizole withdrawn |
| Late 1990s | Term "safety pharmacology" coined in ICH M3 and S6 draft documents |
| 2000 | ICH S7A adopted globally - first internationally harmonized safety pharmacology framework |
| 2005 | ICH S7B adopted - QT/hERG-focused guidance; formalizes cardiac repolarization assessment |
| 2010s-present | CiPA initiative; human iPSC-CM models; in silico cardiac action potential modeling |
| 2025-2026 | ICH S7A 25-year anniversary review; proposals to modernize and unify S7A+S7B |
| System | Parameters |
|---|---|
| Cardiovascular | HR, BP, ECG (QRS/PR/QT/QTc), hERG, cardiac contractility |
| CNS | Locomotor activity, reflexes, coordination, body temperature, seizure threshold, EEG |
| Respiratory | Respiratory rate, tidal volume, minute ventilation, SpO2 |
STEP 1 → Candidate Selection & IND/CTA trigger
↓
STEP 2 → Study Planning: ICH S7A/S7B review, species, doses, protocol, IACUC approval
↓
STEP 3 → In Vitro Screening: hERG patch clamp, Nav1.5/Cav1.2, receptor binding panels
↓
STEP 4 → In Vivo Core Battery:
4A - CNS (Modified Irwin/FOB in conscious rat)
4B - CVS (telemetered dog/rat; ECG + BP)
4C - Respiratory (whole-body plethysmography in conscious rat)
↓
STEP 5 → Supplemental Studies (if indicated): renal, GI, ANS, ocular, abuse
↓
STEP 6 → GLP Data Collection & QA Audits
↓
STEP 7 → Data Analysis: NOAEL, safety margins, QTc concentration-response modeling
↓
STEP 8 → Regulatory Report (GLP format) → IND Module 4 submission (FDA/EMA/PMDA)
↓
STEP 9 → Integration with Phase I Design: stopping rules, ECG monitoring, eligibility criteria
↓
STEP 10 → Continuous Monitoring: pharmacovigilance, post-approval supplemental studies