Another md pathology exam question Atypical CML
"There is no BCR-ABL-negative CML, and such diseases as 'atypical' CML and chronic neutrophilic leukemia have distinct genetic features that identify them as unique disease entities." - Goldman-Cecil Medicine
| Feature | Details |
|---|---|
| Leukocytosis | WBC >13 × 10⁹/L |
| Peripheral blood | Spectrum of maturing neutrophils + metamyelocytes + myelocytes + promyelocytes (granulocyte dysplasia is characteristic) |
| Blasts | <20% (>20% = AML transformation) |
| Bone marrow | Myeloid hyperplasia with dysplasia (dysgranulopoiesis) |
| Monocytes | NOT a prominent feature (unlike CMML, monocytes are NOT >10%) |
| Basophilia | Absent or minimal (contrasts with classic BCR-ABL+ CML) |
| Philadelphia chromosome | Absent |
| BCR-ABL1 | Absent (mandatory exclusion) |
| Feature | Classic CML | Atypical CML |
|---|---|---|
| BCR-ABL1 / Ph chromosome | Present | Absent |
| Dysplasia | Absent | Present (hallmark) |
| Basophilia | Prominent | Absent/minimal |
| Eosinophilia | Common | Less prominent |
| WHO group | MPN | MDS/MPN |
| TKI response | Excellent | None |
| Prognosis | Good with TKI | Poor (median survival ~2-3 years) |
Make a study guide on MDS/MPN overlap disorders for board prep
ls /tmp/workspace/ 2>/dev/null && mkdir -p /tmp/workspace/mds-mpn-guide
~/mds-mpn-guide/build_deck.py
from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.util import Inches, Pt
import copy
from io import BytesIO
# ── Colour palette ──────────────────────────────────────────────────────────
C_DARK_BLUE = RGBColor(0x1A, 0x37, 0x6C) # deep navy
C_MED_BLUE = RGBColor(0x27, 0x5D, 0xA6) # accent blue
C_LIGHT_BLUE = RGBColor(0xD6, 0xE4, 0xF7) # pale blue fill
C_TEAL = RGBColor(0x00, 0x86, 0x8A) # teal accent
C_ORANGE = RGBColor(0xE8, 0x7D, 0x1E) # warm orange
C_RED = RGBColor(0xC0, 0x39, 0x2B) # alert red
C_GREEN = RGBColor(0x1E, 0x8A, 0x44) # green
C_WHITE = RGBColor(0xFF, 0xFF, 0xFF)
C_DARK_GREY = RGBColor(0x2C, 0x2C, 0x2C)
C_MID_GREY = RGBColor(0x60, 0x60, 0x60)
C_LIGHT_GREY = RGBColor(0xF4, 0xF6, 0xF9)
C_GOLD = RGBColor(0xF0, 0xC0, 0x27)
C_PURPLE = RGBColor(0x6C, 0x3D, 0x9E)
prs = Presentation()
prs.slide_width = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]
# ── Helper functions ─────────────────────────────────────────────────────────
def add_rect(slide, x, y, w, h, fill_rgb=None, line_rgb=None, line_width=None):
shape = slide.shapes.add_shape(1, Inches(x), Inches(y), Inches(w), Inches(h))
if fill_rgb:
shape.fill.solid()
shape.fill.fore_color.rgb = fill_rgb
else:
shape.fill.background()
if line_rgb:
shape.line.color.rgb = line_rgb
if line_width:
shape.line.width = Pt(line_width)
else:
shape.line.fill.background()
return shape
def add_text(slide, text, x, y, w, h, size=14, bold=False, color=C_DARK_GREY,
align=PP_ALIGN.LEFT, italic=False, wrap=True, anchor=MSO_ANCHOR.TOP):
tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = wrap
tf.vertical_anchor = anchor
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = 0
p = tf.paragraphs[0]
p.alignment = align
run = p.add_run()
run.text = text
run.font.size = Pt(size)
run.font.bold = bold
run.font.italic = italic
run.font.color.rgb = color
run.font.name = "Calibri"
return tf
def add_multiline_text(slide, lines, x, y, w, h, size=11, color=C_DARK_GREY,
bold_first=False, wrap=True, line_spacing=None):
"""lines = list of (text, bold, color_override)"""
tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
tf = tb.text_frame
tf.word_wrap = wrap
tf.margin_left = tf.margin_right = tf.margin_top = tf.margin_bottom = 0
for i, item in enumerate(lines):
if isinstance(item, str):
text, bold, col = item, False, color
else:
text = item[0]
bold = item[1] if len(item) > 1 else False
col = item[2] if len(item) > 2 else color
if i == 0:
p = tf.paragraphs[0]
else:
p = tf.add_paragraph()
if line_spacing:
p.space_before = Pt(line_spacing)
run = p.add_run()
run.text = text
run.font.size = Pt(size)
run.font.bold = bold
run.font.color.rgb = col
run.font.name = "Calibri"
return tf
def slide_header(slide, title, subtitle=None,
bar_color=C_DARK_BLUE, title_color=C_WHITE):
"""Top header bar with title"""
add_rect(slide, 0, 0, 13.333, 1.0, fill_rgb=bar_color)
add_text(slide, title, 0.35, 0.08, 12.5, 0.85,
size=26, bold=True, color=title_color, align=PP_ALIGN.LEFT,
anchor=MSO_ANCHOR.MIDDLE)
if subtitle:
add_text(slide, subtitle, 0.35, 0.78, 12, 0.3,
size=11, bold=False, color=C_LIGHT_BLUE, align=PP_ALIGN.LEFT)
def footer(slide, text="MDS/MPN Overlap Disorders | Board Prep Study Guide"):
add_rect(slide, 0, 7.15, 13.333, 0.35, fill_rgb=C_DARK_BLUE)
add_text(slide, text, 0.3, 7.17, 12.5, 0.3,
size=9, color=C_LIGHT_BLUE, align=PP_ALIGN.LEFT)
def section_pill(slide, text, x, y, w=2.5, h=0.32, color=C_MED_BLUE):
add_rect(slide, x, y, w, h, fill_rgb=color)
add_text(slide, text, x+0.05, y, w-0.1, h,
size=9, bold=True, color=C_WHITE, align=PP_ALIGN.CENTER,
anchor=MSO_ANCHOR.MIDDLE)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 1 – Title Slide
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
# Full background gradient-like via two rects
add_rect(s, 0, 0, 13.333, 7.5, fill_rgb=C_DARK_BLUE)
add_rect(s, 0, 0, 13.333, 3.5, fill_rgb=C_MED_BLUE)
# Accent stripe
add_rect(s, 0, 3.4, 13.333, 0.12, fill_rgb=C_GOLD)
add_text(s, "MDS / MPN Overlap Disorders", 0.6, 0.5, 12, 2.2,
size=44, bold=True, color=C_WHITE, align=PP_ALIGN.CENTER,
anchor=MSO_ANCHOR.MIDDLE)
add_text(s, "Myelodysplastic / Myeloproliferative Neoplasms", 0.6, 2.6, 12, 0.7,
size=20, bold=False, color=C_GOLD, align=PP_ALIGN.CENTER)
add_text(s, "Board Prep Study Guide | Pathology | 2026", 0.6, 3.7, 12, 0.5,
size=16, color=RGBColor(0xAA, 0xCC, 0xEE), align=PP_ALIGN.CENTER)
# Entity pills
entities = ["CMML", "aCML", "JMML", "MDS/MPN-U", "CNL (ref)"]
cols = [C_TEAL, C_ORANGE, C_GREEN, C_PURPLE, C_MID_GREY]
for i, (ent, col) in enumerate(zip(entities, cols)):
xx = 1.2 + i * 2.2
add_rect(s, xx, 4.5, 2.0, 0.55, fill_rgb=col)
add_text(s, ent, xx, 4.5, 2.0, 0.55,
size=13, bold=True, color=C_WHITE, align=PP_ALIGN.CENTER,
anchor=MSO_ANCHOR.MIDDLE)
add_text(s, "Sources: Quick Compendium Clinical Pathology 5e | Harrison's 22E | Goldman-Cecil | Henry's Lab Medicine",
0.6, 7.1, 12, 0.35, size=9, color=RGBColor(0x88, 0xAA, 0xCC),
align=PP_ALIGN.CENTER)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 2 – Overview & Classification
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, fill_rgb=C_LIGHT_GREY)
slide_header(s, "Overview: What Are MDS/MPN Overlap Disorders?")
footer(s)
# Left panel – concept
add_rect(s, 0.25, 1.1, 5.8, 5.9, fill_rgb=C_WHITE, line_rgb=C_MED_BLUE, line_width=1)
add_text(s, "Core Concept", 0.4, 1.15, 5.5, 0.4,
size=13, bold=True, color=C_DARK_BLUE)
concept_lines = [
("Features of BOTH myelodysplasia AND myeloproliferation simultaneously", False),
("", False),
("MDS features:", True, C_MED_BLUE),
(" • Cytopenias (dysplastic blood cells)", False),
(" • Bone marrow dysplasia", False),
(" • Ineffective haematopoiesis", False),
("", False),
("MPN features:", True, C_TEAL),
(" • Hypercellular marrow", False),
(" • Peripheral blood leukocytosis / monocytosis", False),
(" • Splenomegaly", False),
("", False),
("Key rule: BCR-ABL1 MUST be absent in all entities", True, C_RED),
("Philadelphia chromosome MUST be absent", False, C_RED),
]
add_multiline_text(s, concept_lines, 0.4, 1.6, 5.5, 5.2, size=11, line_spacing=1)
# Right panel – WHO entities table
add_rect(s, 6.4, 1.1, 6.7, 5.9, fill_rgb=C_WHITE, line_rgb=C_MED_BLUE, line_width=1)
add_text(s, "WHO 2022 Classification – MDS/MPN Entities", 6.55, 1.15, 6.4, 0.4,
size=13, bold=True, color=C_DARK_BLUE)
# Table header
add_rect(s, 6.4, 1.6, 6.7, 0.38, fill_rgb=C_DARK_BLUE)
add_text(s, "Entity", 6.45, 1.62, 2.2, 0.34, size=10, bold=True, color=C_WHITE)
add_text(s, "Key Defining Feature", 8.7, 1.62, 4.2, 0.34, size=10, bold=True, color=C_WHITE)
rows = [
("CMML", "Monocytosis >1×10⁹/L + dysplasia", C_WHITE, C_DARK_GREY),
("aCML", "Neutrophilia + dysgranulopoiesis, no BCR-ABL", C_LIGHT_BLUE, C_DARK_GREY),
("JMML", "Children; RAS/MAPK mutations; monocytosis", C_WHITE, C_DARK_GREY),
("MDS/MPN-RS-T", "Ring sideroblasts + thrombocytosis, SF3B1", C_LIGHT_BLUE, C_DARK_GREY),
("MDS/MPN-U", "MDS/MPN features, not fitting above", C_WHITE, C_DARK_GREY),
]
for i, (name, feat, bg, fg) in enumerate(rows):
yy = 2.02 + i * 0.88
add_rect(s, 6.4, yy, 6.7, 0.86, fill_rgb=bg, line_rgb=RGBColor(0xCC, 0xDD, 0xEE), line_width=0.5)
add_text(s, name, 6.45, yy+0.05, 2.2, 0.76, size=11, bold=True, color=C_DARK_BLUE)
add_text(s, feat, 8.7, yy+0.05, 4.2, 0.76, size=10, color=fg, wrap=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 3 – CMML Part 1: Criteria & Morphology
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, fill_rgb=C_LIGHT_GREY)
slide_header(s, "CMML – Chronic Myelomonocytic Leukemia (1/2)", bar_color=C_TEAL)
footer(s)
# Diagnostic criteria box
add_rect(s, 0.25, 1.1, 8.2, 4.1, fill_rgb=C_WHITE, line_rgb=C_TEAL, line_width=1.5)
section_pill(s, "WHO Diagnostic Criteria (ALL required)", 0.35, 1.1, 3.5, color=C_TEAL)
crit_lines = [
("1. Sustained PB monocytosis ≥0.5×10⁹/L AND monocytes ≥10% of WBC differential", False),
(" (must persist >3 months; exclude reactive causes first)", False, C_MID_GREY),
("2. Not meeting criteria for BCR-ABL1+ CML, PV, ET, or PMF", False),
("3. No PDGFRA, PDGFRB, FGFR1, PCM1-JAK2 rearrangements", False),
("4. <20% blasts + promonocytes in PB and BM", False),
(" (≥20% → reclassify as AML)", False, C_RED),
("5. Dysplasia in ≥1 myeloid lineage OR cytogenetic/molecular clonality evidence", False),
]
add_multiline_text(s, crit_lines, 0.4, 1.55, 7.9, 3.4, size=11, line_spacing=2)
# Subtype box
add_rect(s, 0.25, 5.3, 8.2, 1.9, fill_rgb=C_WHITE, line_rgb=C_TEAL, line_width=1)
section_pill(s, "Subtypes (WBC-based)", 0.35, 5.3, 2.5, color=C_TEAL)
subtype_lines = [
("MDS-CMML (WBC <13×10⁹/L): cytopenia-predominant, dyplastic features", False),
("MPN-CMML (WBC ≥13×10⁹/L): proliferative, splenomegaly, constitutional symptoms", False),
("Blast count: CMML-1 = <5% PB blasts, <10% BM blasts | CMML-2 = 5–19% PB or 10–19% BM", True, C_MED_BLUE),
]
add_multiline_text(s, subtype_lines, 0.4, 5.7, 7.9, 1.4, size=11, line_spacing=3)
# Right info panel
add_rect(s, 8.65, 1.1, 4.45, 6.1, fill_rgb=C_WHITE, line_rgb=C_TEAL, line_width=1)
section_pill(s, "Key Facts", 8.75, 1.1, 1.8, color=C_DARK_BLUE)
facts = [
("Epidemiology", True, C_DARK_BLUE),
("• Median age 73–75 years", False),
("• Male predominance (1.5–3:1)", False),
("• Incidence ~4/100,000/year", False),
("", False),
("Genetics", True, C_DARK_BLUE),
("• TET2 ~60% (epigenetic)", False),
("• SRSF2 ~50% (splicing)", False),
("• ASXL1 ~40% (chromatin)", False),
("• RAS pathway ~30%", False),
("• TET2 + SRSF2 co-mutation → CMML phenotype", False),
("• Cytogenetics abnormal in ~30%", False),
(" (trisomy 8, -7/del7q most common)", False),
("", False),
("Immunophenotype", True, C_DARK_BLUE),
("• CD13+, CD33+ (myelomonocytic)", False),
("• CD14+, CD64+, CD68+, CD163+ (variable)", False),
("• Classical MO1: CD14+/CD16−", False),
("• Dual esterase staining characteristic", False),
]
add_multiline_text(s, facts, 8.75, 1.5, 4.1, 5.5, size=10, line_spacing=1)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 4 – CMML Part 2: Differential, Treatment, Prognosis
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, fill_rgb=C_LIGHT_GREY)
slide_header(s, "CMML – Differential Diagnosis, Treatment & Prognosis (2/2)", bar_color=C_TEAL)
footer(s)
# Differential
add_rect(s, 0.25, 1.1, 6.1, 5.9, fill_rgb=C_WHITE, line_rgb=C_TEAL, line_width=1)
section_pill(s, "Reactive Monocytosis – Must Exclude First", 0.35, 1.1, 4.0, color=C_RED)
diff_lines = [
("Infections:", True, C_DARK_BLUE),
(" TB, fungal infections, subacute bacterial endocarditis", False),
(" Viral infections, protozoal infections", False),
("", False),
("Autoimmune / Inflammatory:", True, C_DARK_BLUE),
(" Connective tissue diseases, sarcoidosis", False),
(" Lipid storage disorders", False),
("", False),
("Other:", True, C_DARK_BLUE),
(" Post-splenectomy state", False),
(" BM regeneration after chemotherapy", False),
(" Recovery phase of acute infection", False),
("", False),
("Haematologic mimics:", True, C_DARK_BLUE),
(" BCR-ABL1+ CML (exclude by FISH/PCR)", False),
(" PDGFRA/PDGFRB rearrangements → exclude", False),
(" Primary myelofibrosis with monocytosis", False),
(" PV with monocytosis", False),
]
add_multiline_text(s, diff_lines, 0.4, 1.55, 5.7, 5.3, size=10.5, line_spacing=1)
# Treatment & Prognosis
add_rect(s, 6.6, 1.1, 6.5, 2.8, fill_rgb=C_WHITE, line_rgb=C_ORANGE, line_width=1)
section_pill(s, "Treatment", 6.7, 1.1, 1.8, color=C_ORANGE)
tx_lines = [
("• Hypomethylating agents (azacitidine/decitabine)", False),
(" Response rate ~30–40%", False, C_MID_GREY),
("• Hydroxyurea: proliferative disease control", False),
("• Allogeneic HSCT: only curative option", True, C_RED),
("• Clinical trials: JAK inhibitors, SRC inhibitors", False),
("• TKIs NOT effective (no BCR-ABL)", True, C_RED),
]
add_multiline_text(s, tx_lines, 6.75, 1.55, 6.1, 2.2, size=10.5, line_spacing=1)
add_rect(s, 6.6, 4.05, 6.5, 3.05, fill_rgb=C_WHITE, line_rgb=C_RED, line_width=1)
section_pill(s, "Prognosis", 6.7, 4.05, 1.8, color=C_RED)
prog_lines = [
("• Median survival: <3 years", True, C_RED),
("• ~20% risk of AML transformation", True, C_RED),
("• Adverse prognostic factors:", False),
(" ASXL1 frameshift/nonsense mutations", False),
(" Higher blast count (CMML-2)", False),
(" MPN-CMML phenotype (higher WBC)", False),
(" Thrombocytopenia, anemia", False),
("• CMML-specific scoring systems:", False),
(" CPSS, GFM, MDAPS", False),
]
add_multiline_text(s, prog_lines, 6.75, 4.5, 6.1, 2.4, size=10.5, line_spacing=1)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 5 – Atypical CML
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, fill_rgb=C_LIGHT_GREY)
slide_header(s, "Atypical CML (aCML), BCR-ABL1-Negative", bar_color=C_ORANGE)
footer(s)
# Left column – criteria
add_rect(s, 0.25, 1.1, 6.2, 3.8, fill_rgb=C_WHITE, line_rgb=C_ORANGE, line_width=1.5)
section_pill(s, "Diagnostic Criteria", 0.35, 1.1, 2.2, color=C_ORANGE)
crit = [
("• WBC >13×10⁹/L with immature granulocytes", False),
(" (neutrophils, metamyelocytes, myelocytes, promyelocytes)", False, C_MID_GREY),
("• Dysgranulopoiesis (MANDATORY – key feature)", True, C_RED),
("• Bone marrow: myeloid hyperplasia + dysplasia", False),
("• Blasts <20% (≥20% → AML)", False),
("• Monocytes NOT prominent (<10% of WBC differential)", False),
("• Basophilia absent or minimal", False),
("• Philadelphia chromosome ABSENT", True, C_RED),
("• BCR-ABL1 ABSENT (mandatory exclusion by PCR/FISH)", True, C_RED),
]
add_multiline_text(s, crit, 0.4, 1.55, 5.8, 3.2, size=11, line_spacing=1)
# Left column – genetics
add_rect(s, 0.25, 5.05, 6.2, 2.2, fill_rgb=C_WHITE, line_rgb=C_ORANGE, line_width=1)
section_pill(s, "Molecular Genetics", 0.35, 5.05, 2.2, color=C_ORANGE)
gen = [
("SETBP1 mutations: ~25% of cases", False),
("ETNK1 mutations: recurrent, recently identified", False),
("CSF3R mutations: 5–10% (vs 80% in CNL)", False),
("JAK2 mutations: some cases", False),
("No single defining mutation (contrast with CNL)", False, C_MID_GREY),
]
add_multiline_text(s, gen, 0.4, 5.5, 5.8, 1.6, size=11, line_spacing=2)
# Right – vs Classic CML comparison table
add_rect(s, 6.65, 1.1, 6.45, 6.15, fill_rgb=C_WHITE, line_rgb=C_ORANGE, line_width=1)
section_pill(s, "aCML vs Classic BCR-ABL+ CML", 6.75, 1.1, 3.2, color=C_DARK_BLUE)
# Table headers
add_rect(s, 6.65, 1.48, 6.45, 0.4, fill_rgb=C_DARK_BLUE)
for col_x, col_w, text in [(6.7, 2.2, "Feature"), (8.95, 2.0, "Classic CML"), (11.0, 2.0, "Atypical CML")]:
add_text(s, text, col_x, 1.49, col_w, 0.38, size=10, bold=True, color=C_WHITE)
table_rows = [
("BCR-ABL1 / Ph", "Present", "Absent"),
("Dysplasia", "Absent", "Present (hallmark)"),
("Basophilia", "Prominent", "Absent/minimal"),
("WHO category", "MPN", "MDS/MPN"),
("TKI response", "Excellent", "None"),
("Monocytosis", "Absent", "Absent"),
("Median survival", "Long with TKI", "~2–3 years"),
("Key mutation", "BCR-ABL1", "SETBP1, ETNK1"),
]
alt_bg = [C_WHITE, C_LIGHT_BLUE]
for i, (feat, classic, atypical) in enumerate(table_rows):
yy = 1.92 + i * 0.62
bg = alt_bg[i % 2]
add_rect(s, 6.65, yy, 6.45, 0.60, fill_rgb=bg,
line_rgb=RGBColor(0xCC, 0xDD, 0xEE), line_width=0.5)
add_text(s, feat, 6.7, yy+0.03, 2.2, 0.54, size=10, bold=True, color=C_DARK_GREY)
txt_col = C_RED if atypical in ("Absent", "None", "~2–3 years") else C_DARK_GREY
add_text(s, classic, 8.95, yy+0.03, 2.0, 0.54, size=10, color=C_GREEN)
add_text(s, atypical, 11.0, yy+0.03, 2.0, 0.54, size=10, color=txt_col)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 6 – JMML
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, fill_rgb=C_LIGHT_GREY)
slide_header(s, "JMML – Juvenile Myelomonocytic Leukemia", bar_color=C_GREEN)
footer(s)
# Key facts
add_rect(s, 0.25, 1.1, 3.8, 6.1, fill_rgb=C_WHITE, line_rgb=C_GREEN, line_width=1.5)
section_pill(s, "Epidemiology & Clinical", 0.35, 1.1, 2.8, color=C_GREEN)
epi = [
("• EXCLUSIVELY a childhood disease", True, C_RED),
("• Incidence: 1.3/million children <14 yrs", False),
("• Most common age: <3 years", False),
("• Male predominance (2:1)", False),
("", False),
("Clinical features:", True, C_DARK_BLUE),
("• Monocytosis >1×10⁹/L", False),
("• Splenomegaly (often massive)", False),
("• Leukocytosis (WBC 25–30×10⁹/L)", False),
("• Thrombocytopenia + anemia", False),
("• Circulating NRBCs frequent", False),
("• Cutaneous leukemic infiltrates", False),
("• Hypergammaglobulinemia, autoantibodies", False),
("", False),
("Special association:", True, C_DARK_BLUE),
("• Neurofibromatosis type 1 (NF1) – frequent", True, C_ORANGE),
("• Noonan syndrome (PTPN11 – some spontaneous recovery)", False),
("• Elevated HbF in normal karyotype cases", False),
]
add_multiline_text(s, epi, 0.4, 1.55, 3.5, 5.5, size=10.5, line_spacing=1)
# Diagnostic criteria
add_rect(s, 4.3, 1.1, 4.5, 6.1, fill_rgb=C_WHITE, line_rgb=C_GREEN, line_width=1)
section_pill(s, "WHO Diagnostic Criteria", 4.4, 1.1, 2.6, color=C_GREEN)
diag = [
("Clinical & Haematologic (ALL required):", True, C_DARK_BLUE),
("1. PB monocytosis >1×10⁹/L", False),
("2. BCR-ABL1 absent (Ph chromosome absent)", False),
("3. Blasts + promonocytes <20% (PB + BM)", False),
("4. Splenomegaly", False),
("", False),
("PLUS one genetic criterion:", True, C_RED),
("A. Somatic mutation in KRAS, NRAS, or PTPN11", False),
("B. Clinical NF1 diagnosis OR NF1 mutation", False),
("C. CBL mutation + LOH of CBL", False),
("D. Monosomy 7 or other cytogenetic abnormality", False),
(" OR ≥2 of the following if no mutation found:", False, C_MID_GREY),
(" • Elevated HbF for age", False, C_MID_GREY),
(" • Myeloid precursors on PB smear", False, C_MID_GREY),
(" • WBC >10×10⁹/L", False, C_MID_GREY),
(" • Clonal chromosomal abnormality", False, C_MID_GREY),
(" • GM-CSF hypersensitivity in colony assay", False, C_MID_GREY),
]
add_multiline_text(s, diag, 4.45, 1.55, 4.2, 5.5, size=10.5, line_spacing=1)
# Genetics + treatment
add_rect(s, 9.05, 1.1, 4.05, 3.5, fill_rgb=C_WHITE, line_rgb=C_GREEN, line_width=1)
section_pill(s, "RAS/MAPK Pathway Mutations", 9.15, 1.1, 2.8, color=C_GREEN)
gen2 = [
("Mutation Frequency", True, C_DARK_BLUE),
("PTPN11 ~35% (most common)", False),
("NRAS ~20%", False),
("KRAS ~20%", False),
("NF1 ~15%", False),
("CBL ~10%", False),
("", False),
("Karyotype:", True, C_DARK_BLUE),
("• Monosomy 7 in ~25% of cases", False),
("• Normal karyotype → often high HbF", False),
("", False),
("Mutations are mutually exclusive", False, C_MID_GREY),
]
add_multiline_text(s, gen2, 9.15, 1.55, 3.8, 2.9, size=10.5, line_spacing=1)
add_rect(s, 9.05, 4.75, 4.05, 2.5, fill_rgb=C_WHITE, line_rgb=C_RED, line_width=1)
section_pill(s, "Prognosis & Treatment", 9.15, 4.75, 2.5, color=C_RED)
prog2 = [
("• Poor prognosis overall", True, C_RED),
("• Death from organ failure (leukemic infiltrates)", False),
("• Allogeneic BMT: only curative option", True, C_RED),
("• Noonan+PTPN11 cases: may spontaneously recover", False, C_GREEN),
("• ~35% 5-yr survival without BMT", False),
("• Research: MEK inhibitors (RAS pathway)", False),
]
add_multiline_text(s, prog2, 9.15, 5.15, 3.8, 2.0, size=10.5, line_spacing=1)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 7 – MDS/MPN-RS-T and MDS/MPN-U
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, fill_rgb=C_LIGHT_GREY)
slide_header(s, "MDS/MPN-RS-T & MDS/MPN Unclassifiable (MDS/MPN-U)", bar_color=C_PURPLE)
footer(s)
# RS-T
add_rect(s, 0.25, 1.1, 6.2, 6.1, fill_rgb=C_WHITE, line_rgb=C_PURPLE, line_width=1.5)
section_pill(s, "MDS/MPN with Ring Sideroblasts & Thrombocytosis (MDS/MPN-RS-T)", 0.35, 1.1, 5.8, color=C_PURPLE)
rst_lines = [
("Definition:", True, C_DARK_BLUE),
("• Anaemia with dysplastic erythropoiesis", False),
("• Ring sideroblasts ≥15% of erythroid precursors (or ≥5% if SF3B1 mutated)", False),
("• Thrombocytosis (platelets ≥450×10⁹/L)", False),
("• No BCR-ABL1, no PDGFRA/B/FGFR1 rearrangements", False),
("• Blasts <20%", False),
("", False),
("Key Molecular Feature:", True, C_DARK_BLUE),
("• SF3B1 mutation: hallmark (RNA splicing gene)", True, C_PURPLE),
(" → leads to ring sideroblast formation", False, C_MID_GREY),
("• JAK2 V617F may be present (thrombocytosis component)", False),
("• Concurrent SF3B1 + JAK2: strongly suggestive", True, C_PURPLE),
("", False),
("Clinical:", True, C_DARK_BLUE),
("• Elderly patients, similar to MDS-RS + MPN overlap", False),
("• Anaemia + elevated platelet count", False),
("• Relatively better prognosis than other MDS/MPN entities", False),
("", False),
("Treatment:", True, C_DARK_BLUE),
("• EPO ± lenalidomide for anaemia", False),
("• Hydroxyurea/anagrelide for thrombocytosis", False),
("• Allogeneic HSCT for high-risk cases", False),
]
add_multiline_text(s, rst_lines, 0.4, 1.55, 5.8, 5.5, size=10.5, line_spacing=1)
# MDS/MPN-U
add_rect(s, 6.65, 1.1, 6.45, 6.1, fill_rgb=C_WHITE, line_rgb=C_MID_GREY, line_width=1.5)
section_pill(s, "MDS/MPN Unclassifiable (MDS/MPN-U)", 6.75, 1.1, 3.5, color=C_MID_GREY)
u_lines = [
("Definition (diagnosis of exclusion):", True, C_DARK_BLUE),
("• Has features of BOTH MDS and MPN", False),
("• Does NOT meet criteria for CMML, aCML, JMML,", False),
(" MDS/MPN-RS-T, or classic MPN", False),
("• Blasts <20%", False),
("• BCR-ABL1 and Ph chromosome absent", False),
("", False),
("Two Main Scenarios:", True, C_DARK_BLUE),
("1. Provisional MDS/MPN-U with prominent thrombocytosis:", False),
(" – MDS features + platelets ≥450×10⁹/L", False),
(" – No SF3B1 mutation", False),
(" – No ring sideroblasts (or <15%)", False),
("", False),
("2. MDS with JAK2 mutation:", False),
(" – MDS features but JAK2 V617F present", False),
("", False),
("Genetics:", True, C_DARK_BLUE),
("• Heterogeneous – no defining mutation", False),
("• ASXL1, TET2, EZH2, SETBP1 may be found", False),
("• NGS/cytogenetics for clonality evidence", False),
("", False),
("Prognosis:", True, C_DARK_BLUE),
("• Variable, generally poor", False),
("• Median survival ~18–30 months", False),
("• ~15–20% risk of AML transformation", False),
("• HSCT for eligible patients with high-risk disease", False),
]
add_multiline_text(s, u_lines, 6.8, 1.55, 6.1, 5.5, size=10.5, line_spacing=1)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 8 – Master Comparison Table
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, fill_rgb=C_LIGHT_GREY)
slide_header(s, "Master Comparison Table – All MDS/MPN Entities")
footer(s)
# Table
cols_x = [0.2, 2.55, 4.65, 6.75, 8.85, 11.0]
cols_w = [2.3, 2.1, 2.1, 2.1, 2.1, 2.1]
col_heads = ["Feature", "CMML", "aCML", "JMML", "MDS/MPN-RS-T", "MDS/MPN-U"]
col_colors = [C_DARK_BLUE, C_TEAL, C_ORANGE, C_GREEN, C_PURPLE, C_MID_GREY]
# Header row
add_rect(s, 0.2, 1.05, 13.0, 0.5, fill_rgb=C_DARK_BLUE)
for cx, cw, ch, cc in zip(cols_x, cols_w, col_heads, col_colors):
bg = cc if ch != "Feature" else C_DARK_BLUE
if ch != "Feature":
add_rect(s, cx, 1.05, cw, 0.5, fill_rgb=bg)
add_text(s, ch, cx+0.05, 1.06, cw-0.1, 0.48,
size=10, bold=True, color=C_WHITE, align=PP_ALIGN.CENTER,
anchor=MSO_ANCHOR.MIDDLE)
table_data = [
# (row label, cmml, acml, jmml, rs-t, u)
("Age", "65–75 yrs", "65–75 yrs", "<3 yrs", "Elderly", "Variable"),
("Defining PB finding", "Monocytosis\n≥0.5×10⁹/L", "Neutrophilia\n>13×10⁹/L", "Monocytosis\n>1×10⁹/L", "Thrombocytosis\n≥450×10⁹/L", "Mixed"),
("Dysplasia", "YES", "YES (key!)", "YES", "Erythroid", "YES"),
("BCR-ABL1 / Ph", "ABSENT", "ABSENT", "ABSENT", "ABSENT", "ABSENT"),
("Key mutation(s)","TET2, SRSF2\nASXL1, RAS", "SETBP1\nETNK1, CSF3R", "PTPN11\nKRAS, NRAS\nNF1, CBL", "SF3B1\n(± JAK2)", "Heterogeneous\nASXL1, TET2"),
("Monosomy 7", "Occasional", "Occasional", "~25%", "Rare", "Occasional"),
("Blasts", "<20%", "<20%", "<20%", "<20%", "<20%"),
("Prognosis", "<3 yrs", "~2–3 yrs", "Poor", "Better", "18–30 mo"),
("Curative Rx", "Allo-HSCT", "Allo-HSCT", "Allo-BMT", "Allo-HSCT", "Allo-HSCT"),
("TKI response", "NO", "NO", "NO", "NO", "NO"),
]
alt_bg = [C_WHITE, C_LIGHT_BLUE]
row_h = 0.535
for i, row in enumerate(table_data):
yy = 1.58 + i * row_h
bg = alt_bg[i % 2]
add_rect(s, 0.2, yy, 13.0, row_h, fill_rgb=bg,
line_rgb=RGBColor(0xCC, 0xDD, 0xEE), line_width=0.3)
for j, (cx, cw, val) in enumerate(zip(cols_x, cols_w, row)):
is_bold = (j == 0)
txt_col = C_DARK_BLUE if j == 0 else (C_RED if val in ("ABSENT", "NO") else C_DARK_GREY)
add_text(s, val, cx+0.05, yy+0.02, cw-0.1, row_h-0.04,
size=9 if "\n" in val else 10,
bold=is_bold, color=txt_col,
align=PP_ALIGN.CENTER if j > 0 else PP_ALIGN.LEFT,
anchor=MSO_ANCHOR.MIDDLE, wrap=True)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 9 – High-Yield Board Points
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, fill_rgb=C_LIGHT_GREY)
slide_header(s, "High-Yield Board Points & Mnemonics")
footer(s)
# Left column – mnemonics
add_rect(s, 0.25, 1.1, 6.2, 6.1, fill_rgb=C_WHITE, line_rgb=C_GOLD, line_width=2)
section_pill(s, "Mnemonics & Key Rules", 0.35, 1.1, 2.5, color=C_GOLD)
mn_lines = [
("The UNIVERSAL Rule:", True, C_RED),
("All MDS/MPN entities: BCR-ABL1 ABSENT, Ph ABSENT", True, C_RED),
("All MDS/MPN entities: Blasts <20% (≥20% = AML)", True, C_RED),
("All MDS/MPN entities: TKIs do NOT work", True, C_RED),
("", False),
("CMML Memory Aid:", True, C_TEAL),
('"C = Chronic Monocytosis (>1000/μL, >10% of WBC)"', False, C_TEAL),
(" TET2 + SRSF2 co-mutation → think CMML phenotype", False),
("", False),
("aCML Memory Aid:", True, C_ORANGE),
('"aCML = Absent BCR-ABL + Abnormal dysplasia + Awful prognosis"', False, C_ORANGE),
(" Dysgranulopoiesis is the KEY differentiator from CNL", False),
(" SETBP1 is aCML; CSF3R T618I is CNL", False),
("", False),
("JMML Memory Aid:", True, C_GREEN),
('"JMML = Just kids, Mutations in RAS pathway, Marrow transplant needed"', False, C_GREEN),
(" NF1 association is a classic exam question", False),
(" GM-CSF hypersensitivity in colony assay is confirmatory", False),
("", False),
("RS-T Memory Aid:", True, C_PURPLE),
('"Ring Sideroblasts (SF3B1) + Thrombocytosis = RS-T"', False, C_PURPLE),
(" SF3B1 mutation = ring sideroblasts; JAK2 = thrombocytosis", False),
),
]
add_multiline_text(s, mn_lines, 0.4, 1.55, 5.8, 5.5, size=10.5, line_spacing=1)
# Right column – classic exam traps
add_rect(s, 6.65, 1.1, 6.45, 6.1, fill_rgb=C_WHITE, line_rgb=C_RED, line_width=2)
section_pill(s, "Classic Exam Traps", 6.75, 1.1, 2.2, color=C_RED)
traps = [
("Trap 1: BCR-ABL negative CML", True, C_RED),
(" → There is NO such thing. aCML is a distinct entity.", False),
(" Eliminate any option suggesting BCR-ABL-negative CML exists", False, C_MID_GREY),
("", False),
("Trap 2: TKIs in aCML/CMML", True, C_RED),
(" → TKIs do NOT work. No BCR-ABL = no TKI benefit.", False),
("", False),
("Trap 3: CMML vs Reactive Monocytosis", True, C_RED),
(" → Must persist >3 months; must exclude infections,", False),
(" connective tissue disease, etc.", False),
("", False),
("Trap 4: aCML vs CNL", True, C_RED),
(" → aCML has DYSPLASIA + immature forms", False),
(" → CNL has mature neutrophils WITHOUT dysplasia", False),
(" → CSF3R T618I strongly favours CNL", False),
("", False),
("Trap 5: JMML age", True, C_RED),
(" → Exclusively a CHILDHOOD disease (<14 yrs)", False),
(" → Adult with similar picture = CMML", False),
("", False),
("Trap 6: Blasts ≥20%", True, C_RED),
(" → Always reclassify as AML regardless of prior MDS/MPN dx", False),
("", False),
("Trap 7: JMML genetic test", True, C_RED),
(" → In vitro GM-CSF hypersensitivity = CONFIRMATORY test", False),
]
add_multiline_text(s, traps, 6.8, 1.55, 6.1, 5.5, size=10.5, line_spacing=1)
# ════════════════════════════════════════════════════════════════════════════
# SLIDE 10 – Diagnostic Algorithm
# ════════════════════════════════════════════════════════════════════════════
s = prs.slides.add_slide(blank)
add_rect(s, 0, 0, 13.333, 7.5, fill_rgb=C_LIGHT_GREY)
slide_header(s, "Diagnostic Algorithm – Approach to MDS/MPN")
footer(s)
# Step boxes
steps = [
(0.3, 1.15, 12.5, 0.72, C_DARK_BLUE, C_WHITE,
"STEP 1 – Exclude BCR-ABL1 / Ph chromosome by FISH + PCR. If positive → Classic CML (treat with TKI). Stop here."),
(0.3, 2.05, 12.5, 0.72, C_MED_BLUE, C_WHITE,
"STEP 2 – Exclude PDGFRA, PDGFRB, FGFR1, PCM1-JAK2 rearrangements. If positive → specific MPN with eosinophilia."),
(0.3, 2.95, 12.5, 0.72, C_TEAL, C_WHITE,
"STEP 3 – Check age. Patient <14 years? → Consider JMML. Check monocytosis, test PTPN11/KRAS/NRAS/NF1/CBL, GM-CSF sensitivity."),
(0.3, 3.85, 12.5, 0.72, C_GREEN, C_WHITE,
"STEP 4 – Persistent monocytosis ≥0.5×10⁹/L AND ≥10% of WBC (>3 months)? Dysplasia present? Blasts <20%? → CMML"),
(0.3, 4.75, 12.5, 0.72, C_ORANGE, C_WHITE,
"STEP 5 – Neutrophilia >13×10⁹/L with dysgranulopoiesis? No monocytosis, no basophilia? Blasts <20%? → aCML"),
(0.3, 5.65, 12.5, 0.72, C_PURPLE, C_WHITE,
"STEP 6 – Anaemia + ring sideroblasts ≥15% (or ≥5% + SF3B1) + thrombocytosis ≥450×10⁹/L? Blasts <20%? → MDS/MPN-RS-T"),
(0.3, 6.55, 12.5, 0.62, C_MID_GREY, C_WHITE,
"STEP 7 – Has both MDS and MPN features but doesn't fit above? Blasts <20%, BCR-ABL absent? → MDS/MPN-Unclassifiable"),
]
for x, y, w, h, bg, fg, text in steps:
add_rect(s, x, y, w, h, fill_rgb=bg)
add_text(s, text, x+0.15, y+0.02, w-0.3, h-0.04,
size=11, bold=False, color=fg, anchor=MSO_ANCHOR.MIDDLE, wrap=True)
# Save
out_path = "/tmp/workspace/mds-mpn-guide/MDS_MPN_Overlap_Board_Prep.pptx"
buf = BytesIO()
prs.save(buf)
with open(out_path, "wb") as f:
f.write(buf.getvalue())
print(f"Saved: {out_path}")
cd /tmp/workspace/mds-mpn-guide && python build_deck.py 2>&1
~/mds-mpn-guide/build_deck.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/mds-mpn-guide/build_deck.py'
cd /tmp/workspace/mds-mpn-guide && python build_deck.py 2>&1
MDS MPN Overlap Board Prep
Presentation · PPTX
| Slide | Content |
|---|---|
| 1 | Title slide with colour-coded entity pills |
| 2 | Overview - what makes a disorder MDS/MPN + WHO 2022 classification table |
| 3 | CMML (1/2) - full WHO diagnostic criteria, MDS-CMML vs MPN-CMML subtypes, CMML-1 vs CMML-2 blast thresholds, genetics (TET2, SRSF2, ASXL1, RAS), immunophenotype |
| 4 | CMML (2/2) - reactive monocytosis differential, treatment (HMA, hydroxyurea, HSCT), prognosis (<3 yrs, ~20% AML risk) |
| 5 | aCML - diagnostic criteria with dysgranulopoiesis as hallmark, side-by-side aCML vs classic BCR-ABL+ CML table, SETBP1/ETNK1/CSF3R genetics |
| 6 | JMML - childhood-only entity, RAS/MAPK mutation frequency table (PTPN11/NRAS/KRAS/NF1/CBL), full WHO criteria including GM-CSF hypersensitivity, NF1/Noonan associations |
| 7 | MDS/MPN-RS-T + MDS/MPN-U - SF3B1 hallmark, ring sideroblast threshold (≥15% or ≥5% if SF3B1+), thrombocytosis criteria; MDS/MPN-U as diagnosis of exclusion |
| 8 | Master comparison table - all 5 entities side-by-side: age, PB finding, dysplasia, BCR-ABL status, key mutations, prognosis, treatment |
| 9 | High-yield board points - mnemonics (aCML = Absent BCR-ABL + Abnormal dysplasia + Awful prognosis), 7 classic exam traps |
| 10 | Diagnostic algorithm - colour-coded 7-step flowchart from "exclude BCR-ABL" to final classification |