Prepare notes for this topic pharmacodynamics
| Type | Description | Example |
|---|---|---|
| Full Agonist | Binds and fully activates receptor | Morphine (full mu-opioid agonist) |
| Partial Agonist | Binds and activates, but cannot produce maximum response even at full receptor occupancy | Buprenorphine |
| Antagonist | Binds receptor but does NOT activate it; blocks agonist effects | Naloxone (opioid overdose reversal) |
| Inverse Agonist | Binds receptor and produces the OPPOSITE effect of an agonist | Propranolol (beta-blocker) |
| Allosteric Modulator | Binds a site OTHER than the active site; modifies receptor activity | Benzodiazepines on GABA-A receptors |
The Hill equation describes the concentration-effect relationship: E = Emax × C^H / (EC50^H + C^H) where H = Hill coefficient (measure of curve sigmoidicity)
| Parameter | Definition |
|---|---|
| TD50 (Toxic Dose 50) | Dose at which 50% of individuals experience toxic effects |
| LD50 (Lethal Dose 50) | Dose that is lethal to 50% of the population (studied in animals) |
| Therapeutic Index (TI) | TI = LD50 / ED50 (or TD50 / ED50). A wide TI = safer drug |
| Margin of Safety | Difference between the therapeutic dose and the toxic dose |
| Group | Effect | Example |
|---|---|---|
| Neonates | Immature liver enzymes affect metabolism | Chloramphenicol → "gray baby syndrome" |
| Neonates | Reduced renal clearance | Aminoglycoside toxicity |
| Elderly | Decreased liver & kidney function, reduced drug clearance | Digoxin accumulation |
| Elderly | Reduced response to beta-agonists/antagonists; increased sensitivity to benzodiazepines, opioids, anticholinergics | See note below |
In elderly patients, calcium channel blockers cause greater BP and heart rate drops, and propofol induction dose is 0.5 mg/kg lower than in younger adults. (Rosen's Emergency Medicine)
| Route | Key Feature | Example |
|---|---|---|
| Oral | First-pass metabolism reduces bioavailability | Propranolol |
| Intravenous (IV) | Rapid onset, 100% bioavailability | Emergency drugs |
| Intramuscular / Subcutaneous | Rate depends on blood flow and drug solubility | Insulin, vaccines |
| Stage | Interaction | Example |
|---|---|---|
| Absorption | Antacids reduce absorption of tetracyclines | - |
| Metabolism | Enzyme inducers (rifampin) increase clearance of oral contraceptives | - |
| Metabolism | Enzyme inhibitors (ketoconazole) reduce metabolism of midazolam | - |
| Excretion | Probenecid inhibits renal excretion of penicillin, prolonging its action | - |
| Concept | Drug / Example |
|---|---|
| Partial agonist | Buprenorphine |
| Antagonist | Naloxone (opioids), propranolol (beta) |
| Inverse agonist | Propranolol |
| Allosteric modulator | Benzodiazepines (GABA-A) |
| Narrow TI (monitor levels) | Digoxin, lithium, warfarin, phenytoin |
| CYP3A4 inhibitor (diet) | Grapefruit |
| CYP1A2 inducer (environment) | Smoking (theophylline clearance) |
| G6PD deficiency | Sulfonamides -> hemolysis |
| Gray baby syndrome | Chloramphenicol in neonates |
| Slow acetylators | Isoniazid (INH) |
| Probenecid-penicillin | Excretion interaction |
| Synergism | Sulfonamide + trimethoprim |
Make pdf of this content with flow charts and diagrams
mkdir -p /home/daytona/workspace/pharmacodynamics-pdf && ls /home/daytona/worksp…
~/pharmacodynamics-pdf/generate_pd_pdf.py
"""
Pharmacodynamics Study Notes - PDF Generator
Creates a comprehensive PDF with diagrams, flowcharts, and tables.
"""
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch
import matplotlib.patheffects as pe
import numpy as np
import os
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,
Image, HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import Flowable
ASSETS = "/home/daytona/workspace/pharmacodynamics-pdf/assets"
os.makedirs(ASSETS, exist_ok=True)
# ─── Color Palette ────────────────────────────────────────────────────────────
C_DARK_BLUE = "#1a3a5c"
C_MID_BLUE = "#2e6da4"
C_LIGHT_BLUE = "#aed6f1"
C_TEAL = "#1abc9c"
C_ORANGE = "#e67e22"
C_RED = "#e74c3c"
C_GREEN = "#27ae60"
C_PURPLE = "#8e44ad"
C_YELLOW = "#f39c12"
C_GREY = "#ecf0f1"
C_DARK_GREY = "#7f8c8d"
# ═══════════════════════════════════════════════════════════════════════════════
# DIAGRAM GENERATORS
# ═══════════════════════════════════════════════════════════════════════════════
def draw_box(ax, x, y, w, h, text, facecolor, textcolor='white', fontsize=9, bold=False):
box = FancyBboxPatch((x - w/2, y - h/2), w, h,
boxstyle="round,pad=0.02", linewidth=1.2,
edgecolor='white', facecolor=facecolor, zorder=3)
ax.add_patch(box)
weight = 'bold' if bold else 'normal'
ax.text(x, y, text, ha='center', va='center', fontsize=fontsize,
color=textcolor, fontweight=weight, wrap=True,
multialignment='center', zorder=4)
def arrow(ax, x1, y1, x2, y2, color='#555555'):
ax.annotate('', xy=(x2, y2), xytext=(x1, y1),
arrowprops=dict(arrowstyle='->', color=color, lw=1.5))
# ── 1. Drug-Receptor Interaction Overview ─────────────────────────────────────
def make_receptor_diagram():
fig, ax = plt.subplots(figsize=(10, 5.5))
ax.set_xlim(0, 10); ax.set_ylim(0, 5.5)
ax.axis('off')
fig.patch.set_facecolor('#f7fbff')
ax.set_facecolor('#f7fbff')
ax.text(5, 5.15, 'Drug–Receptor Interaction Types', ha='center', va='center',
fontsize=13, fontweight='bold', color=C_DARK_BLUE)
# Central RECEPTOR box
draw_box(ax, 5, 2.7, 1.6, 0.8, 'RECEPTOR', C_DARK_BLUE, fontsize=10, bold=True)
entries = [
(1.2, 4.2, C_GREEN, 'Full Agonist\n(e.g. Morphine)', 'Binds + fully\nactivates'),
(1.2, 2.7, C_TEAL, 'Partial Agonist\n(e.g. Buprenorphine)','Binds + partial\nactivation'),
(1.2, 1.2, C_PURPLE, 'Allosteric Mod.\n(e.g. Benzos)', 'Binds non-active\nsite'),
(8.8, 4.2, C_RED, 'Antagonist\n(e.g. Naloxone)', 'Binds, blocks\nagonist'),
(8.8, 2.7, C_ORANGE, 'Inverse Agonist\n(e.g. Propranolol)', 'Opposite effect\nof agonist'),
(8.8, 1.2, C_DARK_GREY,'No Drug', 'Basal receptor\nactivity'),
]
for (bx, by, col, label, sub) in entries:
draw_box(ax, bx, by, 2.0, 0.75, label, col, fontsize=8, bold=True)
ax.text(bx, by - 0.55, sub, ha='center', va='center', fontsize=7,
color='#333333', style='italic')
# Arrows from boxes to receptor
for (bx, by, *_) in entries[:3]:
arrow(ax, bx + 1.0, by, 4.2, 2.7, color='#777')
for (bx, by, *_) in entries[3:]:
arrow(ax, bx - 1.0, by, 5.8, 2.7, color='#777')
ax.text(3.0, 3.5, 'Activation', fontsize=7.5, color=C_GREEN,
ha='center', style='italic')
ax.text(7.0, 3.5, 'Blockade', fontsize=7.5, color=C_RED,
ha='center', style='italic')
plt.tight_layout(pad=0.3)
path = f"{ASSETS}/receptor_diagram.png"
plt.savefig(path, dpi=160, bbox_inches='tight', facecolor='#f7fbff')
plt.close()
return path
# ── 2. Dose-Response Curve ─────────────────────────────────────────────────────
def make_dose_response_curve():
fig, ax = plt.subplots(figsize=(8, 4.5))
fig.patch.set_facecolor('#f7fbff')
ax.set_facecolor('#f7fbff')
conc = np.logspace(-2, 2, 300)
def hill(c, emax, ec50, n=1):
return emax * c**n / (ec50**n + c**n)
# Drug A - high potency, moderate efficacy
ax.plot(conc, hill(conc, 80, 0.5), color=C_MID_BLUE, lw=2.5, label='Drug A (high potency, moderate efficacy)')
# Drug B - low potency, high efficacy
ax.plot(conc, hill(conc, 100, 5), color=C_GREEN, lw=2.5, label='Drug B (low potency, high efficacy)')
# Drug C - partial agonist
ax.plot(conc, hill(conc, 50, 1), color=C_ORANGE, lw=2.5, linestyle='--', label='Drug C (partial agonist)')
# EC50 annotations
for emax, ec50, color, label in [(80, 0.5, C_MID_BLUE, 'EC₅₀(A)'),
(100, 5.0, C_GREEN, 'EC₅₀(B)')]:
ax.axvline(ec50, ymin=0, ymax=hill(ec50, emax, ec50)/110, color=color, lw=1.2, linestyle=':')
ax.axhline(emax/2, xmin=0, xmax=np.log10(ec50)/4 + 0.5, color=color, lw=1.2, linestyle=':')
ax.text(ec50, -8, label, ha='center', fontsize=8, color=color, fontweight='bold')
ax.axhline(100, color=C_RED, lw=1.2, linestyle='--', alpha=0.6)
ax.text(80, 102, 'Emax (Drug B)', fontsize=8, color=C_RED, alpha=0.8)
ax.axhline(80, color=C_MID_BLUE, lw=1.2, linestyle='--', alpha=0.6)
ax.text(80, 82, 'Emax (Drug A)', fontsize=8, color=C_MID_BLUE, alpha=0.8)
ax.axhline(50, color=C_ORANGE, lw=1.2, linestyle='--', alpha=0.6)
ax.text(80, 52, 'Emax (Drug C - partial)', fontsize=8, color=C_ORANGE, alpha=0.8)
ax.set_xscale('log')
ax.set_xlabel('Drug Concentration (log scale)', fontsize=10)
ax.set_ylabel('Effect (%)', fontsize=10)
ax.set_title('Dose-Response Curves: Potency vs Efficacy', fontsize=12, fontweight='bold', color=C_DARK_BLUE)
ax.set_ylim(-15, 115)
ax.set_xlim(0.01, 100)
ax.legend(fontsize=8, loc='upper left')
ax.grid(True, alpha=0.3)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.tight_layout()
path = f"{ASSETS}/dose_response.png"
plt.savefig(path, dpi=160, bbox_inches='tight', facecolor='#f7fbff')
plt.close()
return path
# ── 3. Therapeutic Index Diagram ──────────────────────────────────────────────
def make_therapeutic_index():
fig, ax = plt.subplots(figsize=(9, 4.5))
fig.patch.set_facecolor('#f7fbff')
ax.set_facecolor('#f7fbff')
conc = np.logspace(-1, 3, 400)
def hill(c, emax, ec50, n=1):
return emax * c**n / (ec50**n + c**n)
# Therapeutic effect
eff = hill(conc, 100, 5)
# Toxic effect
tox = hill(conc, 100, 50)
ax.fill_between(conc, eff, tox, where=(eff >= tox*0 + 5) & (tox <= 50),
alpha=0.2, color=C_GREEN, label='Therapeutic Window')
ax.plot(conc, eff, color=C_GREEN, lw=2.5, label='Therapeutic Effect')
ax.plot(conc, tox, color=C_RED, lw=2.5, label='Toxic Effect')
# ED50 and TD50
ax.axvline(5, color=C_GREEN, lw=1.5, linestyle='--')
ax.axvline(50, color=C_RED, lw=1.5, linestyle='--')
ax.text(5, 55, 'ED₅₀', ha='center', fontsize=9, color=C_GREEN, fontweight='bold')
ax.text(50, 55, 'TD₅₀', ha='center', fontsize=9, color=C_RED, fontweight='bold')
# TI arrow
ax.annotate('', xy=(50, 45), xytext=(5, 45),
arrowprops=dict(arrowstyle='<->', color=C_DARK_BLUE, lw=2))
ax.text(27, 48, 'Therapeutic Index = TD₅₀ / ED₅₀', ha='center', fontsize=8.5,
color=C_DARK_BLUE, fontweight='bold',
bbox=dict(facecolor='white', edgecolor=C_DARK_BLUE, boxstyle='round,pad=0.3'))
ax.set_xscale('log')
ax.set_xlabel('Dose (log scale)', fontsize=10)
ax.set_ylabel('Population Response (%)', fontsize=10)
ax.set_title('Therapeutic Index & Safety Margin', fontsize=12, fontweight='bold', color=C_DARK_BLUE)
ax.set_ylim(0, 105)
ax.legend(fontsize=9, loc='upper left')
ax.grid(True, alpha=0.3)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.tight_layout()
path = f"{ASSETS}/therapeutic_index.png"
plt.savefig(path, dpi=160, bbox_inches='tight', facecolor='#f7fbff')
plt.close()
return path
# ── 4. Factors Modifying Drug Action - Flowchart ──────────────────────────────
def make_factors_flowchart():
fig, ax = plt.subplots(figsize=(12, 8))
ax.set_xlim(0, 12); ax.set_ylim(0, 8)
ax.axis('off')
fig.patch.set_facecolor('#f7fbff')
ax.set_facecolor('#f7fbff')
ax.text(6, 7.6, 'Factors Modifying Drug Action', ha='center', va='center',
fontsize=14, fontweight='bold', color=C_DARK_BLUE)
# Central node
draw_box(ax, 6, 6.5, 2.2, 0.65, 'DRUG ACTION', C_DARK_BLUE, fontsize=11, bold=True)
branches = [
# (box_x, box_y, color, title, examples)
(1.3, 4.8, C_MID_BLUE, 'Physiological\nFactors',
'Age (neonates/elderly)\nGender\nBody weight'),
(3.5, 4.8, C_GREEN, 'Pathological\nFactors',
'Liver disease\nKidney disease\nCVS disease\nThyroid'),
(6.0, 4.8, C_PURPLE, 'Pharmacogenetic\nFactors',
'CYP2D6 / CYP3A4\nP-glycoprotein\nG6PD deficiency'),
(8.5, 4.8, C_ORANGE, 'Environmental\nFactors',
'Diet (grapefruit)\nSmoking\nAlcohol\nTemperature'),
(10.7, 4.8, C_RED, 'Psychological\nFactors',
'Placebo effect\nNocebo effect'),
]
for (bx, by, col, title, examples) in branches:
draw_box(ax, bx, by, 1.9, 0.75, title, col, fontsize=8.5, bold=True)
arrow(ax, bx, by + 0.38, 5.5 + (bx-6)*0.18, 6.18, color='#999')
# Examples box
ex_box = FancyBboxPatch((bx - 1.0, by - 2.05), 2.0, 1.55,
boxstyle="round,pad=0.02", linewidth=0.8,
edgecolor=col, facecolor='white', zorder=3, alpha=0.9)
ax.add_patch(ex_box)
ax.text(bx, by - 1.28, examples, ha='center', va='center', fontsize=7.0,
color='#333333', multialignment='center', zorder=4)
arrow(ax, bx, by - 0.38, bx, by - 0.52, color=col)
# Route box at bottom center
draw_box(ax, 6, 1.0, 2.8, 0.65,
'Route of Administration\nOral | IV | IM / SC', C_TEAL, fontsize=8, bold=True)
arrow(ax, 6, 6.18, 6, 1.33, color='#aaa')
plt.tight_layout(pad=0.3)
path = f"{ASSETS}/factors_flowchart.png"
plt.savefig(path, dpi=150, bbox_inches='tight', facecolor='#f7fbff')
plt.close()
return path
# ── 5. Drug Tolerance / Tachyphylaxis timeline ────────────────────────────────
def make_tolerance_diagram():
fig, ax = plt.subplots(figsize=(9, 4))
fig.patch.set_facecolor('#f7fbff')
ax.set_facecolor('#f7fbff')
doses = [1, 2, 3, 4, 5, 6, 7, 8]
normal_effect = [80, 80, 80, 80, 80, 80, 80, 80]
tolerance_effect= [80, 70, 60, 50, 45, 42, 40, 38]
tachy_effect = [80, 40, 25, 20, 18, 17, 17, 17]
ax.plot(doses, normal_effect, 'o-', color=C_GREEN, lw=2.5, label='No Tolerance (expected)', markersize=6)
ax.plot(doses, tolerance_effect, 's-', color=C_ORANGE, lw=2.5, label='Tolerance (opioids, nitrates)', markersize=6)
ax.plot(doses, tachy_effect, '^-', color=C_RED, lw=2.5, label='Tachyphylaxis (nitrates - rapid)', markersize=6)
ax.fill_between(doses, tolerance_effect, normal_effect, alpha=0.08, color=C_ORANGE)
ax.fill_between(doses, tachy_effect, normal_effect, alpha=0.08, color=C_RED)
ax.set_xlabel('Repeated Dose Number', fontsize=10)
ax.set_ylabel('Drug Effect (%)', fontsize=10)
ax.set_title('Tolerance vs Tachyphylaxis with Repeated Dosing', fontsize=12, fontweight='bold', color=C_DARK_BLUE)
ax.set_ylim(0, 100)
ax.legend(fontsize=9)
ax.grid(True, alpha=0.3)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.tight_layout()
path = f"{ASSETS}/tolerance_diagram.png"
plt.savefig(path, dpi=160, bbox_inches='tight', facecolor='#f7fbff')
plt.close()
return path
# ── 6. Drug Interaction Flowchart ─────────────────────────────────────────────
def make_drug_interaction_flowchart():
fig, ax = plt.subplots(figsize=(11, 6.5))
ax.set_xlim(0, 11); ax.set_ylim(0, 6.5)
ax.axis('off')
fig.patch.set_facecolor('#f7fbff')
ax.set_facecolor('#f7fbff')
ax.text(5.5, 6.15, 'Drug Interactions', ha='center', fontsize=13,
fontweight='bold', color=C_DARK_BLUE)
draw_box(ax, 5.5, 5.4, 2.4, 0.65, 'DRUG INTERACTIONS', C_DARK_BLUE, fontsize=11, bold=True)
# Two main branches
draw_box(ax, 2.5, 4.3, 2.6, 0.65, 'Pharmacokinetic\nInteractions', C_MID_BLUE, fontsize=9, bold=True)
draw_box(ax, 8.5, 4.3, 2.6, 0.65, 'Pharmacodynamic\nInteractions', C_PURPLE, fontsize=9, bold=True)
arrow(ax, 4.3, 5.08, 3.6, 4.63, color='#777')
arrow(ax, 6.7, 5.08, 7.4, 4.63, color='#777')
# PK sub-branches
pk_items = [
(0.9, 2.9, 'Absorption\nAntacids reduce\ntetracycline absorption'),
(2.5, 2.9, 'Metabolism\nRifampin induces CYP\n(oral contraceptives fail)\nKetoconazole inhibits CYP\n(midazolam accumulates)'),
(4.1, 2.9, 'Excretion\nProbenecid inhibits\nrenal excretion of\npenicillin'),
]
for (bx, by, txt) in pk_items:
draw_box(ax, bx, by, 1.5, 0.55, txt.split('\n')[0], C_LIGHT_BLUE, textcolor=C_DARK_BLUE, fontsize=8, bold=True)
lines = txt.split('\n')[1:]
ex_box = FancyBboxPatch((bx-0.75, by-1.65), 1.5, 1.05,
boxstyle="round,pad=0.02", linewidth=0.8,
edgecolor=C_LIGHT_BLUE, facecolor='white', zorder=3)
ax.add_patch(ex_box)
ax.text(bx, by - 1.13, '\n'.join(lines), ha='center', va='center', fontsize=6.8,
color='#333', multialignment='center', zorder=4)
arrow(ax, bx, by - 0.28, bx, by - 0.62, color=C_MID_BLUE)
arrow(ax, 2.5, 4.0, bx, by + 0.28, color='#aaa')
# PD sub-branches
pd_items = [
(7.5, 2.9, 'Synergism\nSulfonamide +\ntrimethoprim\n(combined antibacterial)'),
(9.5, 2.9, 'Antagonism\nNaloxone reverses\nopioid effects;\nflumazenil reverses\nbenzodiazepines'),
]
for (bx, by, txt) in pd_items:
draw_box(ax, bx, by, 1.7, 0.55, txt.split('\n')[0], '#d7bde2', textcolor=C_DARK_BLUE, fontsize=8, bold=True)
lines = txt.split('\n')[1:]
ex_box = FancyBboxPatch((bx-0.85, by-1.65), 1.7, 1.05,
boxstyle="round,pad=0.02", linewidth=0.8,
edgecolor='#d7bde2', facecolor='white', zorder=3)
ax.add_patch(ex_box)
ax.text(bx, by - 1.13, '\n'.join(lines), ha='center', va='center', fontsize=6.8,
color='#333', multialignment='center', zorder=4)
arrow(ax, bx, by - 0.28, bx, by - 0.62, color=C_PURPLE)
arrow(ax, 8.5, 4.0, bx, by + 0.28, color='#aaa')
plt.tight_layout(pad=0.3)
path = f"{ASSETS}/drug_interactions.png"
plt.savefig(path, dpi=150, bbox_inches='tight', facecolor='#f7fbff')
plt.close()
return path
# ── 7. Pharmacogenetics Summary ───────────────────────────────────────────────
def make_pharmacogenetics_diagram():
fig, ax = plt.subplots(figsize=(10, 5))
ax.set_xlim(0, 10); ax.set_ylim(0, 5)
ax.axis('off')
fig.patch.set_facecolor('#f7fbff')
ax.set_facecolor('#f7fbff')
ax.text(5, 4.7, 'Pharmacogenetic Factors', ha='center', fontsize=13,
fontweight='bold', color=C_DARK_BLUE)
items = [
(1.5, 3.5, C_MID_BLUE, 'CYP2D6\nVariants',
'Poor metabolizers of\ncodeine → reduced\nanalgesic effect'),
(3.8, 3.5, C_TEAL, 'CYP3A4\nVariants',
'Altered metabolism\nof many drugs\n(e.g. midazolam,\nstatins)'),
(6.2, 3.5, C_PURPLE, 'P-glycoprotein\n(Drug Transporter)',
'Genetic variation →\naltered digoxin\nabsorption'),
(8.5, 3.5, C_RED, 'G6PD\nDeficiency',
'Hemolysis with\nsulfonamides,\ndapsone,\nantimalarials'),
(3.0, 1.5, C_ORANGE, 'Slow Acetylators\n(NAT2)',
'Isoniazid accumulates\n→ peripheral\nneuropathy'),
(7.0, 1.5, C_GREEN, 'Thyroid Status',
'Hyperthyroid: rapid\nbeta-blocker clearance\nHypothyroid: longer\ndigoxin half-life'),
]
for (bx, by, col, title, detail) in items:
draw_box(ax, bx, by, 1.85, 0.65, title, col, fontsize=8.5, bold=True)
ex_box = FancyBboxPatch((bx-0.92, by-1.55), 1.85, 0.85,
boxstyle="round,pad=0.02", linewidth=0.8,
edgecolor=col, facecolor='white', zorder=3)
ax.add_patch(ex_box)
ax.text(bx, by - 1.13, detail, ha='center', va='center', fontsize=7,
color='#333', multialignment='center', zorder=4)
arrow(ax, bx, by - 0.33, bx, by - 0.72, color=col)
plt.tight_layout(pad=0.3)
path = f"{ASSETS}/pharmacogenetics.png"
plt.savefig(path, dpi=150, bbox_inches='tight', facecolor='#f7fbff')
plt.close()
return path
# ═══════════════════════════════════════════════════════════════════════════════
# PDF BUILDER
# ═══════════════════════════════════════════════════════════════════════════════
def build_pdf():
print("Generating diagrams...")
img_receptor = make_receptor_diagram()
img_dose = make_dose_response_curve()
img_ti = make_therapeutic_index()
img_factors = make_factors_flowchart()
img_tolerance = make_tolerance_diagram()
img_interact = make_drug_interaction_flowchart()
img_pharmgen = make_pharmacogenetics_diagram()
print("All diagrams generated.")
OUT = "/home/daytona/workspace/pharmacodynamics-pdf/Pharmacodynamics_Notes.pdf"
doc = SimpleDocTemplate(
OUT, pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2.2*cm, bottomMargin=2.2*cm
)
styles = getSampleStyleSheet()
# Custom styles
def S(name, **kw):
base = kw.pop('parent', 'Normal')
s = ParagraphStyle(name, parent=styles[base], **kw)
return s
sTitle = S('Title2', fontSize=22, textColor=colors.HexColor(C_DARK_BLUE),
spaceAfter=4, alignment=TA_CENTER, fontName='Helvetica-Bold')
sSubtitle= S('Sub', fontSize=11, textColor=colors.HexColor(C_MID_BLUE),
spaceAfter=12, alignment=TA_CENTER, fontName='Helvetica')
sH1 = S('H1', fontSize=14, textColor=colors.white,
spaceAfter=6, spaceBefore=14, fontName='Helvetica-Bold',
backColor=colors.HexColor(C_DARK_BLUE), leading=20,
leftIndent=-4, rightIndent=-4, borderPadding=(4,6,4,6))
sH2 = S('H2', fontSize=11, textColor=colors.HexColor(C_DARK_BLUE),
spaceAfter=4, spaceBefore=10, fontName='Helvetica-Bold',
borderPadding=(2,4,2,4),
backColor=colors.HexColor(C_LIGHT_BLUE))
sBody = S('Body2', fontSize=9.5, leading=14, spaceAfter=3,
fontName='Helvetica', alignment=TA_JUSTIFY,
textColor=colors.HexColor('#2c3e50'))
sBullet = S('Bul', fontSize=9, leading=13, spaceAfter=2,
fontName='Helvetica', leftIndent=12,
textColor=colors.HexColor('#2c3e50'))
sNote = S('Note', fontSize=8.5, leading=12,
fontName='Helvetica-Oblique',
textColor=colors.HexColor(C_DARK_GREY),
backColor=colors.HexColor('#fdf6e3'),
borderPadding=(4,6,4,6))
sCaption = S('Cap', fontSize=8, leading=10, alignment=TA_CENTER,
fontName='Helvetica-Oblique',
textColor=colors.HexColor(C_DARK_GREY), spaceAfter=8)
def h1(text): return Paragraph(f" {text}", sH1)
def h2(text): return Paragraph(text, sH2)
def body(text): return Paragraph(text, sBody)
def bullet(text): return Paragraph(f"• {text}", sBullet)
def note(text): return Paragraph(f"<i>Note:</i> {text}", sNote)
def sp(n=6): return Spacer(1, n)
def hr(): return HRFlowable(width="100%", thickness=0.5, color=colors.HexColor(C_LIGHT_BLUE), spaceAfter=4)
def caption(text): return Paragraph(text, sCaption)
def img(path, width=15*cm):
im = Image(path, width=width, height=None)
im.hAlign = 'CENTER'
return im
def make_table(headers, rows, col_widths=None):
data = [headers] + rows
t = Table(data, colWidths=col_widths, repeatRows=1)
style = TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor(C_DARK_BLUE)),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 9),
('ALIGN', (0,0), (-1,-1), 'LEFT'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,1), (-1,-1), 8.5),
('ROWBACKGROUNDS', (0,1),(-1,-1), [colors.HexColor('#f0f7ff'), colors.white]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#bdc3c7')),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING',(0,0),(-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
])
t.setStyle(style)
return t
story = []
# ── Cover ────────────────────────────────────────────────────────────────
story.append(Spacer(1, 2*cm))
story.append(Paragraph("PHARMACODYNAMICS", sTitle))
story.append(Paragraph("Comprehensive Study Notes with Diagrams & Flowcharts", sSubtitle))
story.append(hr())
story.append(sp(4))
story.append(body("Pharmacodynamics (PD) is the study of <b>what the drug does to the body</b> — "
"encompassing drug–receptor interactions, dose-response relationships, mechanisms of action, "
"toxicity thresholds, and all factors that modify drug effects in a given patient."))
story.append(sp(8))
# ── Section 1: Drug-Receptor Interactions ─────────────────────────────────
story.append(h1("1. Drug–Receptor Interactions"))
story.append(sp())
story.append(body("Receptors are specific macromolecular sites (usually proteins) where drugs bind to produce their effects. "
"The nature of drug–receptor binding determines the type and magnitude of response."))
story.append(sp(6))
story.append(img(img_receptor, width=15*cm))
story.append(caption("Figure 1. Types of drug–receptor interactions and their functional outcomes."))
story.append(sp(6))
tbl1 = make_table(
['Type', 'Mechanism', 'Clinical Example'],
[
['Full Agonist', 'Binds and fully activates the receptor', 'Morphine (mu-opioid)'],
['Partial Agonist', 'Activates but cannot achieve maximum response (ceiling effect)', 'Buprenorphine'],
['Antagonist', 'Binds receptor, NO activation; blocks agonist', 'Naloxone (opioid OD reversal)'],
['Inverse Agonist', 'Produces the OPPOSITE effect of an agonist', 'Propranolol (beta-blocker)'],
['Allosteric Modulator','Binds non-active site; modifies receptor activity', 'Benzodiazepines on GABA-A receptors'],
],
col_widths=[3.5*cm, 6.5*cm, 5.5*cm]
)
story.append(tbl1)
story.append(sp(4))
# ── Section 2: Dose-Response ──────────────────────────────────────────────
story.append(PageBreak())
story.append(h1("2. Dose-Response Relationships"))
story.append(sp())
story.append(h2("Key Pharmacodynamic Parameters"))
story.append(bullet("<b>Potency</b>: Dose or concentration needed to produce a given effect. Measured by EC₅₀ — lower EC₅₀ = higher potency."))
story.append(bullet("<b>Efficacy (Emax)</b>: Maximum effect a drug can produce, regardless of dose. Ceiling effect for partial agonists."))
story.append(bullet("<b>EC₅₀</b>: Concentration that produces 50% of maximum effect. Used to compare potency between drugs."))
story.append(sp(6))
story.append(img(img_dose, width=14*cm))
story.append(caption("Figure 2. Dose-response curves illustrating potency (horizontal position) and efficacy (maximum height). "
"Drug A is more potent but less efficacious than Drug B. Drug C is a partial agonist with limited Emax."))
story.append(sp(8))
story.append(h2("Hill Equation (Concentration-Effect Relationship)"))
story.append(body("The Hill equation mathematically describes the sigmoidal dose-response curve:"))
story.append(sp(3))
eq_data = [['E = Emax × C^H / (EC₅₀^H + C^H)']]
eq_t = Table(eq_data, colWidths=[14*cm])
eq_t.setStyle(TableStyle([
('ALIGN', (0,0), (-1,-1), 'CENTER'),
('FONTNAME', (0,0), (-1,-1), 'Courier-Bold'),
('FONTSIZE', (0,0), (-1,-1), 11),
('BACKGROUND', (0,0), (-1,-1), colors.HexColor('#eaf4fb')),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING',(0,0),(-1,-1), 8),
('BOX', (0,0), (-1,-1), 1, colors.HexColor(C_MID_BLUE)),
]))
story.append(eq_t)
story.append(sp(4))
story.append(body("where <b>H</b> = Hill coefficient (measure of curve steepness/sigmoidicity). "
"A higher H = steeper curve = narrower therapeutic concentration range."))
story.append(sp(8))
story.append(h2("Variability in Dose-Response"))
tbl2 = make_table(
['Term', 'Definition', 'Example'],
[
['Inter-individual\nvariability', 'Different patients respond differently to the same dose', 'Due to genetics, age, gender, disease'],
['Tachyphylaxis', 'RAPID decrease in drug response with repeated doses', 'Nitrates for angina'],
['Tolerance', 'GRADUAL decrease over time; requires higher doses for same effect', 'Opioids, alcohol'],
['Cross-tolerance','Tolerance to one drug confers tolerance to related drugs', 'Benzodiazepines & alcohol'],
['Hypersensitivity','Exaggerated response to a small dose', 'Allergic/idiosyncratic reactions'],
['Dependence', 'Physical or psychological need for the drug', 'Opioids, benzodiazepines'],
],
col_widths=[3.5*cm, 6.5*cm, 5.5*cm]
)
story.append(tbl2)
# ── Section 3: Therapeutic Index ──────────────────────────────────────────
story.append(PageBreak())
story.append(h1("3. Therapeutic Index & Drug Toxicity"))
story.append(sp())
story.append(img(img_ti, width=14*cm))
story.append(caption("Figure 3. Therapeutic Index = TD₅₀ / ED₅₀. The shaded green zone represents the therapeutic window. "
"Drugs with narrow TI (e.g. digoxin, lithium, warfarin, phenytoin) require plasma level monitoring."))
story.append(sp(6))
tbl3 = make_table(
['Parameter', 'Definition', 'Clinical Relevance'],
[
['ED₅₀', 'Effective Dose in 50% of population', 'Sets the therapeutic dose target'],
['TD₅₀', 'Toxic Dose in 50% of population', 'Upper limit of safe dosing'],
['LD₅₀', 'Lethal Dose in 50% of population (animals)', 'Preclinical safety screening'],
['Therapeutic Index', 'TI = TD₅₀ / ED₅₀ (wide = safer)', 'Narrow TI drugs need TDM'],
['Margin of Safety', 'Difference between therapeutic & toxic dose', 'Guides dose adjustment'],
],
col_widths=[3.5*cm, 6*cm, 6*cm]
)
story.append(tbl3)
story.append(sp(6))
story.append(h2("Narrow Therapeutic Index Drugs — Require Monitoring"))
narrow_ti = [
['Drug', 'Monitored Parameter', 'Risk if Toxic'],
['Digoxin', 'Serum digoxin level', 'Arrhythmia, bradycardia'],
['Lithium', 'Serum lithium', 'Neurotoxicity, renal failure'],
['Warfarin', 'INR', 'Bleeding or thrombosis'],
['Phenytoin', 'Serum level', 'Nystagmus, ataxia, seizures'],
['Aminoglycosides','Trough levels', 'Nephrotoxicity, ototoxicity'],
['Theophylline','Serum level', 'Seizures, arrhythmia'],
]
tbl4 = make_table(narrow_ti[0], narrow_ti[1:], col_widths=[4*cm, 5*cm, 6.5*cm])
story.append(tbl4)
# ── Section 4: Tolerance Diagram ──────────────────────────────────────────
story.append(PageBreak())
story.append(h1("4. Tolerance, Tachyphylaxis & Dependence"))
story.append(sp())
story.append(img(img_tolerance, width=13*cm))
story.append(caption("Figure 4. Drug effect with repeated dosing. Tachyphylaxis (red) shows rapid early loss of effect; "
"tolerance (orange) shows gradual decline over time. Green line = expected effect without tolerance."))
story.append(sp(6))
story.append(note("Key distinction: Tachyphylaxis is RAPID (within doses of the same session, e.g. nitrates), "
"while Tolerance is GRADUAL (develops over days-weeks, e.g. opioids)."))
# ── Section 5: Factors Modifying Drug Action ──────────────────────────────
story.append(PageBreak())
story.append(h1("5. Factors Modifying Drug Action"))
story.append(sp())
story.append(img(img_factors, width=16*cm))
story.append(caption("Figure 5. Overview of all categories of factors that modify drug action."))
story.append(sp(8))
story.append(h2("A. Physiological Factors"))
tbl5 = make_table(
['Factor', 'Mechanism', 'Drug Example'],
[
['Neonates', 'Immature liver enzymes; reduced renal clearance', 'Chloramphenicol → gray baby syndrome; Aminoglycosides'],
['Elderly', 'Decreased liver & kidney function; altered receptor sensitivity','Digoxin accumulation; increased benzodiazepine sensitivity'],
['Gender', 'Hormonal differences in enzyme expression', 'Women metabolize benzodiazepines slower than men'],
['Body Weight', 'Volume of distribution varies; dosing by BSA or weight', 'Chemotherapy drugs, aminoglycosides'],
],
col_widths=[3*cm, 7*cm, 5.5*cm]
)
story.append(tbl5)
story.append(sp(6))
story.append(h2("B. Pathological Factors"))
tbl6 = make_table(
['Disease', 'Effect on Drug', 'Example'],
[
['Liver Disease', 'Reduced metabolism → prolonged drug half-life', 'Warfarin (hepatic dysfunction)'],
['Kidney Disease', 'Impaired excretion of renally eliminated drugs', 'Aminoglycosides, lithium accumulation'],
['Cardiovascular Dis.', 'Reduced perfusion → delayed distribution & elimination', 'Digoxin in heart failure'],
['Hyperthyroidism', 'Increased drug metabolism (CYP enzyme induction)', 'Rapid clearance of beta-blockers'],
['Hypothyroidism', 'Decreased metabolism', 'Prolonged digoxin half-life'],
],
col_widths=[4*cm, 6.5*cm, 5*cm]
)
story.append(tbl6)
# ── Section 6: Pharmacogenetics ───────────────────────────────────────────
story.append(PageBreak())
story.append(h1("6. Pharmacogenetic Factors"))
story.append(sp())
story.append(img(img_pharmgen, width=15*cm))
story.append(caption("Figure 6. Key pharmacogenetic factors and their clinical consequences."))
story.append(sp(6))
tbl7 = make_table(
['Gene/Enzyme', 'Variant Effect', 'Clinical Impact'],
[
['CYP2D6', 'Poor metabolizers: reduced enzyme activity', 'Codeine → inadequate analgesia; toxicity in ultra-rapid metabolizers'],
['CYP3A4', 'Variants alter metabolism of ~50% of all drugs', 'Altered levels of midazolam, statins, ciclosporin'],
['P-glycoprotein', 'Transporter variants alter drug absorption', 'Altered digoxin bioavailability'],
['NAT2 (acetylator)', 'Slow acetylators: reduced INH metabolism', 'Isoniazid → peripheral neuropathy (slow acetylators)'],
['G6PD deficiency', 'Enzyme absent → oxidative stress', 'Hemolysis with sulfonamides, dapsone, primaquine'],
],
col_widths=[3.5*cm, 6*cm, 6*cm]
)
story.append(tbl7)
# ── Section 7: Environmental Factors ─────────────────────────────────────
story.append(PageBreak())
story.append(h1("7. Environmental Factors"))
story.append(sp())
tbl8 = make_table(
['Factor', 'Mechanism', 'Drug Example'],
[
['Grapefruit juice', 'Inhibits intestinal CYP3A4', 'Increased statin, ciclosporin, amlodipine levels'],
['High-fat meal', 'Delays gastric emptying & drug absorption', 'Delayed antacid effect'],
['Smoking', 'Induces CYP1A2', 'Increased theophylline & caffeine clearance'],
['Acute alcohol', 'Inhibits drug metabolism; additive CNS depression','Potentiates sedatives, opioids'],
['Chronic alcohol', 'Induces CYP enzymes (especially CYP2E1)', 'Increased warfarin metabolism; reduced drug levels'],
['Heat', 'Increases peripheral blood flow', 'Enhanced transdermal and SC drug absorption'],
],
col_widths=[3.5*cm, 6.5*cm, 5.5*cm]
)
story.append(tbl8)
story.append(sp(8))
story.append(h2("Route of Administration"))
tbl9 = make_table(
['Route', 'Key Feature', 'Clinical Example'],
[
['Oral (PO)', 'Subject to first-pass metabolism; reduced bioavailability', 'Propranolol (high first-pass)'],
['Intravenous (IV)', 'Rapid onset; 100% bioavailability; no first-pass', 'Emergency drugs, antibiotics'],
['Intramuscular (IM)','Bioavailability depends on blood flow & drug solubility', 'Vaccines, IM antibiotics'],
['Subcutaneous (SC)', 'Slower absorption than IM; depot preparations possible', 'Insulin, heparin, enoxaparin'],
['Sublingual', 'Avoids first-pass; rapid absorption via oral mucosa', 'GTN for angina'],
],
col_widths=[3.5*cm, 7*cm, 5*cm]
)
story.append(tbl9)
# ── Section 8: Drug Interactions ─────────────────────────────────────────
story.append(PageBreak())
story.append(h1("8. Drug Interactions"))
story.append(sp())
story.append(img(img_interact, width=15.5*cm))
story.append(caption("Figure 7. Classification of drug interactions into pharmacokinetic and pharmacodynamic types."))
story.append(sp(6))
tbl10 = make_table(
['Type', 'Stage', 'Mechanism', 'Example'],
[
['Pharmacokinetic', 'Absorption', 'Chelation or pH change', 'Antacids reduce tetracycline absorption'],
['Pharmacokinetic', 'Metabolism', 'CYP enzyme induction', 'Rifampin induces CYP → oral contraceptive failure'],
['Pharmacokinetic', 'Metabolism', 'CYP enzyme inhibition', 'Ketoconazole inhibits CYP3A4 → midazolam accumulates'],
['Pharmacokinetic', 'Excretion', 'Renal transporter competition', 'Probenecid inhibits penicillin excretion'],
['Pharmacodynamic', 'Receptor', 'Synergism (combined action)', 'Sulfonamide + trimethoprim (co-trimoxazole)'],
['Pharmacodynamic', 'Receptor', 'Antagonism (reversal of effect)', 'Naloxone reverses opioids; flumazenil reverses benzos'],
],
col_widths=[3*cm, 2.5*cm, 5*cm, 5*cm]
)
story.append(tbl10)
# ── Section 9: Disease-Specific & Psychological Factors ──────────────────
story.append(PageBreak())
story.append(h1("9. Disease-Specific & Psychological Factors"))
story.append(sp(4))
story.append(h2("Disease-Specific Factors"))
tbl11 = make_table(
['Condition', 'Effect on Drug Action', 'Example'],
[
['Infection / Inflammation', 'Altered drug distribution; acidic environment reduces drug activity', 'Aminoglycosides less effective in acidic abscesses'],
['Malnutrition', 'Reduced plasma proteins → more free (active) drug', 'Hypoalbuminemia → increased free phenytoin'],
],
col_widths=[4*cm, 7*cm, 4.5*cm]
)
story.append(tbl11)
story.append(sp(8))
story.append(h2("Psychological Factors"))
tbl12 = make_table(
['Factor', 'Definition', 'Clinical Implication'],
[
['Placebo Effect', 'Positive therapeutic response due to patient belief in treatment',
'Up to 30% response rate in clinical trials; important in pain and depression'],
['Nocebo Effect', 'Negative outcomes caused by patient expectations of adverse effects',
'Patients who expect side effects are more likely to experience them'],
],
col_widths=[3.5*cm, 6.5*cm, 5.5*cm]
)
story.append(tbl12)
story.append(sp(8))
# ── Section 10: Quick Reference ───────────────────────────────────────────
story.append(PageBreak())
story.append(h1("10. Quick Reference Summary"))
story.append(sp())
story.append(h2("Key Drug Examples by Concept"))
tbl13 = make_table(
['Concept', 'Drug(s)', 'Note'],
[
['Partial agonist', 'Buprenorphine', 'Ceiling effect — safer in overdose'],
['Opioid antagonist', 'Naloxone', 'Reverses opioid OD'],
['Beta-inverse agonist', 'Propranolol', 'Reduces basal sympathetic tone'],
['Allosteric modulator', 'Benzodiazepines', 'Enhance GABA-A Cl⁻ conductance'],
['Narrow TI — monitor', 'Digoxin, Lithium, Warfarin, PHT', 'TDM essential'],
['Gray baby syndrome', 'Chloramphenicol', 'Immature UDP-glucuronosyl transferase in neonates'],
['CYP3A4 inhibitor (dietary)', 'Grapefruit', 'Increases statin, CCB, ciclosporin levels'],
['CYP1A2 inducer', 'Smoking', 'Reduces theophylline levels'],
['G6PD hemolysis', 'Sulfonamides, Dapsone, Primaquine','Screen G6PD before prescribing'],
['Slow acetylators', 'Isoniazid', 'Peripheral neuropathy; give pyridoxine'],
['Excretion interaction', 'Probenecid + Penicillin', 'Prolongs penicillin action'],
['Synergism example', 'Co-trimoxazole', 'Sulfonamide + trimethoprim'],
['Tachyphylaxis example', 'Nitrates (GTN)', 'Continuous use → rapid tolerance'],
['Tolerance example', 'Opioids, Benzodiazepines', 'Gradual dose escalation required'],
],
col_widths=[5*cm, 5*cm, 5.5*cm]
)
story.append(tbl13)
story.append(sp(8))
story.append(hr())
story.append(sp(4))
story.append(note("Sources: Rosen's Emergency Medicine; Brenner and Rector's The Kidney (11e); "
"Schwartz's Principles of Surgery (11e); Course notes HomUG-Mod.Phar (3.2–3.3)."))
print("Building PDF...")
doc.build(story)
print(f"PDF saved to: {OUT}")
return OUT
if __name__ == "__main__":
build_pdf()
cd /home/daytona/workspace/pharmacodynamics-pdf && python generate_pd_pdf.py 2>&…
cd /home/daytona/workspace/pharmacodynamics-pdf && python3 -c " from PIL import …
~/pharmacodynamics-pdf/generate_pd_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/pharmacodynamics-pdf/generate_pd_pdf.py'
cd /home/daytona/workspace/pharmacodynamics-pdf && python generate_pd_pdf.py 2>&…
ls -lh /home/daytona/workspace/pharmacodynamics-pdf/Pharmacodynamics_Notes.pdf
Pharmacodynamics Notes
PDF Document · PDF
| Section | Content | Visual |
|---|---|---|
| 1. Drug-Receptor Interactions | Full/partial agonist, antagonist, inverse agonist, allosteric modulators | Diagram with labeled arrows |
| 2. Dose-Response Relationships | Potency, efficacy, EC₅₀, Hill equation | Sigmoidal dose-response curves (3 drugs) |
| 3. Therapeutic Index & Toxicity | TD₅₀, LD₅₀, ED₅₀, TI, margin of safety | Therapeutic window graph with annotation |
| 4. Tolerance & Tachyphylaxis | Definitions, cross-tolerance, dependence | Timeline comparison graph |
| 5. Factors Modifying Drug Action | All 6 categories summarized | Color-coded flowchart |
| 6. Pharmacogenetic Factors | CYP2D6/3A4, P-gp, G6PD, NAT2 | Visual summary diagram |
| 7. Environmental Factors | Diet, smoking, alcohol, temperature, route of admin | Detailed table |
| 8. Drug Interactions | PK (absorption/metabolism/excretion) + PD (synergism/antagonism) | Two-branch flowchart |
| 9. Disease-Specific & Psychological | Infection, malnutrition, placebo/nocebo | Table |
| 10. Quick Reference | 14-row key drug-by-concept master table | - |
Prepare notes with visual diagram and photos with flowchart in esay to understand for topic
mkdir -p /home/daytona/workspace/ans-autacoids-pdf/assets && echo "OK"
~/ans-autacoids-pdf/generate_ans_pdf.py
"""
ANS & Autacoids - Module 4.1 Study Notes PDF Generator
Includes: Cholinergic, Adrenergic, Serotonin, Histamine, Migraine
"""
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import FancyBboxPatch
import numpy as np
import os
from PIL import Image as PILImage
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
Image, HRFlowable, PageBreak
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
ASSETS = "/home/daytona/workspace/ans-autacoids-pdf/assets"
# ─── COLORS ───────────────────────────────────────────────────────────────────
C_NAVY = "#1a3a5c"
C_BLUE = "#2980b9"
C_LBLUE = "#d6eaf8"
C_GREEN = "#27ae60"
C_LGREEN = "#d5f5e3"
C_RED = "#e74c3c"
C_LRED = "#fadbd8"
C_ORANGE = "#e67e22"
C_LORANGE = "#fdebd0"
C_PURPLE = "#8e44ad"
C_TEAL = "#16a085"
C_YELLOW = "#f39c12"
C_GREY = "#ecf0f1"
C_DARK = "#2c3e50"
def box(ax, x, y, w, h, text, fc, tc='white', fs=8.5, bold=False, ec='white', lw=1.2):
p = FancyBboxPatch((x-w/2, y-h/2), w, h,
boxstyle="round,pad=0.025", lw=lw,
edgecolor=ec, facecolor=fc, zorder=3)
ax.add_patch(p)
ax.text(x, y, text, ha='center', va='center', fontsize=fs,
color=tc, fontweight='bold' if bold else 'normal',
multialignment='center', zorder=4)
def arr(ax, x1, y1, x2, y2, col='#777', lw=1.5):
ax.annotate('', xy=(x2,y2), xytext=(x1,y1),
arrowprops=dict(arrowstyle='->', color=col, lw=lw))
def save(fig, name, dpi=155):
p = f"{ASSETS}/{name}.png"
plt.tight_layout(pad=0.3)
plt.savefig(p, dpi=dpi, bbox_inches='tight', facecolor=fig.get_facecolor())
plt.close()
return p
# ═══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 1 — ANS Overview (Sympathetic vs Parasympathetic)
# ═══════════════════════════════════════════════════════════════════════════════
def make_ans_overview():
fig, ax = plt.subplots(figsize=(13, 7))
ax.set_xlim(0,13); ax.set_ylim(0,7); ax.axis('off')
fig.patch.set_facecolor('#f0f4f8'); ax.set_facecolor('#f0f4f8')
ax.text(6.5, 6.65, 'Autonomic Nervous System (ANS) — Overview',
ha='center', fontsize=14, fontweight='bold', color=C_NAVY)
# Central CNS box
box(ax, 6.5, 5.8, 2.4, 0.65, 'CNS (Brain/Spinal Cord)', C_NAVY, fs=10, bold=True)
# Two branches
box(ax, 2.5, 4.4, 3.2, 0.7, 'PARASYMPATHETIC\n"Rest & Digest"', C_GREEN, fs=9, bold=True)
box(ax, 10.5, 4.4, 3.2, 0.7, 'SYMPATHETIC\n"Fight or Flight"', C_RED, fs=9, bold=True)
arr(ax, 5.3, 5.5, 4.0, 4.75, C_GREEN)
arr(ax, 7.7, 5.5, 9.0, 4.75, C_RED)
# Neurotransmitters
box(ax, 2.5, 3.2, 3.2, 0.6, 'Preganglionic: ACh\nPostganglionic: ACh', C_TEAL, fs=8)
box(ax, 10.5, 3.2, 3.2, 0.6, 'Preganglionic: ACh\nPostganglionic: NE (NorAdr)', '#c0392b', fs=8)
arr(ax, 2.5, 4.05, 2.5, 3.5, C_GREEN)
arr(ax, 10.5, 4.05, 10.5, 3.5, C_RED)
# Receptors
box(ax, 1.2, 2.1, 2.0, 0.65, 'Muscarinic (M)\nReceptors', '#1abc9c', fs=8, bold=True)
box(ax, 3.8, 2.1, 2.0, 0.65, 'Nicotinic (N)\nReceptors', '#148f77', fs=8, bold=True)
box(ax, 9.2, 2.1, 2.0, 0.65, 'α1, α2\nReceptors', '#e74c3c', fs=8, bold=True)
box(ax, 11.8, 2.1, 2.0, 0.65, 'β1, β2, β3\nReceptors', '#c0392b', fs=8, bold=True)
arr(ax, 2.5, 2.9, 1.2, 2.42, C_TEAL)
arr(ax, 2.5, 2.9, 3.8, 2.42, C_TEAL)
arr(ax, 10.5, 2.9, 9.2, 2.42, '#c0392b')
arr(ax, 10.5, 2.9, 11.8, 2.42, '#c0392b')
# Effects
para_eff = ['↓ HR (bradycardia)', '↑ GI motility', 'Bronchoconstriction', 'Miosis (pupil)', 'Lacrimation/Salivation']
symp_eff = ['↑ HR (tachycardia)', '↑ BP (vasoconstriction)', 'Bronchodilation', 'Mydriasis (pupil)', 'Glycogenolysis']
for i, txt in enumerate(para_eff):
ax.text(2.5, 1.35 - i*0.24, f'• {txt}', ha='center', fontsize=7.2, color=C_GREEN)
for i, txt in enumerate(symp_eff):
ax.text(10.5, 1.35 - i*0.24, f'• {txt}', ha='center', fontsize=7.2, color=C_RED)
ax.text(2.5, 1.55, 'PSNS Effects:', ha='center', fontsize=8, fontweight='bold', color=C_GREEN)
ax.text(10.5, 1.55, 'SNS Effects:', ha='center', fontsize=8, fontweight='bold', color=C_RED)
# Drugs legend
ax.text(2.5, 0.35, 'Drugs: Pilocarpine, Neostigmine, Atropine, Scopolamine',
ha='center', fontsize=7.5, color=C_TEAL, style='italic',
bbox=dict(facecolor='#e8f8f5', boxstyle='round,pad=0.2', edgecolor=C_TEAL, lw=0.7))
ax.text(10.5, 0.35, 'Drugs: Epinephrine, Salbutamol, Atenolol, Prazosin',
ha='center', fontsize=7.5, color='#c0392b', style='italic',
bbox=dict(facecolor='#fdedec', boxstyle='round,pad=0.2', edgecolor='#c0392b', lw=0.7))
return save(fig, 'ans_overview')
# ═══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 2 — Cholinergic Drug Flowchart
# ═══════════════════════════════════════════════════════════════════════════════
def make_cholinergic():
fig, ax = plt.subplots(figsize=(13, 8.5))
ax.set_xlim(0,13); ax.set_ylim(0,8.5); ax.axis('off')
fig.patch.set_facecolor('#f0f8f4'); ax.set_facecolor('#f0f8f4')
ax.text(6.5, 8.15, 'Cholinergic & Anticholinergic Drugs', ha='center',
fontsize=14, fontweight='bold', color=C_NAVY)
# Root
box(ax, 6.5, 7.3, 3.0, 0.65, 'ACETYLCHOLINE (ACh)\nParasympathetic NT', C_NAVY, fs=10, bold=True)
# Two branches
box(ax, 2.5, 6.1, 3.2, 0.7, 'CHOLINERGIC DRUGS\n(Mimic ACh)', C_GREEN, fs=9, bold=True)
box(ax, 10.5, 6.1, 3.2, 0.7, 'ANTICHOLINERGIC DRUGS\n(Block ACh)', C_RED, fs=9, bold=True)
arr(ax, 5.0, 7.0, 4.1, 6.45, C_GREEN)
arr(ax, 8.0, 7.0, 9.0, 6.45, C_RED)
# Cholinergic sub-types
box(ax, 1.3, 4.8, 2.4, 0.65, 'Direct-Acting\n(Muscarinic)', C_TEAL, fs=8, bold=True)
box(ax, 3.7, 4.8, 2.4, 0.65, 'Indirect-Acting\n(AChE Inhibitors)', '#1a7a56', fs=8, bold=True)
arr(ax, 2.5, 5.75, 1.3, 5.13, C_GREEN)
arr(ax, 2.5, 5.75, 3.7, 5.13, C_GREEN)
# Direct acting details
direct = ['Pilocarpine → Glaucoma', 'Bethanechol → Urinary retention', 'Carbachol → Glaucoma/miosis', 'Methacholine → Asthma test']
for i, t in enumerate(direct):
ax.text(1.3, 4.25 - i*0.28, f'• {t}', ha='center', fontsize=6.8, color=C_DARK)
ax.text(1.3, 4.3, '', ha='center')
# Indirect acting details
indirect = ['Neostigmine → Myasthenia gravis', 'Physostigmine → Glaucoma', 'Pyridostigmine → MG (long-acting)', 'Donepezil → Alzheimer\'s', 'Organophosphates → Pesticides']
for i, t in enumerate(indirect):
ax.text(3.7, 4.25 - i*0.28, f'• {t}', ha='center', fontsize=6.8, color=C_DARK)
# Nicotinic agonists
box(ax, 2.5, 2.5, 3.2, 0.55, 'Nicotinic Agonists', '#0e6655', fs=8, bold=True)
ax.text(2.5, 2.1, '• Nicotine → ganglion stimulation', ha='center', fontsize=7, color=C_DARK)
ax.text(2.5, 1.85, '• Succinylcholine → NMJ (surgical paralysis)', ha='center', fontsize=7, color=C_DARK)
# Anticholinergic sub-types
box(ax, 10.5, 4.8, 3.2, 0.65, 'Muscarinic Antagonists\n(Block M-receptors)', '#c0392b', fs=8, bold=True)
arr(ax, 10.5, 5.75, 10.5, 5.13, C_RED)
anti_drugs = [
('Atropine', 'Bradycardia, organophosphate OD, pre-op'),
('Scopolamine', 'Motion sickness (transdermal patch)'),
('Ipratropium', 'COPD, asthma (inhaled bronchodilator)'),
('Tiotropium', 'COPD (long-acting inhaled)'),
('Oxybutynin', 'Overactive bladder'),
('Glycopyrrolate','Reduces secretions (pre-op)'),
('Benztropine', 'Parkinson\'s (extra-pyramidal effects)'),
]
for i, (drug, use) in enumerate(anti_drugs):
y = 4.15 - i*0.31
ax.text(8.8, y, f'• {drug}:', fontsize=7.2, color=C_RED, fontweight='bold')
ax.text(9.65, y, use, fontsize=6.8, color=C_DARK)
# Adverse effects
box(ax, 2.5, 1.3, 3.8, 0.55, 'Cholinergic Side Effects (DUMBELS mnemonic)', C_GREEN, tc='white', fs=7.5, bold=True)
dumbels = 'D=Defecation/Diarrhea U=Urination M=Miosis B=Bradycardia\nE=Emesis L=Lacrimation S=Salivation/Sweating'
ax.text(2.5, 0.85, dumbels, ha='center', fontsize=7.2, color=C_DARK, multialignment='center')
box(ax, 10.5, 1.3, 4.0, 0.55, 'Anticholinergic Side Effects (Anti-DUMBELS)', C_RED, tc='white', fs=7.5, bold=True)
anti_se = 'Dry mouth Blurred vision Urinary retention\nConstipation Tachycardia Confusion (elderly)'
ax.text(10.5, 0.85, anti_se, ha='center', fontsize=7.2, color=C_DARK, multialignment='center')
return save(fig, 'cholinergic')
# ═══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 3 — Adrenergic Receptor Map
# ═══════════════════════════════════════════════════════════════════════════════
def make_adrenergic():
fig, ax = plt.subplots(figsize=(13, 8))
ax.set_xlim(0,13); ax.set_ylim(0,8); ax.axis('off')
fig.patch.set_facecolor('#fff8f0'); ax.set_facecolor('#fff8f0')
ax.text(6.5, 7.7, 'Adrenergic & Antiadrenergic Drugs', ha='center',
fontsize=14, fontweight='bold', color=C_NAVY)
# Central
box(ax, 6.5, 6.9, 3.0, 0.65, 'CATECHOLAMINES\nEpinephrine • NE • Dopamine', C_NAVY, fs=9, bold=True)
# 4 receptor branches
receptors = [
(1.6, 5.6, 'α1 Receptor\n(Post-synaptic)', '#8e44ad'),
(4.4, 5.6, 'α2 Receptor\n(Pre-synaptic)', '#6c3483'),
(8.6, 5.6, 'β1 Receptor\n(Heart)', '#e74c3c'),
(11.4, 5.6, 'β2 Receptor\n(Lungs/Vessels)', '#c0392b'),
]
for (rx, ry, label, col) in receptors:
box(ax, rx, ry, 2.5, 0.65, label, col, fs=8.5, bold=True)
arr(ax, 6.5, 6.57, rx, 5.93, col)
# Effects per receptor
effects = [
(1.6, ['Vasoconstriction', 'Pupil dilation (mydriasis)', 'Urinary sphincter contraction', '↑ Blood Pressure']),
(4.4, ['Inhibits NE release\n(autoreceptor)', 'Reduces sympathetic tone', '↓ BP (central action)', 'Analgesia (spinal)']),
(8.6, ['↑ Heart Rate (+ chronotropy)', '↑ Contractility (+ inotropy)', '↑ AV conduction speed', 'Renin release']),
(11.4, ['Bronchodilation', 'Vasodilation (skeletal muscle)', 'Uterine relaxation', 'Glycogenolysis']),
]
for i, (rx, effs) in enumerate(effects):
col = receptors[i][3]
for j, e in enumerate(effs):
ax.text(rx, 4.85 - j*0.3, f'• {e}', ha='center', fontsize=6.8, color=C_DARK)
# Agonist drugs
ax.text(1.6, 3.55, 'AGONISTS:', ha='center', fontsize=7.5, fontweight='bold', color='#8e44ad')
ax.text(1.6, 3.25, 'Phenylephrine (nasal decongestant)\nNorepinephrine (shock)',
ha='center', fontsize=7, color=C_DARK, multialignment='center')
ax.text(4.4, 3.55, 'AGONISTS:', ha='center', fontsize=7.5, fontweight='bold', color='#6c3483')
ax.text(4.4, 3.25, 'Clonidine (hypertension, ADHD)\nMethyldopa (pregnancy HTN)',
ha='center', fontsize=7, color=C_DARK, multialignment='center')
ax.text(8.6, 3.55, 'AGONISTS → Antagonists:', ha='center', fontsize=7.5, fontweight='bold', color=C_RED)
ax.text(8.6, 3.25, 'Dobutamine, Dopamine (agonists)\nMetoprolol, Atenolol → β1-blockers\nHF, HTN, Arrhythmia',
ha='center', fontsize=7, color=C_DARK, multialignment='center')
ax.text(11.4, 3.55, 'AGONISTS:', ha='center', fontsize=7.5, fontweight='bold', color='#c0392b')
ax.text(11.4, 3.25, 'Salbutamol (asthma - SABA)\nFormoterol (asthma - LABA)\nSalmeterol (COPD/asthma)',
ha='center', fontsize=7, color=C_DARK, multialignment='center')
# Antagonist bar
box(ax, 3.0, 2.1, 5.5, 0.6, 'α-BLOCKERS (Antiadrenergic)', '#8e44ad', fs=9, bold=True)
box(ax, 10.0, 2.1, 5.5, 0.6, 'β-BLOCKERS (Antiadrenergic)', C_RED, fs=9, bold=True)
ax.text(3.0, 1.65, 'Prazosin, Doxazosin → HTN, BPH (α1-selective)\nPhentolamine → Pheochromocytoma (non-selective)\nYohimbine → α2-blocker',
ha='center', fontsize=7.2, color=C_DARK, multialignment='center')
ax.text(10.0, 1.65, 'Metoprolol, Atenolol → HTN, angina, HF (β1-selective)\nPropranolol → Arrhythmia, thyrotoxicosis (non-selective)\nCarvedilol → α+β blocker (HF)',
ha='center', fontsize=7.2, color=C_DARK, multialignment='center')
# Clinical use table at bottom
box(ax, 6.5, 0.45, 12.5, 0.55, 'Asthma: β2 agonist | Hypertension: β1 blocker / α1 blocker | Shock: α1 agonist + dopamine | HF: β1 blocker (carvedilol)',
C_NAVY, fs=8, bold=True)
return save(fig, 'adrenergic')
# ═══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 4 — Serotonin System & Drugs
# ═══════════════════════════════════════════════════════════════════════════════
def make_serotonin():
fig, ax = plt.subplots(figsize=(13, 8))
ax.set_xlim(0,13); ax.set_ylim(0,8); ax.axis('off')
fig.patch.set_facecolor('#f5f0fa'); ax.set_facecolor('#f5f0fa')
ax.text(6.5, 7.7, 'Serotonin (5-HT) System & Serotonergic Drugs',
ha='center', fontsize=14, fontweight='bold', color=C_NAVY)
# Serotonin synthesis
box(ax, 6.5, 6.9, 3.5, 0.65, 'Tryptophan → 5-HTP → 5-HT (Serotonin)\nStored in CNS neurons & GI enterochromaffin cells', C_PURPLE, fs=8.5, bold=True)
# Receptors
recs = [
(1.5, 5.7, '5-HT₁\n(A/B/D/E/F)', '#7d3c98'),
(4.5, 5.7, '5-HT₂\n(A/B/C)', '#8e44ad'),
(7.5, 5.7, '5-HT₃\n(Ion channel)', '#9b59b6'),
(10.5, 5.7, '5-HT₄\n(GI motility)', '#a569bd'),
]
for (rx, ry, label, col) in recs:
box(ax, rx, ry, 2.3, 0.65, label, col, fs=9, bold=True)
arr(ax, 6.5, 6.57, rx, 6.03, col)
# Effects per receptor
rec_effs = [
(1.5, ['Vasoconstriction (B/D)', 'Anxiolysis (1A)', 'Migraine target (1B/1D)', 'Inhibitory autoreceptor']),
(4.5, ['Platelet aggregation', 'Vasoconstriction', 'Hallucinogen target', 'Mood regulation']),
(7.5, ['Nausea/vomiting\n(CTZ activation)', 'GI peristalsis', 'Peripheral pain', 'Target for antiemetics']),
(10.5, ['↑ GI motility', 'Prokinetic target', 'Cardiac effects', 'IBS therapy target']),
]
for i, (rx, effs) in enumerate(rec_effs):
for j, e in enumerate(effs):
ax.text(rx, 4.95 - j*0.3, f'• {e}', ha='center', fontsize=6.8, color=C_DARK)
# Drug boxes
drug_rows = [
(1.5, 3.3, '#7d3c98', 'SSRIs\n(5-HT reuptake inhibitors)',
'Fluoxetine, Sertraline,\nParoxetine, Citalopram\nUse: Depression, OCD, anxiety'),
(4.5, 3.3, '#8e44ad', 'SNRIs',
'Venlafaxine, Duloxetine\nUse: Depression, anxiety,\nneuropathic pain'),
(7.5, 3.3, '#9b59b6', '5-HT₃ Antagonists\n(Antiemetics)',
'Ondansetron, Granisetron\nUse: Chemo/post-op nausea\n★ Most important antiemetic'),
(10.5, 3.3, '#a569bd', 'Triptans\n(5-HT₁B/D agonists)',
'Sumatriptan, Zolmitriptan,\nFrovatriptan, Rizatriptan\nUse: Acute migraine'),
]
for (dx, dy, col, title, detail) in drug_rows:
box(ax, dx, dy, 2.5, 0.65, title, col, fs=7.5, bold=True)
arr(ax, dx, dy - 0.33, dx, dy - 0.55, col)
bx = FancyBboxPatch((dx-1.25, dy-1.65), 2.5, 1.0,
boxstyle='round,pad=0.02', lw=0.8,
edgecolor=col, facecolor='white', zorder=3)
ax.add_patch(bx)
ax.text(dx, dy - 1.15, detail, ha='center', va='center', fontsize=6.8,
color=C_DARK, multialignment='center', zorder=4)
# Bottom note
box(ax, 6.5, 0.45, 12.5, 0.55,
'Serotonin Syndrome: Hyperthermia + Clonus + Agitation — seen with SSRI + MAOi combinations',
'#922b21', fs=8, bold=True)
return save(fig, 'serotonin')
# ═══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 5 — Migraine Pathophysiology & Treatment Flowchart
# ═══════════════════════════════════════════════════════════════════════════════
def make_migraine():
fig, ax = plt.subplots(figsize=(13, 9))
ax.set_xlim(0,13); ax.set_ylim(0,9); ax.axis('off')
fig.patch.set_facecolor('#fffaf0'); ax.set_facecolor('#fffaf0')
ax.text(6.5, 8.7, 'Migraine: Pathophysiology & Treatment', ha='center',
fontsize=14, fontweight='bold', color=C_NAVY)
# Pathophysiology chain
steps = [
(1.3, 7.7, 'TRIGGER\n(stress, food,\nhormones, sleep)', C_ORANGE),
(3.6, 7.7, 'Cortical Spreading\nDepression (CSD)', '#d68910'),
(6.0, 7.7, 'Trigeminal Nerve\nActivation', '#ca6f1e'),
(8.4, 7.7, 'CGRP Release\n(vasodilation &\nneuroinflammation)', '#ba4a00'),
(11.0, 7.7, 'PAIN\n(throbbing,\nunilateral)', C_RED),
]
for i, (sx, sy, label, col) in enumerate(steps):
box(ax, sx, sy, 2.2, 0.75, label, col, fs=8, bold=True)
if i < len(steps)-1:
arr(ax, sx+1.1, sy, steps[i+1][0]-1.1, sy, col)
# Serotonin role
ax.text(6.0, 6.9, '↓ Serotonin levels trigger migraine', ha='center',
fontsize=8.5, color=C_PURPLE, fontweight='bold', style='italic')
ax.text(6.0, 6.65, '5-HT₁B/D agonists (triptans) → reverse vasoconstriction + block CGRP release',
ha='center', fontsize=7.5, color=C_PURPLE)
# Migraine types
box(ax, 3.2, 5.9, 5.5, 0.6, 'Migraine WITH Aura (Classic)', '#2471a3', fs=8.5, bold=True)
box(ax, 9.8, 5.9, 5.5, 0.6, 'Migraine WITHOUT Aura (Common)', '#1a5276', fs=8.5, bold=True)
ax.text(3.2, 5.4, '• Visual disturbances before headache\n• Zig-zag lines, blind spots\n• Duration: 20-60 min\n• Higher stroke risk', ha='center', fontsize=7.5, color=C_DARK, multialignment='center')
ax.text(9.8, 5.4, '• Most common type (75%)\n• No preceding aura\n• Sudden onset pulsating pain\n• Nausea, photophobia', ha='center', fontsize=7.5, color=C_DARK, multialignment='center')
# ACUTE treatment box
box(ax, 3.2, 3.85, 5.5, 0.65, '⚡ ACUTE TREATMENT\n(Abort the attack)', C_RED, fs=9, bold=True)
acute_drugs = [
('NSAIDs', 'Ibuprofen, Naproxen — first-line for mild-moderate'),
('Triptans', 'Sumatriptan, Zolmitriptan — 5-HT₁B/D agonist, first-line for moderate-severe'),
('Ergot Alkaloids', 'Ergotamine, DHE — 5-HT + α receptor — reserve for refractory'),
('Antiemetics', 'Ondansetron, Metoclopramide — treat nausea'),
('CGRP antagonists', 'Ubrogepant, Rimegepant — newest class, no vasoconstriction risk'),
('Ditans', 'Lasmiditan — 5-HT₁F agonist — no cardiovascular contraindication'),
]
for i, (drug, detail) in enumerate(acute_drugs):
ax.text(0.4, 3.25 - i*0.33, f'• {drug}:', fontsize=7.5, color=C_RED, fontweight='bold')
ax.text(2.0, 3.25 - i*0.33, detail, fontsize=7, color=C_DARK)
# PREVENTIVE treatment box
box(ax, 9.8, 3.85, 5.5, 0.65, '🛡 PREVENTIVE TREATMENT\n(Reduce frequency)', C_GREEN, fs=9, bold=True)
prev_drugs = [
('Beta-blockers', 'Propranolol, Metoprolol — first-line preventive'),
('Anticonvulsants', 'Valproate, Topiramate — reduce excitability'),
('TCAs', 'Amitriptyline — especially if comorbid depression/sleep issues'),
('Ca²⁺ Ch. Blockers', 'Flunarizine, Verapamil — reduce vasospasm'),
('CGRP mAbs', 'Erenumab, Fremanezumab — injected monthly, very effective'),
('Botox (OnabotulinumtoxinA)', '— chronic migraine (≥15 days/month)'),
]
for i, (drug, detail) in enumerate(prev_drugs):
ax.text(7.1, 3.25 - i*0.33, f'• {drug}:', fontsize=7.5, color=C_GREEN, fontweight='bold')
ax.text(9.1, 3.25 - i*0.33, detail, fontsize=7, color=C_DARK)
# Important notes
box(ax, 6.5, 0.55, 12.5, 0.65,
'⚠ Ergotamine + Triptans — NEVER combine (vasospasm risk) | Triptans contraindicated in CAD, stroke, uncontrolled HTN',
'#922b21', fs=8, bold=True)
return save(fig, 'migraine')
# ═══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 6 — Histamine & Antihistamines
# ═══════════════════════════════════════════════════════════════════════════════
def make_histamine():
fig, ax = plt.subplots(figsize=(13, 7.5))
ax.set_xlim(0,13); ax.set_ylim(0,7.5); ax.axis('off')
fig.patch.set_facecolor('#fff5f0'); ax.set_facecolor('#fff5f0')
ax.text(6.5, 7.2, 'Histamine Receptors & Antihistamine Drugs',
ha='center', fontsize=14, fontweight='bold', color=C_NAVY)
# Histamine source
box(ax, 6.5, 6.4, 3.5, 0.65, 'HISTAMINE\n(from mast cells, basophils, enterochromaffin)', C_NAVY, fs=9, bold=True)
# 4 Receptors
h_recs = [
(1.6, 5.2, 'H₁ Receptor', C_RED),
(4.4, 5.2, 'H₂ Receptor', C_ORANGE),
(8.2, 5.2, 'H₃ Receptor', C_PURPLE),
(11.4, 5.2, 'H₄ Receptor', C_TEAL),
]
for (rx, ry, label, col) in h_recs:
box(ax, rx, ry, 2.4, 0.6, label, col, fs=9.5, bold=True)
arr(ax, 6.5, 6.08, rx, 5.5, col)
# Location & effects per receptor
rec_info = [
(1.6, ['Location: Smooth muscle,\nendothelium, CNS',
'Effects:', '• Bronchoconstriction', '• Vasodilation (↓ BP)', '• Itch & urticaria', '• Nasal secretions']),
(4.4, ['Location: Gastric parietal cells',
'Effects:', '• ↑ Gastric acid secretion', '• ↑ HR (at high dose)', '• Vasodilation']),
(8.2, ['Location: Presynaptic CNS\nneurons',
'Effects:', '• Inhibits histamine release', '• Regulates appetite/sleep', '• Autoreceptor function']),
(11.4, ['Location: Immune cells\n(eosinophils, mast cells)',
'Effects:', '• Immune modulation', '• Chemotaxis', '• Role in allergy/\ninflammation']),
]
for i, (rx, lines) in enumerate(rec_info):
col = h_recs[i][3]
for j, line in enumerate(lines):
style = 'bold' if j == 0 else 'normal'
ax.text(rx, 4.5 - j*0.3, line, ha='center', fontsize=6.8,
color=col if j==0 else C_DARK, fontweight=style)
# Drug boxes
drug_info = [
(1.6, 1.7, C_RED, 'H₁ ANTIHISTAMINES',
'1st Gen (Sedating):\nDiphenhydramine, Chlorphenamine,\nPromethazine, Cyclizine\nUses: Allergy, motion sickness,\npruritus, common cold\nSE: Sedation, anticholinergic\n\n2nd Gen (Non-sedating):\nCetirizine, Loratadine,\nFexofenadine, Desloratadine\nUses: Allergic rhinitis, urticaria\nSE: Minimal sedation'),
(4.4, 1.7, C_ORANGE, 'H₂ ANTAGONISTS',
'Ranitidine (withdrawn - NDMA)\nFamotidine\nCimetidine (CYP inhibitor!)\nNizatidine\n\nUses:\n• Peptic ulcer disease\n• GERD\n• Zollinger-Ellison\n\nNote: PPIs (Omeprazole)\nnow preferred over H₂\nantagonists for PUD'),
(8.2, 1.7, C_PURPLE, 'H₃ LIGANDS',
'Pitolisant — H₃ inverse agonist\nUse: Narcolepsy (wakefulness)\n\nH₃ antagonists: research\nfor cognition, ADHD,\nAlzheimer\'s disease\n\n(No widely used H₃\nblockers in routine\nclinical practice yet)'),
(11.4, 1.7, C_TEAL, 'H₄ LIGANDS',
'Still investigational\nPotential uses:\n• Atopic dermatitis\n• Asthma\n• Inflammatory bowel\n disease\n• Autoimmune disease\n\nNo approved drugs\nin routine use'),
]
for (dx, dy, col, title, detail) in drug_info:
box(ax, dx, dy, 2.5, 0.6, title, col, fs=8, bold=True)
bx = FancyBboxPatch((dx-1.25, dy-2.3), 2.5, 1.65,
boxstyle='round,pad=0.02', lw=0.8,
edgecolor=col, facecolor='white', zorder=3)
ax.add_patch(bx)
ax.text(dx, dy-1.48, detail, ha='center', va='center', fontsize=6.3,
color=C_DARK, multialignment='center', zorder=4)
return save(fig, 'histamine')
# ═══════════════════════════════════════════════════════════════════════════════
# DIAGRAM 7 — Clinical Use Summary (Quick Reference)
# ═══════════════════════════════════════════════════════════════════════════════
def make_clinical_summary():
fig, ax = plt.subplots(figsize=(13, 7.5))
ax.set_xlim(0,13); ax.set_ylim(0,7.5); ax.axis('off')
fig.patch.set_facecolor('#f8f9fa'); ax.set_facecolor('#f8f9fa')
ax.text(6.5, 7.2, 'Clinical Conditions → Drug of Choice (Quick Reference)',
ha='center', fontsize=13, fontweight='bold', color=C_NAVY)
conditions = [
# (condition, drug, mechanism, color)
('Asthma (acute)', 'Salbutamol (SABA)', 'β2 agonist → bronchodilation', C_BLUE),
('Asthma (chronic)', 'Budesonide + Formoterol', 'ICS + LABA', C_BLUE),
('COPD', 'Tiotropium (Ipratropium)', 'M3 antagonist → bronchodilation', C_TEAL),
('Hypertension', 'Atenolol / Metoprolol', 'β1 blocker → ↓ HR, ↓ CO', C_RED),
('Heart Failure', 'Carvedilol + ACEi', 'α+β blocker + angiotensin blockade', C_RED),
('Angina', 'Propranolol / Atenolol', 'β blocker → ↓ O2 demand', C_RED),
('Glaucoma', 'Pilocarpine / Timolol', 'Cholinergic agonist / β blocker', C_GREEN),
('Myasthenia Gravis', 'Neostigmine / Pyridostigmine','AChE inhibitor → ↑ ACh', C_GREEN),
('Motion Sickness', 'Scopolamine', 'Muscarinic (M1) antagonist', C_ORANGE),
('Opioid Overdose Reversal','Naloxone', 'Opioid receptor antagonist', C_RED),
('Organophosphate Poisoning','Atropine + Pralidoxime', 'M-antagonist + AChE reactivator', C_ORANGE),
('Acute Migraine', 'Sumatriptan (+ NSAIDs)', '5-HT₁B/D agonist', C_PURPLE),
('Migraine Prevention', 'Propranolol / Topiramate', 'β blocker / anticonvulsant', C_PURPLE),
('Depression', 'SSRIs (Fluoxetine)', '5-HT reuptake inhibition', '#8e44ad'),
('Chemotherapy Nausea', 'Ondansetron', '5-HT₃ antagonist', '#9b59b6'),
('Peptic Ulcer', 'Omeprazole (PPI)', 'H⁺/K⁺ ATPase inhibitor', C_ORANGE),
('Allergic Rhinitis', 'Cetirizine / Loratadine', '2nd-gen H₁ antihistamine', C_TEAL),
('Anaphylaxis', 'Epinephrine (IM)', 'α1+β1+β2 agonist', C_RED),
('Shock (septic)', 'Norepinephrine', 'α1 agonist → vasoconstriction', '#8e44ad'),
('Pheochromocytoma', 'Phenoxybenzamine', 'Irreversible α blocker', '#a569bd'),
]
cols_per_row = 4
rows = [conditions[i:i+cols_per_row] for i in range(0, len(conditions), cols_per_row)]
cell_w = 3.1
start_y = 6.6
for r, row in enumerate(rows):
for c, (cond, drug, mech, col) in enumerate(row):
cx = 0.5 + c * cell_w + cell_w/2
cy = start_y - r * 0.92
bp = FancyBboxPatch((cx - cell_w/2 + 0.05, cy - 0.37), cell_w - 0.1, 0.74,
boxstyle='round,pad=0.02', lw=0.7,
edgecolor=col, facecolor='white', zorder=2)
ax.add_patch(bp)
# Color left strip
strip = FancyBboxPatch((cx - cell_w/2 + 0.05, cy - 0.37), 0.18, 0.74,
boxstyle='round,pad=0.0', lw=0, facecolor=col, zorder=3)
ax.add_patch(strip)
ax.text(cx - cell_w/2 + 0.35, cy + 0.12, cond, fontsize=7.0, color=col,
fontweight='bold', va='center')
ax.text(cx - cell_w/2 + 0.35, cy - 0.08, drug, fontsize=7.5, color=C_DARK,
fontweight='bold', va='center')
ax.text(cx - cell_w/2 + 0.35, cy - 0.26, mech, fontsize=6.3, color='#666',
va='center', style='italic')
return save(fig, 'clinical_summary')
# ═══════════════════════════════════════════════════════════════════════════════
# PDF BUILDER
# ═══════════════════════════════════════════════════════════════════════════════
def build_pdf():
print("Generating diagrams...")
imgs = {
'ans': make_ans_overview(),
'chol': make_cholinergic(),
'adren': make_adrenergic(),
'sero': make_serotonin(),
'migr': make_migraine(),
'hist': make_histamine(),
'clin': make_clinical_summary(),
}
print("All diagrams done. Building PDF...")
OUT = "/home/daytona/workspace/ans-autacoids-pdf/ANS_Autacoids_Notes.pdf"
doc = SimpleDocTemplate(OUT, pagesize=A4,
leftMargin=1.8*cm, rightMargin=1.8*cm,
topMargin=2*cm, bottomMargin=2*cm)
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, parent=styles.get(kw.pop('parent','Normal')), **kw)
sTitle = S('T', fontSize=22, textColor=colors.HexColor(C_NAVY),
alignment=TA_CENTER, fontName='Helvetica-Bold', spaceAfter=4)
sSub = S('Sub', fontSize=10, textColor=colors.HexColor(C_BLUE),
alignment=TA_CENTER, fontName='Helvetica', spaceAfter=10)
sH1 = S('H1', fontSize=14, textColor=colors.white,
fontName='Helvetica-Bold', spaceAfter=6, spaceBefore=12,
backColor=colors.HexColor(C_NAVY), leading=20,
leftIndent=-4, rightIndent=-4, borderPadding=(4,6,4,6))
sH2 = S('H2', fontSize=11, textColor=colors.HexColor(C_NAVY),
fontName='Helvetica-Bold', spaceAfter=4, spaceBefore=8,
backColor=colors.HexColor(C_LBLUE), borderPadding=(3,5,3,5))
sBody = S('B', fontSize=9, leading=13, fontName='Helvetica',
textColor=colors.HexColor(C_DARK), alignment=TA_JUSTIFY, spaceAfter=3)
sBul = S('Bul', fontSize=9, leading=13, fontName='Helvetica',
textColor=colors.HexColor(C_DARK), leftIndent=10, spaceAfter=2)
sNote = S('N', fontSize=8.5, fontName='Helvetica-Oblique',
textColor=colors.HexColor('#922b21'),
backColor=colors.HexColor('#fdedec'), borderPadding=(4,6,4,6), spaceAfter=4)
sCap = S('Cap', fontSize=7.5, alignment=TA_CENTER, fontName='Helvetica-Oblique',
textColor=colors.HexColor('#7f8c8d'), spaceAfter=6)
def h1(t): return Paragraph(f" {t}", sH1)
def h2(t): return Paragraph(t, sH2)
def body(t): return Paragraph(t, sBody)
def bul(t): return Paragraph(f"• {t}", sBul)
def note(t): return Paragraph(f"⚠ {t}", sNote)
def sp(n=6): return Spacer(1, n)
def hr(): return HRFlowable(width="100%", thickness=0.5, color=colors.HexColor(C_LBLUE), spaceAfter=4)
def cap(t): return Paragraph(t, sCap)
def mkimg(path, width=15*cm):
pil = PILImage.open(path)
pw, ph = pil.size
ratio = ph/pw
h = width * ratio
MAX_H = 11*cm
if h > MAX_H:
h = MAX_H; width = h/ratio
im = Image(path, width=width, height=h)
im.hAlign = 'CENTER'
return im
def mktable(headers, rows, widths=None):
data = [headers] + rows
t = Table(data, colWidths=widths, repeatRows=1)
t.setStyle(TableStyle([
('BACKGROUND', (0,0),(-1,0), colors.HexColor(C_NAVY)),
('TEXTCOLOR', (0,0),(-1,0), colors.white),
('FONTNAME', (0,0),(-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0),(-1,0), 9),
('FONTNAME', (0,1),(-1,-1),'Helvetica'),
('FONTSIZE', (0,1),(-1,-1), 8.5),
('ROWBACKGROUNDS',(0,1),(-1,-1),[colors.HexColor('#eaf4fb'), colors.white]),
('GRID', (0,0),(-1,-1), 0.4, colors.HexColor('#bdc3c7')),
('ALIGN', (0,0),(-1,-1), 'LEFT'),
('VALIGN', (0,0),(-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0),(-1,-1), 4),
('BOTTOMPADDING',(0,0),(-1,-1),4),
('LEFTPADDING', (0,0),(-1,-1), 6),
]))
return t
story = []
# ── COVER ────────────────────────────────────────────────────────────────
story += [sp(30), Paragraph("Module 4.1", sSub),
Paragraph("ANS & AUTACOIDS", sTitle),
Paragraph("Cholinergic • Adrenergic • Serotonin • Histamine • Migraine", sSub),
hr(), sp(4),
body("This module covers the major drug classes acting on the <b>Autonomic Nervous System (ANS)</b> and autacoids. "
"The ANS regulates involuntary functions — heart rate, blood pressure, digestion, breathing — "
"through two main divisions: parasympathetic (cholinergic) and sympathetic (adrenergic). "
"Autacoids are locally acting substances like serotonin, histamine, and CGRP."),
sp(8)]
# ── SECTION 1: ANS OVERVIEW ────────────────────────────────────────────
story += [h1("Section 1: Autonomic Nervous System (ANS) — Overview"),
sp(), mkimg(imgs['ans'], 16*cm),
cap("Figure 1. ANS divisions — parasympathetic (rest & digest) vs sympathetic (fight or flight), receptors, effects, and key drugs."),
sp(6)]
story += [h2("Key Neurotransmitters"),
mktable(
['Division', 'Pre-ganglionic NT', 'Post-ganglionic NT', 'Receptor Type'],
[['Parasympathetic', 'Acetylcholine (ACh)', 'Acetylcholine (ACh)', 'Muscarinic (M1-M5) + Nicotinic (Nn)'],
['Sympathetic', 'Acetylcholine (ACh)', 'Norepinephrine (NE)', 'Adrenergic (α1, α2, β1, β2, β3)'],
['Both (ganglion)','—', '—', 'Nicotinic (Ng) — ganglionic']],
[3.5*cm, 4*cm, 4*cm, 5*cm]
), sp(4)]
# ── SECTION 2: CHOLINERGIC ───────────────────────────────────────────────
story += [PageBreak(), h1("Section 2: Cholinergic & Anticholinergic Drugs"),
sp(), mkimg(imgs['chol'], 16*cm),
cap("Figure 2. Cholinergic drug classification — direct/indirect agonists and anticholinergic antagonists with clinical uses."),
sp(6)]
story += [h2("Cholinergic Drugs — Classification"),
mktable(
['Class', 'Drug', 'Use', 'Key SE'],
[['Direct muscarinic\nagonist', 'Pilocarpine', 'Glaucoma (miosis)', 'DUMBELS effects'],
['Direct muscarinic\nagonist', 'Bethanechol', 'Post-op urinary retention', 'Diarrhea, cramps'],
['AChE inhibitor\n(reversible)', 'Neostigmine', 'Myasthenia gravis, post-op reversal of NMB', 'Excessive secretions'],
['AChE inhibitor\n(reversible)', 'Pyridostigmine', 'Myasthenia gravis (longer-acting)', 'GI cramping'],
['AChE inhibitor\n(reversible)', 'Physostigmine', 'Atropine toxicity, glaucoma', 'CNS effects'],
['AChE inhibitor\n(reversible)', 'Donepezil', "Alzheimer's dementia", 'Nausea, vivid dreams'],
['AChE inhibitor\n(irreversible)','Organophosphates','Pesticides/nerve agents (toxic use)', 'SLUDGE syndrome → death']],
[4*cm, 3.5*cm, 4.5*cm, 4*cm]
), sp(6)]
story += [h2("Anticholinergic (Muscarinic Antagonist) Drugs"),
mktable(
['Drug', 'Selectivity', 'Clinical Use', 'Key SE'],
[['Atropine', 'Non-selective M', 'Bradycardia, OP poisoning, pre-op, eye exam', 'Dry mouth, confusion, urinary retention'],
['Scopolamine', 'M1 > M2/M3', 'Motion sickness (transdermal)', 'Sedation, dry mouth'],
['Ipratropium', 'M3 (inhaled)', 'COPD, acute asthma', 'Dry mouth, minimal systemic'],
['Tiotropium', 'M3 (inhaled, once daily)', 'COPD maintenance', 'Dry mouth, urinary retention'],
['Oxybutynin', 'M3 (bladder)', 'Overactive bladder / urge incontinence', 'Dry mouth, constipation, confusion'],
['Benztropine', 'M (CNS)', "Parkinson's disease (EPSEs)", 'Anticholinergic effects'],
['Glycopyrrolate', 'M (periphery, QNH)', 'Pre-op (reduce secretions), hyperhidrosis', 'Minimal CNS (cannot cross BBB)']],
[3*cm, 3.5*cm, 5*cm, 4.5*cm]
), sp(4)]
story += [note("DUMBELS mnemonic for cholinergic toxicity: Defecation/Diarrhea, Urination, Miosis, Bradycardia, Emesis, Lacrimation, Salivation/Sweating. "
"Treatment of organophosphate poisoning = Atropine (blocks M-receptors) + Pralidoxime (reactivates AChE if given early).")]
# ── SECTION 3: ADRENERGIC ────────────────────────────────────────────────
story += [PageBreak(), h1("Section 3: Adrenergic & Antiadrenergic Drugs"),
sp(), mkimg(imgs['adren'], 16*cm),
cap("Figure 3. Adrenergic receptor subtypes, their effects, and key agonist/antagonist drugs at each receptor."),
sp(6)]
story += [h2("Adrenergic Receptor Subtypes — Quick Reference"),
mktable(
['Receptor', 'Location', 'Effect', 'Agonist Drug', 'Antagonist Drug'],
[['α1', 'Blood vessels, iris, bladder', 'Vasoconstriction, mydriasis', 'Phenylephrine, NE', 'Prazosin, Doxazosin'],
['α2', 'Presynaptic neurons, CNS', 'Inhibits NE release, ↓ BP', 'Clonidine, Methyldopa', 'Yohimbine'],
['β1', 'Heart, kidney', '↑ HR, ↑ contractility, renin release', 'Dobutamine, Dopamine', 'Metoprolol, Atenolol, Bisoprolol'],
['β2', 'Bronchi, uterus, vessels', 'Bronchodilation, vasodilation', 'Salbutamol, Formoterol', 'Non-selective (Propranolol)'],
['β3', 'Adipose, bladder', 'Lipolysis, bladder relaxation', 'Mirabegron (bladder)', '—']],
[2*cm, 4*cm, 3.5*cm, 3.5*cm, 3.5*cm]
), sp(6)]
story += [h2("Beta-Blocker Classification"),
mktable(
['Type', 'Drugs', 'Key Property', 'Use'],
[['Non-selective (β1+β2)', 'Propranolol, Timolol, Carvedilol (α+β)', 'Blocks both β1 and β2', 'Arrhythmia, thyrotoxicosis, portal HTN (propranolol)'],
['Selective (β1)', 'Metoprolol, Atenolol, Bisoprolol', 'Spares β2 (safer in asthma)', 'HTN, angina, HF, MI secondary prevention'],
['With ISA', 'Pindolol, Acebutolol', 'Partial agonist at rest', 'HTN in bradycardic patients']],
[4*cm, 5*cm, 3.5*cm, 4*cm]
), sp(4)]
story += [note("Beta-blockers are cardioprotective in HF (start low, go slow) but take weeks to show benefit. "
"Never abruptly stop — causes rebound tachycardia/angina. Avoid non-selective β-blockers in asthma (bronchoconstriction via β2 blockade).")]
# ── SECTION 4: SEROTONIN ─────────────────────────────────────────────────
story += [PageBreak(), h1("Section 4: Serotonin System & Serotonergic Drugs"),
sp(), mkimg(imgs['sero'], 16*cm),
cap("Figure 4. Serotonin receptor subtypes (5-HT₁ to 5-HT₄), their functions, and major drug classes acting on each."),
sp(6)]
story += [h2("SSRIs & SNRIs — Comparison"),
mktable(
['Class', 'Drugs', 'Mechanism', 'Uses', 'Key SE'],
[['SSRI', 'Fluoxetine, Sertraline, Paroxetine, Citalopram, Escitalopram',
'Block 5-HT reuptake transporter (SERT)',
'Depression, OCD, panic disorder, PTSD, social anxiety, bulimia', 'Nausea, sexual dysfunction, insomnia, serotonin syndrome'],
['SNRI', 'Venlafaxine, Duloxetine, Desvenlafaxine',
'Block both SERT and NET (norepinephrine transporter)',
'Depression, anxiety, neuropathic pain, fibromyalgia', 'Hypertension, nausea, sweating, discontinuation syndrome'],
['Serotonin\nModulator', 'Mirtazapine, Trazodone',
'α2 antagonist (Mirtazapine) / 5-HT2 blocker (Trazodone)',
'Depression with insomnia/anxiety, appetite loss', 'Sedation, weight gain (mirtazapine)']],
[2*cm, 4*cm, 3.5*cm, 3.5*cm, 3*cm]
), sp(4)]
story += [note("Serotonin Syndrome = Triad of: (1) Altered mental status, (2) Neuromuscular abnormality (clonus, hyperreflexia), (3) Autonomic instability (hyperthermia, tachycardia). "
"Caused by: SSRI + MAOi, SSRI + Tramadol, SSRI + Linezolid. Treatment: Stop drug, cyproheptadine (5-HT2 antagonist), supportive care.")]
# ── SECTION 5: MIGRAINE ──────────────────────────────────────────────────
story += [PageBreak(), h1("Section 5: Migraine — Pathophysiology & Treatment"),
sp(), mkimg(imgs['migr'], 16*cm),
cap("Figure 5. Migraine mechanism (CSD → trigeminal activation → CGRP release) and treatment options — acute vs preventive."),
sp(6)]
story += [h2("Triptans — Key Details"),
mktable(
['Drug', 'Route', 'Onset', 'Half-life', 'Notes'],
[['Sumatriptan', 'SC / IN / PO', '20 min (SC)', '2 h', 'Prototype triptan; fastest SC onset'],
['Zolmitriptan', 'PO / Nasal spray', '~45 min', '2.5 h', 'Nasal spray useful when vomiting'],
['Rizatriptan', 'PO (oral dissolving)', '30-45 min', '2 h', 'Fast-dissolving wafer; convenient'],
['Naratriptan', 'PO', '1-3 h', '6 h', 'Slower onset, fewer recurrences'],
['Frovatriptan', 'PO', '2-4 h', '>24 h', 'Longest t½; best for menstrual migraine'],
['Eletriptan', 'PO', '~1 h', '4 h', 'High potency; good for severe attacks']],
[3*cm, 3*cm, 2.5*cm, 2.5*cm, 5.5*cm]
), sp(4)]
story += [note("Triptans are contraindicated in: CAD, stroke history, uncontrolled HTN, basilar/hemiplegic migraine, Prinzmetal angina. "
"Never combine with ergotamine (vasospasm risk). Wait ≥24h after ergotamine before giving triptan.")]
# ── SECTION 6: HISTAMINE ─────────────────────────────────────────────────
story += [PageBreak(), h1("Section 6: Histamine & Antihistamines"),
sp(), mkimg(imgs['hist'], 16*cm),
cap("Figure 6. Histamine receptor subtypes H1-H4, their effects, and antihistamine drug classes."),
sp(6)]
story += [h2("H1 Antihistamines — Generation Comparison"),
mktable(
['Property', '1st Generation (Sedating)', '2nd Generation (Non-sedating)'],
[['Drugs', 'Diphenhydramine, Chlorphenamine, Promethazine, Cyclizine', 'Cetirizine, Loratadine, Fexofenadine, Desloratadine'],
['CNS penetration', 'High (crosses BBB)', 'Low (minimal BBB crossing)'],
['Sedation', 'Yes — significant', 'Minimal to none'],
['Anticholinergic SE', 'Yes — dry mouth, urinary retention, blurred vision', 'No'],
['Duration', '4-6 hours (TID dosing)', '12-24 hours (OD/BD dosing)'],
['Uses', 'Allergy, motion sickness, pruritus, insomnia, pre-op', 'Allergic rhinitis, urticaria, chronic allergy'],
['Avoid in', 'Elderly (confusion, falls), BPH, glaucoma', 'Generally well tolerated']],
[4*cm, 6.5*cm, 6*cm]
), sp(4)]
story += [h2("H2 Antagonists (Antiulcer Drugs)"),
mktable(
['Drug', 'Potency', 'Key Features', 'Uses'],
[['Famotidine', 'Most potent H2 blocker', 'No CYP interaction, safe', 'PUD, GERD, Zollinger-Ellison'],
['Cimetidine', 'Least potent', 'Strong CYP inhibitor → many drug interactions; gynecomastia', 'PUD (less used now)'],
['Ranitidine', '—', 'Withdrawn globally (NDMA contamination)', 'Withdrawn'],
['Nizatidine', 'Similar to ranitidine', 'No significant CYP interaction', 'PUD, GERD']],
[3*cm, 3.5*cm, 5.5*cm, 4.5*cm]
), sp(4)]
story += [note("PPIs (Proton Pump Inhibitors: Omeprazole, Pantoprazole, Esomeprazole) are now preferred over H2 blockers for PUD and GERD as they are more effective. "
"H2 blockers are still useful for nocturnal acid breakthrough and OTC antacid use.")]
# ── SECTION 7: CLINICAL QUICK REFERENCE ─────────────────────────────────
story += [PageBreak(), h1("Section 7: Clinical Quick Reference — Drug of Choice"),
sp(), mkimg(imgs['clin'], 16*cm),
cap("Figure 7. Condition-to-drug-of-choice quick reference covering all ANS and autacoid drug classes."),
sp(6)]
story += [h2("High-Yield Exam Points"),
mktable(
['Question', 'Answer'],
[['Drug for acute migraine (moderate-severe)', 'Triptan (e.g. Sumatriptan) ± NSAID'],
['Drug for asthma (acute bronchospasm)', 'Salbutamol (SABA) — β2 agonist'],
['Drug for COPD (bronchodilation)', 'Tiotropium (LAMA) — M3 antagonist'],
['Drug for motion sickness', 'Scopolamine (M1 antagonist — transdermal patch)'],
['Drug for organophosphate poisoning', 'Atropine + Pralidoxime'],
['Drug for chemo-induced nausea', 'Ondansetron (5-HT₃ antagonist)'],
['Drug for anaphylaxis', 'Epinephrine IM (α1+β1+β2)'],
['Drug for HF with reduced EF', 'Carvedilol (α+β blocker) + ACEi + Loop diuretic'],
['Drug for pheochromocytoma pre-op', 'Phenoxybenzamine (irreversible α blocker) FIRST — then beta blocker'],
['SSRIs cause this serious toxicity when combined with MAOi', 'Serotonin Syndrome'],
['Why is Cimetidine avoided?', 'Strong CYP2C19/3A4 inhibitor — many drug interactions; also causes gynecomastia'],
['Triptans are contraindicated in?', 'CAD, history of stroke, uncontrolled HTN, basilar/hemiplegic migraine']],
[7.5*cm, 9*cm]
), sp(6)]
story += [hr(), sp(4),
Paragraph("Sources: Katzung's Basic & Clinical Pharmacology 16e; Lippincott Illustrated Reviews: Pharmacology; "
"Guyton & Hall Medical Physiology; Goldman-Cecil Medicine; Course notes HomUG-Mod.Phar 4.1.1–4.1.4", sCap)]
print("Building PDF...")
doc.build(story)
print(f"✓ PDF saved: {OUT}")
return OUT
if __name__ == "__main__":
build_pdf()
cd /home/daytona/workspace/ans-autacoids-pdf && python generate_ans_pdf.py 2>&1
ls -lh /home/daytona/workspace/ans-autacoids-pdf/ANS_Autacoids_Notes.pdf
ANS Autacoids Notes
PDF Document · PDF
| Section | Content | Visual Type |
|---|---|---|
| 1. ANS Overview | Parasympathetic vs Sympathetic divisions, neurotransmitters, receptors, effects | Full color ANS diagram |
| 2. Cholinergic & Anticholinergic | Direct/indirect agonists, muscarinic antagonists, DUMBELS mnemonic | Drug flowchart |
| 3. Adrenergic & Antiadrenergic | α1, α2, β1, β2 receptors, agonists & antagonists, beta-blocker classification | Receptor map diagram |
| 4. Serotonin System | 5-HT₁ to 5-HT₄ receptors, SSRIs, SNRIs, 5-HT₃ antagonists, triptans | Serotonin pathway diagram |
| 5. Migraine | CSD → trigeminal → CGRP pathway, acute vs preventive treatment, triptan comparison table | Pathophysiology + treatment flowchart |
| 6. Histamine & Antihistamines | H1-H4 receptors, 1st vs 2nd gen antihistamines, H2 blockers | Receptor diagram + tables |
| 7. Quick Reference | 20 clinical conditions → Drug of Choice + 12 high-yield exam MCQs | Color-coded summary chart |