Complete echo findings of severe ms with diagrams
severe mitral stenosis echocardiography findings 2D echo Doppler criteria diagrams
https://pmc.ncbi.nlm.nih.gov/articles/PMC3727554
| Parameter | Mild | Moderate | Severe |
|---|---|---|---|
| Valve area (cm²) | >1.5 | 1.0-1.5 | <1.0 |
| Mean gradient (mmHg) | <5 | 5-10 | >10 |
| PA systolic pressure (mmHg) | <30 | 30-50 | >50 |
| Pressure half-time (ms) | <150 | 150-220 | >220 |


| Chamber | Finding |
|---|---|
| Left Atrium (LA) | Markedly enlarged; "giant LA" in long-standing severe MS |
| LA appendage (LAA) | Dilated; often harbours thrombus (especially in AF) |
| Spontaneous echo contrast | "Smoke" in LA/LAA due to sluggish flow - indicates high thromboembolic risk |
| Left Ventricle (LV) | Small to normal-sized, normal wall thickness, normal systolic function (EF preserved) |
| Right Ventricle (RV) | Dilated and hypertrophied (from pulmonary hypertension) |
| Right Atrium (RA) | Enlarged (from TR and RV dysfunction) |
| Interventricular septum | Paradoxical motion in severe RV pressure overload |
| Pulmonary artery | Dilated |
| Feature | Finding |
|---|---|
| EF slope | Reduced (normal = 70-150 mm/s; severe MS <20 mm/s) |
| Anterior leaflet waveform | Box-like, flat EF slope; loss of normal "M" shape |
| Posterior leaflet motion | Moves anteriorly in diastole (same direction as AML) - reversal of normal posterior motion |
| AC shoulder | Absent or diminished |
| Leaflet thickening | Multiple dense echoes on M-mode |
| LA size | Increased on M-mode measurement |

| Doppler Parameter | Severe MS Value |
|---|---|
| Peak E velocity (Vmax) | >1.5 m/s (often 2-3 m/s) |
| Mean diastolic gradient | >10 mmHg |
| Deceleration slope | Very slow/gradual |
| Pressure Half-Time (PHT) | >220 ms |
| MVA by PHT | <1.0 cm² (using MVA = 220/T½) |
| Method | Technique | Notes |
|---|---|---|
| 2D Planimetry | PSAX view at leaflet tips; trace inner edge of orifice | Gold standard; start from apex, scan slowly to identify smallest orifice |
| 3D Planimetry | 3D dataset re-planed at minimal orifice | Most accurate; avoids oblique cutting error; recommended by ACC/AHA |
| PHT method | MVA = 220/T½ | Unreliable post-PBMV, abnormal compliance |
| Continuity equation | MVA = transmitral SV / VTI_MS | Useful when PHT unreliable; complex flow conditions |
| PISA method | MVA = (2πr² × Va × 0.5) / Vmax | Complex; less commonly used |
| Feature | Score 1 | Score 2 | Score 3 | Score 4 |
|---|---|---|---|---|
| Leaflet mobility | Highly mobile, restriction at tips only | Mid-body and base reduced mobility | Valve moves forward in diastole mainly from base | No or minimal forward movement |
| Valve thickening | Nearly normal (4-5 mm) | Mid-leaflet normal, tips thick (5-8 mm) | Thickening extends through entire leaflet (5-8 mm) | Marked thickening of all leaflet tissue (>8-10 mm) |
| Subvalvular thickening | Minimal chordal thickening just below valve | Thickening up to 1/3 of chordal length | Thickening extending to distal 1/3 of chords | Extensive thickening and shortening of all chords to papillary muscles |
| Calcification | A single bright echo area | Scattered areas of brightness confined to leaflet margins | Brightness extending into mid-portion of leaflets | Extensive brightness throughout much of leaflet tissue |
| Domain | What to Assess |
|---|---|
| Valve morphology | Commissural fusion, leaflet thickening, calcification, subvalvular apparatus |
| Valve area | 2D/3D planimetry (primary); PHT method; continuity equation |
| Gradient | Mean diastolic gradient (CW Doppler, apical view) |
| Wilkins score | For PBMV candidacy |
| LA / LAA | Size, spontaneous contrast, thrombus |
| LV | Size, systolic function (usually preserved) |
| Coexisting MR | Color Doppler, quantify if present |
| Tricuspid valve | TR Vmax → PASP estimate; TR severity |
| RV function | TAPSE, FAC, TDI S' wave |
| Pulmonary artery | Size, PASP |
| Other valves | AR, AS, TS - common in rheumatic disease |
| Parameter | Threshold for Severe |
|---|---|
| MVA (any method) | <1.0 cm² |
| Mean gradient | >10 mmHg |
| Pressure half-time | >220 ms |
| PA systolic pressure | >50 mmHg |
| Peak E velocity | >1.5-2.0 m/s |
| Wilkins score (high) | >11 (unfavorable anatomy) |
Tes
Create a PDF summary of severe MS echo findings for reference
ls -la /tmp/workspace/ 2>/dev/null || mkdir -p /tmp/workspace && echo "created"
~/severe_ms_echo_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
TableStyle, HRFlowable, KeepTogether)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import PageBreak
import os
os.makedirs("/tmp/workspace/output", exist_ok=True)
OUTPUT = "/tmp/workspace/output/Severe_MS_Echo_Reference.pdf"
# ── Colours ──────────────────────────────────────────────────────────────────
NAVY = colors.HexColor("#1B3A5C")
TEAL = colors.HexColor("#1A7A8A")
AMBER = colors.HexColor("#E07B20")
LIGHTBLUE = colors.HexColor("#D6EAF8")
LIGHTTEAL = colors.HexColor("#D1F2EB")
LIGHTAMB = colors.HexColor("#FDEBD0")
WHITE = colors.white
RED = colors.HexColor("#C0392B")
GREY_BG = colors.HexColor("#F2F2F2")
DARK_GREY = colors.HexColor("#4A4A4A")
MID_GREY = colors.HexColor("#888888")
# ── Document ──────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=18*mm, rightMargin=18*mm,
topMargin=15*mm, bottomMargin=15*mm,
title="Severe Mitral Stenosis – Complete Echocardiography Reference",
author="Orris Medical Reference",
)
W = A4[0] - 36*mm # usable width
# ── Styles ────────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
TITLE_STYLE = S("DocTitle",
fontName="Helvetica-Bold", fontSize=18, textColor=WHITE,
alignment=TA_CENTER, spaceAfter=4)
SUBTITLE_STYLE = S("DocSubtitle",
fontName="Helvetica", fontSize=10, textColor=colors.HexColor("#B0C4DE"),
alignment=TA_CENTER, spaceAfter=2)
SEC_STYLE = S("SecHead",
fontName="Helvetica-Bold", fontSize=11, textColor=WHITE,
spaceBefore=6, spaceAfter=3)
SUBSEC_STYLE = S("SubSecHead",
fontName="Helvetica-Bold", fontSize=9.5, textColor=NAVY,
spaceBefore=5, spaceAfter=2)
BODY = S("Body",
fontName="Helvetica", fontSize=8.5, textColor=DARK_GREY,
leading=13, spaceAfter=2)
BODY_BOLD = S("BodyBold",
fontName="Helvetica-Bold", fontSize=8.5, textColor=DARK_GREY,
leading=13, spaceAfter=2)
NOTE = S("Note",
fontName="Helvetica-Oblique", fontSize=7.5, textColor=MID_GREY,
leading=11, spaceAfter=2)
CELL = S("Cell",
fontName="Helvetica", fontSize=8, textColor=DARK_GREY, leading=11)
CELL_BOLD = S("CellBold",
fontName="Helvetica-Bold", fontSize=8, textColor=DARK_GREY, leading=11)
CELL_RED = S("CellRed",
fontName="Helvetica-Bold", fontSize=8, textColor=RED, leading=11)
CELL_WHITE = S("CellWhite",
fontName="Helvetica-Bold", fontSize=8.5, textColor=WHITE, leading=12)
CELL_TEAL = S("CellTeal",
fontName="Helvetica-Bold", fontSize=8, textColor=TEAL, leading=11)
# ── Helper: section header bar ────────────────────────────────────────────────
def section_header(text, color=NAVY):
data = [[Paragraph(text, SEC_STYLE)]]
t = Table(data, colWidths=[W])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [3]),
]))
return t
def subsec(text):
return Paragraph(text, SUBSEC_STYLE)
def body(text):
return Paragraph(text, BODY)
def note(text):
return Paragraph(f"<i>{text}</i>", NOTE)
def sp(h=4):
return Spacer(1, h*mm)
def hr(color=TEAL, thickness=0.5):
return HRFlowable(width="100%", thickness=thickness, color=color, spaceAfter=2*mm)
# ── Build story ───────────────────────────────────────────────────────────────
story = []
# ═══════════════════════════ TITLE BLOCK ═════════════════════════════════════
title_data = [[
Paragraph("SEVERE MITRAL STENOSIS", TITLE_STYLE),
],[
Paragraph("Complete Echocardiography Reference Card", SUBTITLE_STYLE),
],[
Paragraph("2D Echo · M-Mode · Doppler · Severity Criteria · Wilkins Score · Chamber Consequences",
SUBTITLE_STYLE),
]]
title_tbl = Table(title_data, colWidths=[W])
title_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
]))
story += [title_tbl, sp(4)]
# ═══════════════════════════ 1. SEVERITY CRITERIA ════════════════════════════
story += [section_header("1. SEVERITY CLASSIFICATION (ASE / EAE Criteria)"), sp(2)]
sev_data = [
[Paragraph("<b>Parameter</b>", CELL_WHITE),
Paragraph("<b>Mild</b>", CELL_WHITE),
Paragraph("<b>Moderate</b>", CELL_WHITE),
Paragraph("<b>SEVERE</b>", CELL_WHITE)],
[Paragraph("Valve Area (cm²)", CELL_BOLD),
Paragraph(">1.5", CELL),
Paragraph("1.0 – 1.5", CELL),
Paragraph("<b><font color='#C0392B'><1.0</font></b>", CELL)],
[Paragraph("Mean Gradient (mmHg)", CELL_BOLD),
Paragraph("<5", CELL),
Paragraph("5 – 10", CELL),
Paragraph("<b><font color='#C0392B'>>10</font></b>", CELL)],
[Paragraph("PA Systolic Pressure (mmHg)", CELL_BOLD),
Paragraph("<30", CELL),
Paragraph("30 – 50", CELL),
Paragraph("<b><font color='#C0392B'>>50</font></b>", CELL)],
[Paragraph("Pressure Half-Time (ms)", CELL_BOLD),
Paragraph("<150", CELL),
Paragraph("150 – 220", CELL),
Paragraph("<b><font color='#C0392B'>>220</font></b>", CELL)],
[Paragraph("Peak E-Velocity (m/s)", CELL_BOLD),
Paragraph("<1.0", CELL),
Paragraph("1.0 – 1.5", CELL),
Paragraph("<b><font color='#C0392B'>>1.5 – 2.0</font></b>", CELL)],
]
cw = [W*0.37, W*0.18, W*0.22, W*0.23]
sev_tbl = Table(sev_data, colWidths=cw)
sev_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("BACKGROUND", (0,1), (-1,1), LIGHTBLUE),
("BACKGROUND", (0,2), (-1,2), WHITE),
("BACKGROUND", (0,3), (-1,3), LIGHTBLUE),
("BACKGROUND", (0,4), (-1,4), WHITE),
("BACKGROUND", (0,5), (-1,5), LIGHTBLUE),
("BACKGROUND", (3,1), (3,5), LIGHTAMB),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story += [sev_tbl]
story += [sp(2), note("Gradients measured at HR 60-80 bpm in sinus rhythm. Valve area is the PRIMARY criterion for severity."), sp(3)]
# ═══════════════════════════ 2. 2D ECHO ══════════════════════════════════════
story += [section_header("2. 2D ECHOCARDIOGRAPHIC FINDINGS"), sp(2)]
# -- 2a Valve morphology
story += [subsec("A. Mitral Valve Morphology (Rheumatic MS)")]
morph_data = [
[Paragraph("<b>Feature</b>", CELL_WHITE),
Paragraph("<b>Description</b>", CELL_WHITE)],
[Paragraph("Commissural fusion", CELL_BOLD),
Paragraph("Fusion of medial and lateral commissures – the pathognomonic lesion of rheumatic MS", CELL)],
[Paragraph("Diastolic doming", CELL_BOLD),
Paragraph("Base and mid-body move toward LV apex; tips restricted → hockey-stick shape of AML in PLAX", CELL)],
[Paragraph("Posterior leaflet motion", CELL_BOLD),
Paragraph("PML moves ANTERIORLY in diastole (same direction as AML) – reversal of normal motion", CELL)],
[Paragraph("Leaflet thickening", CELL_BOLD),
Paragraph("Predominantly at tips; variable calcification of body in severe/chronic disease", CELL)],
[Paragraph("Subvalvular apparatus", CELL_BOLD),
Paragraph("Chordal thickening, fusion, shortening, fibrosis and calcification – prominent in severe MS", CELL)],
[Paragraph("Mitral orifice (PSAX)", CELL_BOLD),
Paragraph("Fish-mouth / slit-like appearance; area directly planimetered in PSAX view at leaflet tips", CELL)],
]
cw2 = [W*0.32, W*0.68]
morph_tbl = Table(morph_data, colWidths=cw2)
morph_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHTBLUE, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story += [morph_tbl, sp(3)]
# ═══════════════════════════ 3. M-MODE ═══════════════════════════════════════
story += [section_header("3. M-MODE ECHO FINDINGS"), sp(2)]
mmode_data = [
[Paragraph("<b>Feature</b>", CELL_WHITE),
Paragraph("<b>Finding in Severe MS</b>", CELL_WHITE),
Paragraph("<b>Normal</b>", CELL_WHITE)],
[Paragraph("EF slope (AML)", CELL_BOLD),
Paragraph("<b><font color='#C0392B'>Reduced: <20 mm/s</font></b>", CELL),
Paragraph("70–150 mm/s", CELL)],
[Paragraph("AML waveform", CELL_BOLD),
Paragraph("Box-like, flat slope; loss of normal \"M\" pattern", CELL),
Paragraph("Normal M-shape", CELL)],
[Paragraph("PML motion", CELL_BOLD),
Paragraph("Moves ANTERIORLY (same direction as AML) in diastole", CELL),
Paragraph("Moves posteriorly", CELL)],
[Paragraph("AC shoulder", CELL_BOLD),
Paragraph("Absent or diminished", CELL),
Paragraph("Present", CELL)],
[Paragraph("Leaflet appearance", CELL_BOLD),
Paragraph("Multiple dense echoes; thickened, brighter than normal", CELL),
Paragraph("Single thin line", CELL)],
[Paragraph("LA dimension", CELL_BOLD),
Paragraph("Increased (often >45 mm)", CELL),
Paragraph("<40 mm", CELL)],
]
cw3 = [W*0.30, W*0.42, W*0.28]
mmode_tbl = Table(mmode_data, colWidths=cw3)
mmode_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHTBLUE, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story += [mmode_tbl, sp(3)]
# ═══════════════════════════ 4. DOPPLER ══════════════════════════════════════
story += [section_header("4. DOPPLER FINDINGS"), sp(2)]
# 4a: CW Doppler table
story += [subsec("A. Continuous Wave Doppler (Apical 4-Chamber View)")]
cw_data = [
[Paragraph("<b>Parameter</b>", CELL_WHITE),
Paragraph("<b>Severe MS Value</b>", CELL_WHITE),
Paragraph("<b>Notes</b>", CELL_WHITE)],
[Paragraph("Peak E-velocity (Vmax)", CELL_BOLD),
Paragraph("<b><font color='#C0392B'>>1.5 – 2.0 m/s</font></b>", CELL),
Paragraph("CW cursor parallel to flow; use modal velocity", CELL)],
[Paragraph("Mean diastolic gradient", CELL_BOLD),
Paragraph("<b><font color='#C0392B'>>10 mmHg</font></b>", CELL),
Paragraph("Average 3-5 beats (5 in AF); flow-dependent", CELL)],
[Paragraph("Deceleration slope", CELL_BOLD),
Paragraph("Very slow / prolonged", CELL),
Paragraph("Reflects impaired pressure equalisation", CELL)],
[Paragraph("Pressure Half-Time (T½)", CELL_BOLD),
Paragraph("<b><font color='#C0392B'>>220 ms</font></b>", CELL),
Paragraph("Time Vmax → Vmax/√2; severe if >220 ms", CELL)],
[Paragraph("MVA by PHT", CELL_BOLD),
Paragraph("<b><font color='#C0392B'><1.0 cm²</font></b>", CELL),
Paragraph("MVA = 220 / T½ (empirical formula)", CELL)],
[Paragraph("Diastolic flow duration", CELL_BOLD),
Paragraph("Prolonged throughout diastole", CELL),
Paragraph("Gradient persists into late diastole", CELL)],
]
cw_t = Table(cw_data, colWidths=[W*0.30, W*0.28, W*0.42])
cw_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHTBLUE, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story += [cw_t, sp(2)]
# PHT formula box
pht_data = [[
Paragraph(
"<b>PHT Formula: MVA = 220 / T½</b><br/>"
"<font size='7.5'>where T½ = time (ms) from peak E-velocity to the point where velocity falls to Vmax/√2 (= Vmax × 0.707)<br/>"
"Caution: NOT valid immediately after PBMV; unreliable with significant AR or abnormal LV/LA compliance</font>",
S("pht", fontName="Helvetica", fontSize=8.5, textColor=NAVY, leading=13))
]]
pht_tbl = Table(pht_data, colWidths=[W])
pht_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHTBLUE),
("BOX", (0,0), (-1,-1), 1.2, TEAL),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
]))
story += [pht_tbl, sp(3)]
# 4b: Color Doppler
story += [subsec("B. Color Flow Doppler")]
color_data = [
[Paragraph("<b>Finding</b>", CELL_WHITE),
Paragraph("<b>Description</b>", CELL_WHITE)],
[Paragraph("Diastolic inflow jet", CELL_BOLD),
Paragraph("Narrow, turbulent, aliased jet through the stenotic mitral orifice", CELL)],
[Paragraph("PISA (atrial side)", CELL_BOLD),
Paragraph("Concentric zone of flow acceleration (proximal isovelocity surface area) on LA side in diastole", CELL)],
[Paragraph("Intraventricular vortex", CELL_BOLD),
Paragraph("Swirling turbulent flow within LV cavity after crossing stenotic valve", CELL)],
[Paragraph("Coexistent MR", CELL_BOLD),
Paragraph("Systolic regurgitant jet into LA – common in rheumatic disease; quantify if present", CELL)],
]
color_tbl = Table(color_data, colWidths=cw2)
color_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHTBLUE, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story += [color_tbl, sp(3)]
# ═══════════════════════════ 5. MVA METHODS ══════════════════════════════════
story += [section_header("5. MITRAL VALVE AREA – MEASUREMENT METHODS"), sp(2)]
mva_data = [
[Paragraph("<b>Method</b>", CELL_WHITE),
Paragraph("<b>Technique</b>", CELL_WHITE),
Paragraph("<b>Key Points / Pitfalls</b>", CELL_WHITE)],
[Paragraph("2D Planimetry\n(PSAX)", CELL_BOLD),
Paragraph("Trace inner edge of orifice in PSAX at leaflet tips; low gain", CELL),
Paragraph("Scan from apex toward base to identify smallest orifice; calcification may cause overestimation", CELL)],
[Paragraph("3D Planimetry\n(Recommended)", CELL_BOLD),
Paragraph("Align 3D dataset at plane of minimal orifice; trace orifice", CELL),
Paragraph("Most accurate; avoids oblique-cut error; best for asymmetric commissural fusion", CELL)],
[Paragraph("Pressure Half-Time\n(PHT)", CELL_BOLD),
Paragraph("MVA = 220 / T½ from CW Doppler apical view", CELL),
Paragraph("Unreliable post-PBMV, significant AR, or abnormal compliance", CELL)],
[Paragraph("Continuity Equation", CELL_BOLD),
Paragraph("MVA = (transmitral SV) / VTI_MS", CELL),
Paragraph("Useful when PHT unreliable; requires absence of significant MR/AR", CELL)],
[Paragraph("PISA Method", CELL_BOLD),
Paragraph("MVA = (2πr² × Va × 0.5) / Vmax", CELL),
Paragraph("Complex; semi-quantitative; less commonly used clinically", CELL)],
]
mva_tbl = Table(mva_data, colWidths=[W*0.22, W*0.38, W*0.40])
mva_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHTBLUE, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story += [mva_tbl, sp(3)]
# ═══════════════════════════ 6. CHAMBER CONSEQUENCES ═════════════════════════
story += [section_header("6. CHAMBER CONSEQUENCES IN SEVERE MS"), sp(2)]
chamber_data = [
[Paragraph("<b>Chamber / Structure</b>", CELL_WHITE),
Paragraph("<b>Echo Finding</b>", CELL_WHITE),
Paragraph("<b>Clinical Significance</b>", CELL_WHITE)],
[Paragraph("Left Atrium (LA)", CELL_BOLD),
Paragraph("Markedly enlarged; 'giant LA' in long-standing severe MS", CELL),
Paragraph("Stasis, thrombus risk, AF", CELL)],
[Paragraph("LA Appendage (LAA)", CELL_BOLD),
Paragraph("Dilated; spontaneous echo contrast ('smoke'); thrombus in AF", CELL),
Paragraph("High thromboembolic risk; TEE mandatory before PBMV", CELL)],
[Paragraph("Left Ventricle (LV)", CELL_BOLD),
Paragraph("Small-normal size; NORMAL systolic function (EF preserved)", CELL),
Paragraph("LV dilation suggests coexisting MR/AR/cardiomyopathy", CELL)],
[Paragraph("Right Ventricle (RV)", CELL_BOLD),
Paragraph("Dilated + hypertrophied (chronic pressure overload)", CELL),
Paragraph("RV failure = poor prognosis", CELL)],
[Paragraph("Right Atrium (RA)", CELL_BOLD),
Paragraph("Enlarged (secondary to TR and elevated RV pressures)", CELL),
Paragraph("TR severity correlates with PA pressure", CELL)],
[Paragraph("Pulmonary Artery (PA)", CELL_BOLD),
Paragraph("Dilated; PASP >50 mmHg by TR jet velocity", CELL),
Paragraph("Reactive PH may persist post-intervention", CELL)],
[Paragraph("IVS", CELL_BOLD),
Paragraph("Paradoxical septal motion in severe RV pressure overload", CELL),
Paragraph("Indicates RV volume/pressure overload", CELL)],
]
ch_tbl = Table(chamber_data, colWidths=[W*0.27, W*0.40, W*0.33])
ch_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHTBLUE, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story += [ch_tbl, sp(3)]
# ═══════════════════════════ 7. WILKINS SCORE ════════════════════════════════
story += [section_header("7. WILKINS ECHOCARDIOGRAPHIC SCORE (PBMV Selection)", color=AMBER), sp(2)]
wilk_header = [
Paragraph("<b>Feature</b>", CELL_WHITE),
Paragraph("<b>Score 1</b>", CELL_WHITE),
Paragraph("<b>Score 2</b>", CELL_WHITE),
Paragraph("<b>Score 3</b>", CELL_WHITE),
Paragraph("<b>Score 4</b>", CELL_WHITE),
]
wilk_data = [
wilk_header,
[Paragraph("<b>Mobility</b>", CELL_BOLD),
Paragraph("Highly mobile; restriction at tips only", CELL),
Paragraph("Mid-body and base reduced", CELL),
Paragraph("Forward movement mainly from base", CELL),
Paragraph("No/minimal forward movement", CELL)],
[Paragraph("<b>Thickening</b>", CELL_BOLD),
Paragraph("Nearly normal (4-5 mm)", CELL),
Paragraph("Tips thick (5-8 mm); mid-body normal", CELL),
Paragraph("Thickening through entire leaflet (5-8 mm)", CELL),
Paragraph("Marked thickening all tissue (>8 mm)", CELL)],
[Paragraph("<b>Subvalvular</b>", CELL_BOLD),
Paragraph("Minimal thickening just below valve", CELL),
Paragraph("Thickening up to 1/3 chordal length", CELL),
Paragraph("Thickening to distal 1/3 of chords", CELL),
Paragraph("Extensive thickening to papillary muscles", CELL)],
[Paragraph("<b>Calcification</b>", CELL_BOLD),
Paragraph("Single bright echo at margins", CELL),
Paragraph("Scattered brightness at margins", CELL),
Paragraph("Brightness into mid-leaflet", CELL),
Paragraph("Extensive brightness throughout leaflet", CELL)],
]
wcw = [W*0.18, W*0.205, W*0.205, W*0.205, W*0.205]
wilk_tbl = Table(wilk_data, colWidths=wcw)
wilk_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#B7770D")),
("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHTAMB, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story += [wilk_tbl, sp(2)]
# Score interpretation
score_interp = [
[Paragraph("<b>Total Score</b>", CELL_WHITE),
Paragraph("<b>Interpretation</b>", CELL_WHITE),
Paragraph("<b>Recommendation</b>", CELL_WHITE)],
[Paragraph("≤ 8", CELL_BOLD),
Paragraph("Favourable anatomy", CELL),
Paragraph("PBMV – good results expected (>80% success)", CELL)],
[Paragraph("9 – 11", CELL_BOLD),
Paragraph("Intermediate", CELL),
Paragraph("3D echo may help reclassify; individualise decision", CELL)],
[Paragraph("> 11", CELL_BOLD),
Paragraph("<b><font color='#C0392B'>Unfavourable anatomy</font></b>", CELL),
Paragraph("Surgical MVR preferred; PBMV high risk of failure/MR", CELL)],
]
si_tbl = Table(score_interp, colWidths=[W*0.18, W*0.30, W*0.52])
si_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#B7770D")),
("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHTAMB, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story += [si_tbl, sp(3)]
# ═══════════════════════════ 8. TEE INDICATIONS ══════════════════════════════
story += [section_header("8. TEE INDICATIONS IN SEVERE MS"), sp(2)]
tee_data = [
[Paragraph("<b>Indication</b>", CELL_WHITE),
Paragraph("<b>Details</b>", CELL_WHITE)],
[Paragraph("LA/LAA thrombus detection", CELL_BOLD),
Paragraph("TTE sensitivity <50%; TEE sensitivity ~99%, specificity ~99%. MANDATORY before PBMV", CELL)],
[Paragraph("Spontaneous echo contrast", CELL_BOLD),
Paragraph("'Smoke' in LA/LAA indicates severe stasis and high embolic risk", CELL)],
[Paragraph("Valve morphology", CELL_BOLD),
Paragraph("Better resolution of commissural fusion, subvalvular apparatus, calcification extent", CELL)],
[Paragraph("MR quantification", CELL_BOLD),
Paragraph("Accurate grading before any intervention; >moderate MR contraindicates PBMV", CELL)],
[Paragraph("Post-PBMV assessment", CELL_BOLD),
Paragraph("Commissural splitting, new/worsened MR, residual gradient, pericardial effusion", CELL)],
[Paragraph("Intraoperative guidance", CELL_BOLD),
Paragraph("Surgical commissurotomy and mitral valve repair/replacement", CELL)],
]
tee_tbl = Table(tee_data, colWidths=cw2)
tee_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHTBLUE, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story += [tee_tbl, sp(3)]
# ═══════════════════════════ 9. COMPLETE ECHO CHECKLIST ══════════════════════
story += [section_header("9. COMPLETE ECHO EXAMINATION CHECKLIST"), sp(2)]
chk_data = [
[Paragraph("<b>Domain</b>", CELL_WHITE),
Paragraph("<b>What to Assess</b>", CELL_WHITE),
Paragraph("<b>Tool/View</b>", CELL_WHITE)],
[Paragraph("Valve morphology", CELL_BOLD),
Paragraph("Commissural fusion, thickening, calcification, subvalvular apparatus", CELL),
Paragraph("PLAX, PSAX, apical views; 3D", CELL)],
[Paragraph("Valve area", CELL_BOLD),
Paragraph("2D/3D planimetry (primary); PHT method; continuity equation", CELL),
Paragraph("PSAX; apical CW Doppler", CELL)],
[Paragraph("Pressure gradient", CELL_BOLD),
Paragraph("Mean diastolic gradient – average 3-5 beats (5 in AF)", CELL),
Paragraph("Apical CW Doppler", CELL)],
[Paragraph("Wilkins score", CELL_BOLD),
Paragraph("Mobility, thickening, subvalvular, calcification – each 1-4", CELL),
Paragraph("PLAX, PSAX, apical", CELL)],
[Paragraph("LA / LAA", CELL_BOLD),
Paragraph("Size, spontaneous contrast, thrombus", CELL),
Paragraph("TTE + TEE", CELL)],
[Paragraph("LV function", CELL_BOLD),
Paragraph("Size, EF (usually preserved); wall motion; diastolic parameters NOT reliable", CELL),
Paragraph("Apical views; M-mode", CELL)],
[Paragraph("Coexisting MR", CELL_BOLD),
Paragraph("Color Doppler; quantify grade; exclude severe MR before PBMV", CELL),
Paragraph("Apical views; CW/PW Doppler", CELL)],
[Paragraph("Tricuspid valve", CELL_BOLD),
Paragraph("TR Vmax → PASP (4v² + RAP); TR severity grade", CELL),
Paragraph("Apical 4C; CW Doppler", CELL)],
[Paragraph("RV function", CELL_BOLD),
Paragraph("TAPSE (>17 mm normal); TDI S' wave (>9.5 cm/s); FAC (>35%)", CELL),
Paragraph("Apical 4C; M-mode", CELL)],
[Paragraph("Pulmonary artery", CELL_BOLD),
Paragraph("PA size; estimate PASP; Doppler PA flow acceleration time", CELL),
Paragraph("PSAX at AV level", CELL)],
[Paragraph("Other valves", CELL_BOLD),
Paragraph("Aortic (AR, AS), tricuspid stenosis – common in rheumatic disease", CELL),
Paragraph("Multiple views", CELL)],
]
chk_tbl = Table(chk_data, colWidths=[W*0.23, W*0.47, W*0.30])
chk_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHTBLUE, WHITE]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story += [chk_tbl, sp(3)]
# ═══════════════════════════ 10. QUICK REFERENCE BOX ═════════════════════════
story += [section_header("10. SEVERE MS AT A GLANCE – QUICK REFERENCE", color=RED), sp(2)]
quick_data = [
[Paragraph("<b>Parameter</b>", CELL_WHITE),
Paragraph("<b>Severe MS Threshold</b>", CELL_WHITE)],
[Paragraph("Mitral Valve Area", CELL_BOLD),
Paragraph("<b><font color='#C0392B' size='10'>< 1.0 cm²</font></b>", CELL)],
[Paragraph("Mean Diastolic Gradient", CELL_BOLD),
Paragraph("<b><font color='#C0392B' size='10'>> 10 mmHg</font></b>", CELL)],
[Paragraph("Pressure Half-Time", CELL_BOLD),
Paragraph("<b><font color='#C0392B' size='10'>> 220 ms</font></b>", CELL)],
[Paragraph("PA Systolic Pressure", CELL_BOLD),
Paragraph("<b><font color='#C0392B' size='10'>> 50 mmHg</font></b>", CELL)],
[Paragraph("Peak E-velocity (Vmax)", CELL_BOLD),
Paragraph("<b><font color='#C0392B' size='10'>> 1.5 – 2.0 m/s</font></b>", CELL)],
[Paragraph("Wilkins Score (unfavourable)", CELL_BOLD),
Paragraph("<b><font color='#C0392B' size='10'>> 11</font></b>", CELL)],
]
q_tbl = Table(quick_data, colWidths=[W*0.50, W*0.50])
q_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#8B0000")),
("ROWBACKGROUNDS",(0,1), (-1,-1), [colors.HexColor("#FFF0F0"), WHITE]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story += [q_tbl, sp(3)]
# ═══════════════════════════ FOOTER / SOURCE ═════════════════════════════════
hr_line = HRFlowable(width="100%", thickness=1, color=NAVY, spaceAfter=3*mm)
story.append(hr_line)
story.append(Paragraph(
"<i>Sources: Textbook of Clinical Echocardiography 6e (Otto & Bonow) · Braunwald's Heart Disease 11e · "
"Fuster & Hurst's The Heart 15e · ASE/EAE Echocardiographic Assessment of Valve Stenosis · "
"PMC3727554 (Echocardiography in Mitral Stenosis). "
"Generated by Orris Medical Reference · July 2026</i>",
NOTE))
# ── Build ─────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF saved to: {OUTPUT}")
cd /tmp/workspace && python severe_ms_echo_pdf.py
ls -lh /tmp/workspace/output/Severe_MS_Echo_Reference.pdf
Severe MS Echo Reference
PDF Document · PDF
Complete echo findings of severe mr with diagrams
severe mitral regurgitation echocardiography complete findings 2D Doppler EROA vena contracta criteria ASE