Explain common 10 heart diseases with ECG changes and ECG images of those diseases

Reading File
Finding Sources
Finding Sources
Finding Sources
Searching Images

ECG ST elevation myocardial infarction STEMI

Searching Images

ECG atrial fibrillation electrocardiogram

Finding Sources
Finding Sources
Finding Sources
Searching Images

ECG ventricular tachycardia electrocardiogram

Searching Images

ECG complete heart block atrioventricular block

Searching Images

ECG Wolff-Parkinson-White delta wave pre-excitation

Searching Images

ECG left ventricular hypertrophy hypertrophic cardiomyopathy

Searching Images

ECG pericarditis saddle-shaped ST elevation

Searching Images

ECG pulmonary embolism S1Q3T3 right heart strain

Searching Images

ECG Brugada syndrome coved ST elevation V1 V2

Searching Images

ECG long QT syndrome torsades de pointes

Finding Sources
Finding Sources

10 Common Heart Diseases — ECG Changes & Images


1. ST-Elevation Myocardial Infarction (STEMI)

ECG Changes

  • Hyperacute T waves (earliest sign) — tall, broad, symmetric peaked T waves
  • ST-segment elevation ≥1 mm in ≥2 contiguous limb leads or ≥2 mm in ≥2 precordial leads; convex ("tombstone") morphology in severe cases
  • Reciprocal ST depression in mirror-image leads (e.g., inferior STEMI → depression in aVL)
  • Pathological Q waves (>40 ms wide, >1/4 of R-wave height) develop within hours and indicate transmural necrosis
  • T-wave inversion follows as the infarct evolves
Localisation: Anterior (V1–V4 = LAD), Inferior (II, III, aVF = RCA/LCx), Lateral (I, aVL, V5–V6 = LCx)
Anterior STEMI — prominent ST elevation V2–V5 with tombstoning morphology
Anterior STEMI: Convex ST-segment elevation across V1–V6, most pronounced in V2–V4; reciprocal depression in inferior leads. — Harrison's Principles of Internal Medicine 22E

2. Atrial Fibrillation (AF)

ECG Changes

  • Absent P waves — replaced by chaotic fibrillatory (f) waves best seen in V1 and lead II; frequency 350–600 impulses/min
  • Irregularly irregular R-R intervals — the hallmark finding
  • Narrow QRS complexes (unless aberrant conduction or bundle branch block co-exists)
  • Ventricular rate typically 100–180/min if uncontrolled; low-voltage QRS in limb leads may suggest infiltrative disease (e.g., amyloidosis)
AF ECG — fine fibrillatory baseline, absent P waves, irregularly irregular rhythm
Atrial fibrillation with rapid ventricular response: absent P waves, fibrillatory baseline, irregular RR intervals. — Tintinalli's Emergency Medicine

3. Complete (Third-Degree) Atrioventricular Block

ECG Changes

  • Complete AV dissociation — P waves and QRS complexes fire independently with no fixed PR interval
  • Regular P-P intervals (atrial rate faster, typically 60–100/min)
  • Regular R-R intervals at a slower escape rate (ventricular 30–50/min)
  • Wide QRS if escape rhythm is infra-Hisian/ventricular; narrow QRS if junctional escape
  • Secondary ST-T changes from abnormal ventricular activation
Complete heart block — P waves marching through at faster rate, independent slow wide-complex QRS
Third-degree AV block: slow bradycardic ventricular escape rhythm (~44 bpm), wide QRS, complete AV dissociation with faster independent P waves. — Harrison's Principles of Internal Medicine 22E

4. Ventricular Tachycardia (VT)

ECG Changes

  • Wide QRS complex tachycardia (QRS >120 ms) at rate 100–250/min
  • AV dissociation — P waves occur independently of QRS (seen in ~50% of VT cases)
  • Fusion beats — partial ventricular capture producing intermediate-morphology QRS
  • Capture beats — brief normal narrow QRS when sinus impulse fully captures ventricles (pathognomonic of VT)
  • Brugada criteria: concordance in precordial leads, RS interval >100 ms, no RS complex in any precordial lead → VT
  • Ventricular fibrillation: chaotic, irregular, disorganized baseline with no discernible QRS
VT ECG — regular wide-complex tachycardia ~150 bpm with capture beat highlighted
Monomorphic ventricular tachycardia: broad regular QRS complexes, capture beat (red circle) indicating AV dissociation. — Tintinalli's Emergency Medicine

5. Wolff-Parkinson-White (WPW) Syndrome

ECG Changes

  • Short PR interval (<120 ms) — early ventricular activation via accessory pathway (Bundle of Kent)
  • Delta wave — slurred upstroke at the start of QRS, representing ventricular pre-excitation
  • Wide QRS complex (>120 ms) — fusion of pre-excited and normal ventricular activation
  • Secondary ST-T changes opposite to QRS vector (discordant)
  • Risk of rapid AF conduction → ventricular fibrillation if antidromic pathway allows fast impulses
Pathway localisation by delta polarity: Negative deltas in inferior leads (II, III, aVF) → posteroseptal pathway; positive V1 → left free wall pathway
WPW ECG — short PR, delta waves, widened QRS in multiple leads
WPW syndrome: shortened PR interval, delta waves (red arrows in leads II and III), widened QRS with pre-excitation. — Harrison's Principles of Internal Medicine 22E

6. Hypertrophic Cardiomyopathy (HCM)

ECG Changes

  • Left ventricular hypertrophy (LVH) voltage criteria: Sokolow-Lyon (SV1 + RV5 or RV6 >35 mm); Cornell (RaVL + SV3 >28 mm in men)
  • ST-segment depression and T-wave inversion (strain pattern) in lateral leads I, aVL, V4–V6
  • Giant, deep symmetric T-wave inversions in V2–V5 (classic in apical HCM / Yamaguchi syndrome, >10 mm depth)
  • Absence of septal Q waves in lateral leads (V5, V6, I, aVL) due to abnormal septal depolarisation
  • Left axis deviation; possible LAE (P mitrale)
HCM ECG — LVH voltage with deep T-wave inversions in precordial leads
Hypertrophic cardiomyopathy: high-voltage R waves, ST depression, and deep T-wave inversions V2–V6; absent septal Q waves in lateral leads. — Goldman-Cecil Medicine

7. Acute Pericarditis

ECG Changes (evolves in 4 stages)

StageTimingECG Finding
IDays 1–2Diffuse concave ("saddle-shaped") ST elevation in all leads except aVR and V1; PR depression (most sensitive sign) in II, V4–V6; PR elevation in aVR
IIDays 3–7ST returns to baseline; T waves flatten
IIIWeeks 1–3T-wave inversion in previously elevated leads
IVWeeks–monthsECG normalises
Key differentiator from STEMI: ST elevation is diffuse (not territorial), concave not convex; no reciprocal depression except aVR; PR depression present; no Q waves.
Pericarditis ECG — diffuse saddle-shaped ST elevation, PR depression in lead II
Acute pericarditis: diffuse concave ST elevation across I, II, III, aVF, V2–V6; PR depression in lead II; reciprocal changes in aVR. Note sinus tachycardia (inflammatory response).

8. Pulmonary Embolism (PE)

ECG Changes

  • Sinus tachycardia — the most common finding (>40% of cases)
  • S1Q3T3 pattern (McGinn-White sign): prominent S wave in lead I, Q wave in lead III, T-wave inversion in lead III — reflects acute right heart strain
  • Right axis deviation and right bundle branch block (complete or incomplete RBBB — rSR' in V1)
  • T-wave inversions V1–V4 (right ventricular strain)
  • P pulmonale — peaked P waves >2.5 mm in lead II (right atrial enlargement)
  • Low-voltage QRS; non-specific ST changes
  • New atrial fibrillation or flutter may appear
PE ECG — S1Q3T3 pattern with annotations, sinus tachycardia
Acute pulmonary embolism: S1Q3T3 pattern highlighted with circles/arrows — deep S in lead I, Q wave in III, inverted T in III; sinus tachycardia >100 bpm.

9. Brugada Syndrome

ECG Changes

Three pattern types (Type 1 is the only diagnostic pattern):
TypeST MorphologyT WaveDiagnostic?
Type 1 (Coved)J-point ≥2 mm, convex/coved downsloping STNegative (inverted)✅ Yes
Type 2 (Saddle-back)J-point ≥2 mm, saddle-back STPositive❌ Requires pharmacological challenge
Type 3<2 mm ST elevationPositive❌ Non-diagnostic
  • Changes confined to V1–V2 (right precordial leads), best seen with electrodes in 2nd–3rd intercostal space
  • Associated with RBBB-like pattern (rSR' in V1), first-degree AV block, prolonged PR
  • Caused by SCN5A loss-of-function mutations → sodium channel dysfunction → risk of polymorphic VT and sudden cardiac death
Brugada Type 1 — coved ST elevation V1–V2 with inverted T wave
Brugada syndrome Type 1: Classic coved ST-segment elevation ≥2 mm in V1–V2, descending into inverted T waves — the only spontaneously diagnostic pattern. — Harrison's Principles of Internal Medicine 22E

10. Long QT Syndrome (LQTS)

ECG Changes

  • Prolonged QTc interval: ≥450 ms (males) or ≥460 ms (females) is borderline; ≥500 ms is high-risk
    • Corrected using Bazett formula: QTc = QT ÷ √RR
  • T-wave morphology subtypes:
    • LQT1 (KCNQ1): Broad-based smooth T wave
    • LQT2 (KCNH2): Bifid (notched) T wave — most common
    • LQT3 (SCN5A): Late-onset peaked T wave with long isoelectric ST segment
  • Prominent U waves — best seen in V2–V3; can fuse with T wave masking true QT
  • T-wave alternans — beat-to-beat alternation in T-wave morphology/amplitude (sign of instability)
  • Torsades de Pointes (TdP): Polymorphic VT with QRS complexes twisting around the isoelectric line — the dreaded complication
Long QT syndrome — prolonged QTc 680 ms with U waves; initiation of torsades de pointes
Long QT syndrome: Panel A shows baseline QTc 680 ms with prominent U waves (arrows); Panel B shows short-long-short sequence triggering polymorphic VT (torsades de pointes). — Harrison's Principles of Internal Medicine

Quick Reference Summary

#DiseaseKey ECG FindingCritical Clue
1STEMIConvex ST elevation + Q wavesTerritorial distribution + reciprocal changes
2Atrial FibrillationNo P waves, irregular R-R"Irregularly irregular"
3Complete Heart BlockP-wave/QRS dissociation, slow escapeNo PR relationship
4Ventricular TachycardiaWide QRS tachycardia, AV dissociationFusion/capture beats
5WPW SyndromeShort PR + delta wave + wide QRSSlurred QRS upstroke
6HCMLVH voltage + giant T inversionsDeep V2–V5 T inversions (apical type)
7PericarditisDiffuse saddle ST + PR depressionAll leads (not territorial)
8Pulmonary EmbolismS1Q3T3 + sinus tachycardia + RBBBRight heart strain pattern
9Brugada SyndromeCoved ST elevation V1–V2 + inverted TOnly Type 1 is diagnostic
10Long QT SyndromeQTc >500 ms + T-wave changesTorsades de pointes risk
Sources: Harrison's Principles of Internal Medicine 22E (2025); Braunwald's Heart Disease; Tintinalli's Emergency Medicine; Goldman-Cecil Medicine; Fuster and Hurst's The Heart, 15th Ed; Ganong's Review of Medical Physiology

Pdf

Reading File
Reading File
Running Command

ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or missing"

Running Command

mkdir -p /home/daytona/workspace/heart-ecg-pdf

Writing File

~/heart-ecg-pdf/generate_pdf.py

import json
import subprocess
import base64
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,
    PageBreak, Image as RLImage, HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import BalancedColumns
from io import BytesIO

OUTPUT = "/home/daytona/workspace/heart-ecg-pdf/Heart_Diseases_ECG.pdf"
IMG_DIR = "/home/daytona/workspace/heart-ecg-pdf/imgs"
os.makedirs(IMG_DIR, exist_ok=True)

# ── Image URLs ──────────────────────────────────────────────────────────────
IMAGE_URLS = {
    "stemi":     "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_16738d4b125195130b5e53a811645d4064182fc2bbd0de16b0e00a57af7ff6ef.jpg",
    "af":        "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_55b3585ba004b0ca69f159c22eb5fbb4d8995fc007e77627c0d37922e4d88973.jpg",
    "chb":       "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_755c449b940e537dbbe6dd7bf9c73561fc7bed3c059859efcb9b52c8878d99b4.jpg",
    "vt":        "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_d0c8263390a11db77a98f37c73e35131257aee921845e98272875e8c3fe8caec.jpg",
    "wpw":       "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_53c53d9ed7100de15d6d512e52e2a269252a79c85c12a60e54a4ce2fc4d574ec.jpg",
    "hcm":       "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_2910b31808487d7cd1b8678e2a6942b2ca7518030d03f48787ac4b092bd7e92e.jpg",
    "pericarditis": "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_cd4008531c1b1a2a99ab6d9b4282dcdcedfcf77c302b6ecbb7f7e01c5c985cf9.jpg",
    "pe":        "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_5f391caa5a24ec425e9f48d4d9f73620a3b91f98df1f92cea400318772fda12e.jpg",
    "brugada":   "https://cdn.orris.care/cdss_images/pmc_clinical_VQA_6a00d07e5f8f18709c0b945773550567b91d5cce1d6e873c08d66dcc8caa5600.jpg",
    "lqts":      "https://cdn.orris.care/cdss_images/HARRISON_1763034143291_d1a2f9c1-7f66-4dec-a3f8-19b81f2ba927.png",
}

# ── Download images ──────────────────────────────────────────────────────────
print("Downloading images...")
urls = list(IMAGE_URLS.values())
result = json.loads(subprocess.check_output(
    ["node", "/home/daytona/skills/shared/scripts/fetch_images.js"] + urls
))

img_paths = {}
keys = list(IMAGE_URLS.keys())
for i, item in enumerate(result):
    key = keys[i]
    if item.get("base64"):
        raw = base64.b64decode(item["base64"].split(",")[1])
        ext = "png" if "png" in item["base64"] else "jpg"
        path = f"{IMG_DIR}/{key}.{ext}"
        with open(path, "wb") as f:
            f.write(raw)
        img_paths[key] = path
        print(f"  ✓ {key}")
    else:
        print(f"  ✗ {key}: {item.get('error')}")

# ── Styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

DARK_RED   = colors.HexColor("#8B0000")
MED_RED    = colors.HexColor("#C0392B")
LIGHT_RED  = colors.HexColor("#FADBD8")
DARK_GRAY  = colors.HexColor("#2C3E50")
MID_GRAY   = colors.HexColor("#566573")
LIGHT_GRAY = colors.HexColor("#F2F3F4")
WHITE      = colors.white
GOLD       = colors.HexColor("#D4AC0D")

title_style = ParagraphStyle(
    "TitleStyle", parent=styles["Title"],
    fontSize=26, textColor=WHITE, alignment=TA_CENTER,
    spaceAfter=6, fontName="Helvetica-Bold", leading=32,
)
subtitle_style = ParagraphStyle(
    "SubtitleStyle", parent=styles["Normal"],
    fontSize=12, textColor=colors.HexColor("#F0B27A"),
    alignment=TA_CENTER, spaceAfter=4, fontName="Helvetica",
)
source_style = ParagraphStyle(
    "SourceStyle", parent=styles["Normal"],
    fontSize=8, textColor=colors.HexColor("#A9CCE3"),
    alignment=TA_CENTER, fontName="Helvetica-Oblique",
)
disease_num_style = ParagraphStyle(
    "DiseaseNum", parent=styles["Normal"],
    fontSize=10, textColor=MED_RED,
    fontName="Helvetica-Bold", spaceAfter=2,
)
disease_title_style = ParagraphStyle(
    "DiseaseTitle", parent=styles["Heading1"],
    fontSize=18, textColor=DARK_RED,
    fontName="Helvetica-Bold", spaceAfter=6, spaceBefore=4,
    borderPad=4,
)
section_head_style = ParagraphStyle(
    "SectionHead", parent=styles["Normal"],
    fontSize=11, textColor=WHITE, fontName="Helvetica-Bold",
    backColor=MED_RED, leftIndent=6, rightIndent=6,
    spaceAfter=4, spaceBefore=8, leading=16,
    borderPad=4,
)
body_style = ParagraphStyle(
    "Body", parent=styles["Normal"],
    fontSize=9.5, textColor=DARK_GRAY, fontName="Helvetica",
    spaceAfter=3, leading=14, alignment=TA_JUSTIFY,
)
bullet_style = ParagraphStyle(
    "Bullet", parent=styles["Normal"],
    fontSize=9.5, textColor=DARK_GRAY, fontName="Helvetica",
    leftIndent=14, bulletIndent=4, spaceAfter=2, leading=13,
    bulletFontName="Helvetica", bulletFontSize=10,
)
caption_style = ParagraphStyle(
    "Caption", parent=styles["Normal"],
    fontSize=8, textColor=MID_GRAY, fontName="Helvetica-Oblique",
    alignment=TA_CENTER, spaceAfter=6, spaceBefore=2, leading=11,
)
table_header_style = ParagraphStyle(
    "TableHeader", parent=styles["Normal"],
    fontSize=8.5, textColor=WHITE, fontName="Helvetica-Bold",
    alignment=TA_CENTER,
)
table_cell_style = ParagraphStyle(
    "TableCell", parent=styles["Normal"],
    fontSize=8.5, textColor=DARK_GRAY, fontName="Helvetica",
    alignment=TA_LEFT, leading=11,
)

# ── Helper: add image ────────────────────────────────────────────────────────
def ecg_image(key, caption_text, width=15*cm):
    items = []
    if key in img_paths:
        try:
            img = RLImage(img_paths[key], width=width, height=width*0.45)
            img.hAlign = "CENTER"
            items.append(img)
        except Exception as e:
            print(f"  Image error {key}: {e}")
    items.append(Paragraph(caption_text, caption_style))
    return items

def section_header(text):
    return Paragraph(f"  {text}", section_head_style)

def bullet(text):
    return Paragraph(f"• {text}", bullet_style)

def hr():
    return HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#D5D8DC"), spaceAfter=4, spaceBefore=4)

# ── Cover Page ───────────────────────────────────────────────────────────────
def cover_page(story):
    story.append(Spacer(1, 2.5*cm))

    # Title block with dark background table
    cover_data = [[
        Paragraph("10 Common Heart Diseases", title_style),
    ], [
        Paragraph("ECG Changes &amp; Electrocardiographic Findings", subtitle_style),
    ], [
        Spacer(1, 0.3*cm),
    ], [
        Paragraph("A Comprehensive Clinical Reference", subtitle_style),
    ], [
        Spacer(1, 0.3*cm),
    ], [
        Paragraph("Sources: Harrison's Principles of Internal Medicine 22E · Braunwald's Heart Disease · Tintinalli's Emergency Medicine · Goldman-Cecil Medicine · Fuster and Hurst's The Heart 15E", source_style),
    ]]
    cover_table = Table(cover_data, colWidths=[17*cm])
    cover_table.setStyle(TableStyle([
        ("BACKGROUND",   (0,0), (-1,-1), DARK_GRAY),
        ("ROWPADDING",   (0,0), (-1,-1), 10),
        ("BOX",          (0,0), (-1,-1), 2, MED_RED),
        ("ROUNDEDCORNERS", [8]),
    ]))
    story.append(cover_table)
    story.append(Spacer(1, 1.2*cm))

    # Quick reference summary table on cover
    story.append(Paragraph("  Quick Reference Summary", ParagraphStyle(
        "QRTitle", parent=styles["Normal"], fontSize=13,
        textColor=DARK_RED, fontName="Helvetica-Bold", spaceAfter=6,
    )))

    qr_headers = ["#", "Disease", "Key ECG Finding", "Critical Clue"]
    qr_rows = [
        ["1", "STEMI", "Convex ST elevation + Q waves", "Territorial + reciprocal changes"],
        ["2", "Atrial Fibrillation", "No P waves, irregular RR", '"Irregularly irregular"'],
        ["3", "Complete Heart Block", "P/QRS dissociation, slow escape", "No fixed PR relationship"],
        ["4", "Ventricular Tachycardia", "Wide QRS tachycardia, AV dissociation", "Fusion/capture beats"],
        ["5", "WPW Syndrome", "Short PR + delta wave + wide QRS", "Slurred QRS upstroke"],
        ["6", "Hypertrophic Cardiomyopathy", "LVH voltage + giant T inversions", "Deep V2-V5 T inversions (apical)"],
        ["7", "Acute Pericarditis", "Diffuse saddle ST + PR depression", "All leads, not territorial"],
        ["8", "Pulmonary Embolism", "S1Q3T3 + sinus tachycardia + RBBB", "Right heart strain pattern"],
        ["9", "Brugada Syndrome", "Coved ST elevation V1-V2 + inv T", "Only Type 1 is diagnostic"],
        ["10", "Long QT Syndrome", "QTc >500 ms + T-wave changes", "Torsades de pointes risk"],
    ]

    table_data = [[Paragraph(h, table_header_style) for h in qr_headers]]
    for row in qr_rows:
        table_data.append([Paragraph(cell, table_cell_style) for cell in row])

    qr_table = Table(table_data, colWidths=[1*cm, 4.5*cm, 6.5*cm, 5*cm])
    qr_table.setStyle(TableStyle([
        ("BACKGROUND",   (0,0), (-1,0), DARK_RED),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_GRAY]),
        ("TEXTCOLOR",    (0,0), (-1,0), WHITE),
        ("ALIGN",        (0,0), (0,-1), "CENTER"),
        ("FONTNAME",     (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE",     (0,0), (-1,-1), 8.5),
        ("GRID",         (0,0), (-1,-1), 0.4, colors.HexColor("#D5D8DC")),
        ("ROWPADDING",   (0,0), (-1,-1), 5),
        ("VALIGN",       (0,0), (-1,-1), "MIDDLE"),
    ]))
    story.append(qr_table)
    story.append(PageBreak())

# ── Disease Entries ──────────────────────────────────────────────────────────
diseases = [
    {
        "num": "1",
        "title": "ST-Elevation Myocardial Infarction (STEMI)",
        "img_key": "stemi",
        "caption": "Anterior STEMI: Convex 'tombstone' ST-segment elevation across V1-V6, most pronounced in V2-V4, with reciprocal ST depression in inferior leads (II, III, aVF). Sinus rhythm with hyperacute T waves.",
        "overview": "STEMI results from complete occlusion of a coronary artery causing transmural myocardial injury. Immediate reperfusion (primary PCI within 90 min) is life-saving.",
        "ecg_points": [
            "Hyperacute T waves — earliest sign; tall, broad, symmetric peaked T waves",
            "ST-segment elevation ≥1 mm in ≥2 contiguous limb leads or ≥2 mm in ≥2 precordial leads (convex/tombstone morphology)",
            "Reciprocal ST depression in mirror-image leads (e.g., inferior STEMI → depression in aVL/I)",
            "Pathological Q waves (>40 ms wide, >1/4 R-wave height) — indicate transmural necrosis",
            "T-wave inversion follows as infarct evolves (hours to days)",
            "Localisation: Anterior (V1-V4 = LAD), Inferior (II,III,aVF = RCA), Lateral (I,aVL,V5-V6 = LCx)",
        ],
        "extra": None,
    },
    {
        "num": "2",
        "title": "Atrial Fibrillation (AF)",
        "img_key": "af",
        "caption": "Atrial fibrillation with rapid ventricular response: absent P waves replaced by fine fibrillatory baseline (best seen V1, lead II), and an irregularly irregular R-R interval pattern throughout all leads.",
        "overview": "AF is the most common sustained cardiac arrhythmia (~1-2% prevalence), caused by disorganised atrial electrical activity. It carries a 5x stroke risk, managed with rate/rhythm control and anticoagulation.",
        "ecg_points": [
            "Absent P waves — replaced by chaotic fibrillatory (f) waves at 350-600 impulses/min; best seen in V1 and II",
            "Irregularly irregular R-R intervals — the hallmark finding",
            "Narrow QRS complexes (unless aberrant conduction/bundle branch block co-exists)",
            "Ventricular rate: 100-180/min if uncontrolled; <100/min if rate-controlled",
            "Low-voltage QRS in limb leads may suggest infiltrative disease (e.g., amyloidosis)",
        ],
        "extra": None,
    },
    {
        "num": "3",
        "title": "Complete (Third-Degree) AV Block",
        "img_key": "chb",
        "caption": "Complete heart block: slow ventricular escape rhythm (~44 bpm) with wide QRS complexes, complete AV dissociation — P waves march at a faster independent rate through QRS complexes and T waves. Medical emergency requiring pacing.",
        "overview": "Complete AV block is a life-threatening arrhythmia where no atrial impulses conduct to the ventricles. Causes include inferior MI (RCA), Lyme disease, drugs (beta-blockers, digoxin), and idiopathic fibrosis (Lenegre disease).",
        "ecg_points": [
            "Complete AV dissociation — P waves and QRS complexes fire independently with no fixed PR interval",
            "Regular P-P intervals (atrial rate 60-100/min, faster than ventricles)",
            "Regular R-R intervals at a slower escape rate (junctional: 40-60/min, narrow QRS; ventricular: 20-40/min, wide QRS)",
            "Wide QRS if escape rhythm is infra-Hisian/ventricular (>120 ms)",
            "Secondary ST-T changes from abnormal ventricular activation sequence",
            "P waves may appear before, within, or after QRS complexes — none are conducted",
        ],
        "extra": None,
    },
    {
        "num": "4",
        "title": "Ventricular Tachycardia (VT)",
        "img_key": "vt",
        "caption": "Monomorphic ventricular tachycardia at ~150 bpm: broad regular QRS complexes (>120 ms), AV dissociation. Red circle highlights a capture beat — a narrow QRS indicating transient sinus capture of the ventricles, pathognomonic of VT.",
        "overview": "VT is a life-threatening arrhythmia originating below the bundle of His. Sustained VT (>30 sec) requires urgent cardioversion. Most common cause is structural heart disease (post-MI scar).",
        "ecg_points": [
            "Wide QRS complex tachycardia (QRS >120 ms) at rate 100-250/min",
            "AV dissociation — independent P waves seen in ~50% of cases",
            "Fusion beats — partial ventricular capture producing intermediate-morphology QRS",
            "Capture beats — brief normal narrow QRS (pathognomonic of VT, rare but diagnostic)",
            "Brugada criteria: concordance in precordials, RS interval >100 ms, no RS in any precordial lead → VT",
            "Ventricular fibrillation: chaotic disorganised baseline, no QRS — cardiac arrest",
        ],
        "extra": None,
    },
    {
        "num": "5",
        "title": "Wolff-Parkinson-White (WPW) Syndrome",
        "img_key": "wpw",
        "caption": "WPW syndrome: Shortened PR interval (<120 ms), delta waves (slurred initial QRS upstroke, red arrows in leads II-III), and widened QRS complexes throughout all leads. Negative delta waves in inferior leads suggest posteroseptal pathway.",
        "overview": "WPW is caused by a congenital accessory pathway (Bundle of Kent) bypassing the AV node. Risk of sudden death via antidromic AF with rapid ventricular rates. Curative catheter ablation is first-line for symptomatic patients.",
        "ecg_points": [
            "Short PR interval (<120 ms) — early ventricular activation via accessory pathway",
            "Delta wave — slurred upstroke at the start of QRS (ventricular pre-excitation)",
            "Wide QRS complex (>120 ms) — fusion of pre-excited and normal ventricular activation",
            "Secondary ST-T changes discordant to QRS vector",
            "Pathway localisation: negative deltas in II,III,aVF → posteroseptal; positive V1 → left free wall",
            "Risk: AF with rapid conduction → ventricular fibrillation (avoid AV nodal blockers in AF+WPW)",
        ],
        "extra": None,
    },
    {
        "num": "6",
        "title": "Hypertrophic Cardiomyopathy (HCM)",
        "img_key": "hcm",
        "caption": "HCM (septal type): High-amplitude R waves in V2-V4 (LVH voltage criteria), ST-segment depression, and deep symmetric T-wave inversions V2-V6 with strain pattern. Absent septal Q waves in I, aVL, V5-V6. Positive T wave in aVR (arrhythmic risk marker).",
        "overview": "HCM is the most common inherited cardiac condition (1:500), caused by sarcomere protein mutations. The leading cause of sudden cardiac death in young athletes. ECG is abnormal in >90% of patients.",
        "ecg_points": [
            "LVH voltage: Sokolow-Lyon (SV1 + RV5/V6 >35 mm); Cornell (RaVL + SV3 >28 mm males)",
            "ST-segment depression and T-wave inversion (strain pattern) in I, aVL, V4-V6",
            "Giant deep symmetric T-wave inversions in V2-V5 (apical HCM/Yamaguchi syndrome, >10 mm)",
            "Absence of septal Q waves in lateral leads (V5, V6, I, aVL)",
            "Left axis deviation; left atrial enlargement (P mitrale in lead II)",
            "Positive T wave in aVR — associated with increased arrhythmic risk",
        ],
        "extra": None,
    },
    {
        "num": "7",
        "title": "Acute Pericarditis",
        "img_key": "pericarditis",
        "caption": "Acute pericarditis: Diffuse concave ('saddle-shaped') ST elevation across I, II, III, aVF, V2-V6 with PR depression in lead II (most sensitive sign); reciprocal ST depression and PR elevation only in aVR. Sinus tachycardia reflects systemic inflammation.",
        "overview": "Pericarditis is inflammation of the pericardium, most commonly viral. ECG evolves through 4 stages over days to weeks. Key differentiation from STEMI: diffuse non-territorial changes, concave morphology, PR depression.",
        "ecg_points": [
            "Stage I (Days 1-2): Diffuse concave 'saddle-shaped' ST elevation in all leads except aVR and V1; PR depression (most sensitive)",
            "Stage II (Days 3-7): ST returns to baseline; T waves flatten",
            "Stage III (Weeks 1-3): T-wave inversion in previously elevated leads",
            "Stage IV (Weeks-months): ECG normalises",
            "Key differentiators from STEMI: diffuse (not territorial), concave not convex, PR depression present, no reciprocal depression except aVR, no Q waves",
            "Spodick's sign: downsloping TP segment (subtle but specific)",
        ],
        "extra": {
            "type": "stage_table",
        },
    },
    {
        "num": "8",
        "title": "Pulmonary Embolism (PE)",
        "img_key": "pe",
        "caption": "Acute PE (S1Q3T3 pattern): Prominent deep S wave in lead I (S1), pathological Q wave in lead III (Q3), inverted T wave in lead III (T3), all annotated with circles/arrows. Sinus tachycardia >100 bpm reflecting acute right heart strain.",
        "overview": "PE causes acute right ventricular pressure overload. The ECG has low sensitivity (~20-30%) but high specificity for severe PE when S1Q3T3 + RBBB are present. Sinus tachycardia is the most common finding.",
        "ecg_points": [
            "Sinus tachycardia — most common finding (>40% of cases)",
            "S1Q3T3 pattern (McGinn-White sign): prominent S in lead I, Q wave in III, T-wave inversion in III",
            "Right axis deviation and right bundle branch block (complete or incomplete, rSR' in V1)",
            "T-wave inversions V1-V4 (right ventricular strain)",
            "P pulmonale — peaked P waves >2.5 mm in lead II (right atrial enlargement)",
            "New atrial fibrillation or flutter may appear in massive PE",
        ],
        "extra": None,
    },
    {
        "num": "9",
        "title": "Brugada Syndrome",
        "img_key": "brugada",
        "caption": "Brugada syndrome Type 1 (only diagnostic pattern): Coved ST-segment elevation ≥2 mm in V1-V2 starting from an elevated J-point, descending with convex morphology into a symmetrically inverted T wave. RBBB-like rSR' morphology.",
        "overview": "Brugada syndrome is an inherited SCN5A sodium channel channelopathy causing polymorphic VT and sudden cardiac death, predominantly in young men. Type 1 pattern on ECG (spontaneous or drug-induced) is required for diagnosis.",
        "ecg_points": [
            "Type 1 (Coved — DIAGNOSTIC): J-point ≥2 mm, convex downsloping ST segment, negative (inverted) T wave in V1-V2",
            "Type 2 (Saddle-back): J-point ≥2 mm, saddle-back ST, positive T wave — requires pharmacological challenge",
            "Changes confined to V1-V2; sensitivity improves with electrodes in 2nd-3rd ICS",
            "RBBB-like rSR' pattern in V1; first-degree AV block; prolonged PR interval",
            "Arrhythmia: polymorphic VT, often nocturnal, triggered by fever or sodium channel blockers",
            "Fragmented QRS (multiple notches in QRS) indicates delayed heterogeneous depolarisation — high-risk marker",
        ],
        "extra": {
            "type": "brugada_table",
        },
    },
    {
        "num": "10",
        "title": "Long QT Syndrome (LQTS)",
        "img_key": "lqts",
        "caption": "Long QT syndrome: Panel A — baseline ECG showing markedly prolonged QTc (680 ms) with prominent U waves (arrows in V1). Panel B — short-long-short sequence triggering polymorphic VT (torsades de pointes): rapid QRS complexes twisting around the isoelectric line.",
        "overview": "LQTS is an inherited repolarisation disorder (KCNQ1, KCNH2, SCN5A mutations). Prolonged QTc delays repolarisation, creating risk of early afterdepolarisations and torsades de pointes. QTc >500 ms is high risk.",
        "ecg_points": [
            "Prolonged QTc: ≥450 ms (males) or ≥460 ms (females) borderline; ≥500 ms high-risk",
            "Bazett formula: QTc = QT / sqrt(RR) — correct for heart rate",
            "LQT1 (KCNQ1): broad-based smooth T wave",
            "LQT2 (KCNH2): bifid/notched T wave (most common subtype)",
            "LQT3 (SCN5A): late-onset peaked T wave with long isoelectric ST segment",
            "Prominent U waves in V2-V3 (may fuse with T wave, masking true QT prolongation)",
            "T-wave alternans: beat-to-beat variation in T-wave amplitude/morphology — electrical instability sign",
            "Torsades de Pointes: polymorphic VT, QRS complexes twist around isoelectric baseline",
        ],
        "extra": None,
    },
]

# ── Build PDF ─────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    leftMargin=2*cm, rightMargin=2*cm,
    topMargin=2*cm, bottomMargin=2*cm,
    title="10 Common Heart Diseases — ECG Changes",
    author="Orris Medical AI",
    subject="Cardiology ECG Reference",
)

story = []
cover_page(story)

for disease in diseases:
    # Disease number + title
    story.append(Paragraph(f"DISEASE {disease['num']} OF 10", disease_num_style))
    story.append(Paragraph(disease["title"], disease_title_style))
    story.append(hr())

    # Overview
    story.append(section_header("Overview"))
    story.append(Paragraph(disease["overview"], body_style))
    story.append(Spacer(1, 6))

    # ECG Changes
    story.append(section_header("ECG Changes"))
    for point in disease["ecg_points"]:
        story.append(bullet(point))
    story.append(Spacer(1, 6))

    # Special tables
    if disease.get("extra"):
        if disease["extra"]["type"] == "stage_table":
            story.append(section_header("ECG Stage Evolution"))
            stage_data = [
                [Paragraph(h, table_header_style) for h in ["Stage", "Timing", "ECG Finding"]],
                [Paragraph("I", table_cell_style), Paragraph("Days 1-2", table_cell_style), Paragraph("Diffuse concave ST elevation; PR depression", table_cell_style)],
                [Paragraph("II", table_cell_style), Paragraph("Days 3-7", table_cell_style), Paragraph("ST returns to baseline; T waves flatten", table_cell_style)],
                [Paragraph("III", table_cell_style), Paragraph("Weeks 1-3", table_cell_style), Paragraph("T-wave inversion in previously elevated leads", table_cell_style)],
                [Paragraph("IV", table_cell_style), Paragraph("Weeks-months", table_cell_style), Paragraph("ECG normalises", table_cell_style)],
            ]
            stage_table = Table(stage_data, colWidths=[2*cm, 3.5*cm, 9.5*cm])
            stage_table.setStyle(TableStyle([
                ("BACKGROUND",   (0,0), (-1,0), DARK_RED),
                ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_GRAY]),
                ("GRID",         (0,0), (-1,-1), 0.4, colors.HexColor("#D5D8DC")),
                ("ROWPADDING",   (0,0), (-1,-1), 5),
                ("VALIGN",       (0,0), (-1,-1), "MIDDLE"),
            ]))
            story.append(stage_table)
            story.append(Spacer(1, 6))

        elif disease["extra"]["type"] == "brugada_table":
            story.append(section_header("Brugada ECG Pattern Classification"))
            brug_data = [
                [Paragraph(h, table_header_style) for h in ["Type", "ST Morphology", "T Wave", "Diagnostic?"]],
                [Paragraph("Type 1 (Coved)", table_cell_style), Paragraph("J-point ≥2 mm, convex downsloping", table_cell_style), Paragraph("Negative (inverted)", table_cell_style), Paragraph("YES", ParagraphStyle("Yes", parent=table_cell_style, textColor=colors.green, fontName="Helvetica-Bold"))],
                [Paragraph("Type 2 (Saddle-back)", table_cell_style), Paragraph("J-point ≥2 mm, saddle-back", table_cell_style), Paragraph("Positive", table_cell_style), Paragraph("NO (needs challenge)", ParagraphStyle("No", parent=table_cell_style, textColor=MED_RED))],
                [Paragraph("Type 3", table_cell_style), Paragraph("<2 mm ST elevation", table_cell_style), Paragraph("Positive", table_cell_style), Paragraph("NO", ParagraphStyle("No2", parent=table_cell_style, textColor=MED_RED))],
            ]
            brug_table = Table(brug_data, colWidths=[3.5*cm, 4.5*cm, 4*cm, 3*cm])
            brug_table.setStyle(TableStyle([
                ("BACKGROUND",   (0,0), (-1,0), DARK_RED),
                ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_GRAY]),
                ("GRID",         (0,0), (-1,-1), 0.4, colors.HexColor("#D5D8DC")),
                ("ROWPADDING",   (0,0), (-1,-1), 5),
                ("VALIGN",       (0,0), (-1,-1), "MIDDLE"),
            ]))
            story.append(brug_table)
            story.append(Spacer(1, 6))

    # ECG Image
    story.append(section_header("ECG Image"))
    story.append(Spacer(1, 4))
    for item in ecg_image(disease["img_key"], disease["caption"]):
        story.append(item)

    story.append(PageBreak())

# ── Build ─────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"\nPDF saved to: {OUTPUT}")
You've run out of free credits. Sign up for a free account to continue using Orris.
This is a shared conversation. Sign in to Orris to start your own chat.