immunomodulatory therapy for non infectious uveitis

Reading File
Finding Sources
Searching PubMed

"noninfectious uveitis" AND "immunomodulatory therapy"

Finding Sources
Reading File
Reading Article

PMID: 41412963

Reading Article

PMID: 41265720

Reading File
Finding Sources
Reading File
Reading File
Finding Sources
I now have a comprehensive set of information from Kanski's Clinical Ophthalmology, Wills Eye Manual, Rheumatology textbooks, and two very recent meta-analyses (2026). Let me compose the full answer.

Immunomodulatory Therapy for Non-Infectious Uveitis

Non-infectious uveitis (NIU) is an immune-mediated, potentially sight-threatening condition. When topical/periocular steroids fail or systemic corticosteroids are needed long-term, immunomodulatory therapy (IMT) is introduced - ideally by a multidisciplinary team including an ocular inflammation specialist. The primary goal is steroid-free remission.

Indications for IMT

Start IMT early (without waiting for steroid failure):
  • Birdshot retinochoroidopathy
  • Serpiginous choroidopathy
  • Multifocal choroiditis and panuveitis
  • JIA-associated uveitis
Start IMT as alternative or adjunct to steroids when:
  • Inadequate response to topical/periocular steroids or oral prednisolone >0.5 mg/kg/day
  • Intolerance to systemic steroids
  • Steroid-sparing is needed
  • Sight-threatening acute disease, chronic/persistent disease, macular involvement, or exudative retinal detachment

Pre-Treatment Checklist

Before starting any IMT agent:
  • Rule out active infections, especially tuberculosis (TB screening mandatory before biologics)
  • Check haematological, renal, and hepatic function
  • Take informed consent (benefits, side effects, monitoring requirements)

Classes of IMT Agents

1. Antimetabolites (First-line non-biologic DMARDs)

These inhibit purine/folate metabolism and suppress lymphocyte proliferation.
DrugTypical DoseNotes
Methotrexate (MTX)10-25 mg/week PO/SC + folateMost widely used; effective for JIA uveitis, intermediate uveitis; monitor LFTs, CBC
Mycophenolate mofetil (MMF)1000-2000 mg/dayOften preferred for posterior/panuveitis; favorable efficacy/safety per recent meta-analysis
Azathioprine1-3 mg/kg/dayCheck TPMT enzyme activity before starting; risk of lymphoma with anti-TNF combination
Recent evidence (2026 meta-analysis, PMID 41412963): Among 16 RCTs covering 11 IMT agents, mycophenolic acid showed a favorable trend in both efficacy and safety. The overall treatment failure rate at 6 months was ~37.6%, underscoring that NIU relapse risk remains significant even on IMT.

2. Calcineurin Inhibitors

Block IL-2-dependent T-cell activation. Particularly useful in T-cell-critical uveitis (e.g., Vogt-Koyanagi-Harada disease, birdshot retinochoroidopathy).
DrugNotes
Cyclosporin A2.5-5 mg/kg/day; monitor BP and creatinine
TacrolimusMore potent than cyclosporin; lower dose needed
Voclosporin / SirolimusNewer agents in this class

3. Alkylating Agents

Reserved for severe, refractory cases.
DrugNotes
Cyclophosphamide1-5 mg/kg/day; used in severe systemic vasculitis with uveitis (e.g., Behçet, ANCA+ scleritis)
ChlorambucilRarely used now; historically for Behçet disease

4. Biologics (Biopharmacologicals)

A rapidly evolving field. These agents take 2 weeks to 3 months to achieve full effect - bridging steroids are usually needed initially.

Anti-TNF-α Agents

The most extensively used biologics in NIU:
DrugRouteApproved for NIU
AdalimumabSC 40 mg every 2 weeksYes - FDA approved for NIU
InfliximabIV 5 mg/kg at 0, 2, 6 weeks, then every 8 weeksYes
EtanerceptSCLess effective for uveitis; NOT recommended for isolated uveitis
GolimumabSCYes
Certolizumab pegolSC 200 mg q2 weeks or 400 mg monthlyYes
Key trial evidence: The VISUAL I and VISUAL II trials established adalimumab as the first FDA-approved biologic specifically for NIU. The 2026 meta-analysis (Wang et al., PMID 41412963) confirmed: adalimumab + corticosteroids significantly reduced hazard of treatment failure (HR 0.51, 95% CrI 0.24-0.95) vs corticosteroids alone.
Biosimilar switching (PMID 41265720): A 2026 systematic review found switching from originator adalimumab/infliximab to biosimilars was not associated with increased flare rates (IRR 1.20, 95% CI 0.79-1.83), supporting clinical equivalence - though ~10% reverted due to tolerability issues.

Anti-IL-6 (Tocilizumab)

  • Binds IL-6 receptors, inhibiting pro-inflammatory cytokines
  • Useful for refractory cases, particularly JIA-uveitis and macular edema from uveitis
  • Given IV or SC

Anti-CD20 (Rituximab)

  • Depletes B cells
  • Particularly indicated for B-cell-critical inflammation: scleritis (especially ANCA+), and refractory uveitis associated with systemic vasculitis
  • IV infusion protocol

Other biologics under use/investigation

  • Abatacept (CTLA4-Ig, anti-CD80/86) - used in JIA uveitis refractory to TNF inhibitors
  • Secukinumab / Ixekizumab (anti-IL-17) - used where spondyloarthropathy is the underlying cause, though may worsen IBD-associated uveitis
  • Ustekinumab (anti-IL-12/23)
  • Daclizumab (anti-IL-2R) - studied but now withdrawn

Pathology-Guided Biologic Selection (Kanski's Framework)

This approach aligns biologic choice with the predominant immune pathway:
Dominant Immune Cell TypeDisease ExamplesPreferred Biologic Class
T-cell criticalVKH, birdshot retinochoroidopathyCalcineurin inhibitors + anti-TNF
Neutrophil/macrophage criticalBehçet disease, sarcoidosisAnti-TNF agents (infliximab preferred for Behçet)
B-cell criticalANCA+ scleritis, refractory granulomatousRituximab

Drug Monitoring Summary

DrugKey Monitoring
MethotrexateLFTs, CBC, renal function; avoid alcohol; folate supplementation
AzathioprineCBC, LFTs; TPMT genotyping before start
Mycophenolate mofetilCBC, renal function
Cyclosporin ABP, creatinine, drug levels
Anti-TNF agentsTB screening, CBC, LFTs; screen for HBV reactivation; contraindicated in NYHA III/IV heart failure, demyelinating disease, optic neuropathy
RituximabInfusion reactions; hepatitis B reactivation; PML risk

Safety Considerations

  • Antimetabolites (MTX, MMF, azathioprine) and calcineurin inhibitors do not significantly increase cancer mortality at standard doses
  • Azathioprine monotherapy or anti-TNF monotherapy: small but statistically significant lymphoma risk
  • Combination azathioprine + anti-TNF: higher lymphoma risk
  • All agents carry risk of opportunistic infections; common side effects include headache, fatigue, GI upset, and bone marrow suppression

Step-Up Approach Summary

Topical steroids + cycloplegics
        ↓ (if inadequate or posterior disease)
Systemic corticosteroids
        ↓ (if steroid-sparing needed, or refractory)
Antimetabolite (MTX or MMF as first choice)
+/- Calcineurin inhibitor (for T-cell dominant disease)
        ↓ (if refractory to non-biologic DMARD)
Biologic: Adalimumab or Infliximab (anti-TNF first-line)
        ↓ (if TNF-inhibitor refractory)
Tocilizumab / Rituximab / Abatacept (depending on disease type)

Sources:

do you know about sketchy medical ?

Yes! Sketchy Medical is a popular visual learning platform used by medical students worldwide. Here's what it's about:
What it is: Sketchy Medical uses memorable, story-based illustrations (called "sketches") to teach complex medical content through visual association and narrative mnemonics. The idea is that your brain retains stories and images far better than raw facts.
Main modules:
  • Sketchy Micro - Microbiology (bacteria, viruses, fungi, parasites) - the original and most iconic module
  • Sketchy Pharm - Pharmacology (drug mechanisms, side effects, mnemonics)
  • Sketchy Path - Pathology
  • Sketchy Immuno - Immunology (newer addition)
How it works: Each video features a detailed illustrated "scene" - for example, a Wild West saloon for Staph aureus - where every character, object, and action represents a fact (virulence factor, drug of choice, side effect, etc.). As you watch, you build a mental map of the entire organism or drug.
Who uses it: Primarily USMLE Step 1 and Step 2 CK candidates, though it's used broadly in preclinical years and by international medical graduates (IMGs) studying for licensing exams.
Pros:
  • Excellent retention for visual learners
  • Great for high-yield microbiology and pharmacology
  • Pairs well with First Aid and Anki (many Sketchy-based Anki decks exist)
Limitations:
  • Doesn't replace deep conceptual understanding for clinical reasoning
  • Subscription-based (can be pricey)
  • Works better for some people than others - purely auditory/text learners may not benefit as much
Is there something specific about Sketchy you wanted to know, or are you looking for study tips on how to use it effectively?

can you make similar images for few topics for me

Asking for Preferences

ries buvckler and thiel benke corneal dystrophies

Finding Sources
Finding Sources
Reading File
Reading File
Generating Image

Sketchy Medical style mnemonic illustration for Reis-Bucklers Corneal Dystrophy. A detailed cartoon scene: A GEOGRAPHY CLASSROOM with a MAP on the wall showing grey-white geographic landmass shapes (representing grey-white geographic subepithelial opacities). The teacher is a BUCKET (Reis-BUCKLERS = bucket) wearing a graduation cap. A CHILD student (onset in childhood) is crying in pain holding their eye (recurrent corneal erosions). A BULLDOZER is destroying a FLOOR (Bowman layer replaced by connective tissue). The WINDOW is frosted with a net/reticular pattern that gets thicker from center outward (increasing density centrally, reticular pattern with age). A LASER GUN is on the desk as treatment tool (Excimer laser PTK). There is a DNA strand labeled "TGFB1" and "AD" (autosomal dominant, TGFB1 gene). Label key objects with their mnemonics. Vibrant colors, rich detail, educational cartoon style like Sketchy Medical.

Generating Image

Sketchy Medical style mnemonic illustration for Thiel-Behnke Corneal Dystrophy. A detailed cartoon scene: A BEEHIVE scene (Thiel-BEHNKE sounds like "Bee-nk" and it is called HONEYCOMB dystrophy). Giant honeycomb hexagonal patterns are visible on a WINDOW (central cornea). A CHILD holding their eye (recurrent erosions in childhood). The FLOOR/GROUND has CURLY WORMS on it (Bowman layer curly fibres on electron microscopy). The opacities are shown as tiny rings arranged in a honeycomb network pattern - less individually defined than bricks (less severe than Reis-Bucklers). A DNA strand labeled "TGFB1" and "AD" (autosomal dominant). A BEE CHARACTER labeled "CBD2" (corneal basement dystrophy type 2). A sign says "Milder than next door" with an arrow pointing offscreen (less severe than Reis-Bucklers). Treatment area shows a small X (treatment not always necessary). Vibrant colors, rich detail, educational cartoon style like Sketchy Medical.

!

400, message: Got more than 4194304 bytes when reading: b'data: {"candidates": [{"content": {"role": "model","parts": [{"inlineData": {"mimeType": "image/png"...'.

We encountered an error while processing your request. Please try again or reach out to us for help.

?

Generating Image

Sketchy Medical style mnemonic illustration for Reis-Bucklers Corneal Dystrophy. A cartoon classroom scene: A BUCKET wearing a graduation cap stands at the front (Reis-BUCKLERS = bucket). A MAP on the wall shows grey-white geographic landmass shapes (geographic subepithelial opacities). A CHILD student crying holding their eye (recurrent erosions in childhood). A BULLDOZER destroying the FLOOR (Bowman layer replaced by connective tissue). A frosted window with reticular net pattern denser in the center (central opacities, reticular with age). A LASER on the desk (Excimer laser PTK treatment). DNA helix labeled TGFB1 and AD. Vibrant Sketchy Medical cartoon style with labeled mnemonics.

!

400, message: Got more than 4194304 bytes when reading: b'data: {"candidates": [{"content": {"role": "model","parts": [{"inlineData": {"mimeType": "image/png"...'.

We encountered an error while processing your request. Please try again or reach out to us for help.

try again

Generating Image

Sketchy Medical mnemonic scene for Reis-Bucklers corneal dystrophy. A cartoon bucket character destroying a floor with a bulldozer, a geographic map on the wall, a crying child, a laser gun, and a DNA strand labeled TGFB1. Simple colorful educational illustration.

!

400, message: Got more than 4194304 bytes when reading: b'data: {"candidates": [{"content": {"role": "model","parts": [{"inlineData": {"mimeType": "image/png"...'.

We encountered an error while processing your request. Please try again or reach out to us for help.

?

It seems the image generation tool is repeatedly hitting a size limit error on my end - it's a backend issue, not something you're doing wrong.
In the meantime, let me give you the full Sketchy-style mnemonic scenes in text form so you have the complete story, and we can try the images again later.

🪣 Reis-Bücklers — "The Bucket's Geography Class"

Scene: A classroom where a BUCKET (Bücklers) is the teacher.
Object/CharacterWhat it represents
🪣 Bucket teacherReis-Bücklers
🗺️ Grey geographic MAP on the wallGrey-white geographic subepithelial opacities
🧒 Crying child studentOnset in childhood, recurrent painful erosions
🏗️ Bulldozer destroying the FLOORBowman layer replaced by connective tissue
🕸️ Reticular net on window (dense at center)Opacities become reticular, denser centrally
🔫 Laser gun on the deskTreatment: Excimer laser PTK
🧬 DNA helix labeled "TGFB1 / AD"Autosomal dominant, TGFB1 gene
👁️ Numb eye on posterReduced corneal sensation
Tag: "CBD1"Corneal Basement Dystrophy type 1

🐝 Thiel-Behnke — "The Beehive Next Door"

Scene: Right next door to the geography class is a BEEHIVE (Behnke = Bee-nk).
Object/CharacterWhat it represents
🍯 Honeycomb everywhereCalled honeycomb-shaped corneal dystrophy
🐝 Smaller, calmer beesLess severe than Reis-Bücklers
🧒 Child with mild eye rubRecurrent erosions in childhood (milder)
🐛 Curly worms on the floorCurly fibres on electron microscopy (Bowman layer)
🪟 Honeycomb window (tiny rings, central)Subepithelial opacities in network of tiny rings, central cornea
🚫 No treatment signTreatment not always necessary
🧬 DNA labeled "TGFB1 / AD"Autosomal dominant, TGFB1 gene
Tag: "CBD2"Corneal Basement Dystrophy type 2

Quick Comparison Cheat Sheet

FeatureReis-BücklersThiel-Behnke
NicknameCBD1CBD2 (Honeycomb)
GeneTGFB1TGFB1 (+others)
InheritanceADAD
HistologyConnective tissue replacing BowmanCurly fibres (EM)
OpacitiesGeographic, reticularHoneycomb rings
SeverityMore severeLess severe
ErosionsSevere, childhoodMild, childhood
TreatmentExcimer PTK / keratectomyOften not needed
Both are Bowman layer dystrophies sharing the TGFB1 gene - the key difference is the pattern (geographic vs honeycomb) and severity.
attachment
attachment

heres all the info you can use in generation of image

Generating Image

Sketchy Medical style mnemonic cartoon for Reis-Bucklers Corneal Dystrophy (RBCD). Single illustrated scene: A cartoon BUCKET character (Bucklers) as a child student (childhood onset) standing in front of a GEOGRAPHIC MAP with grey irregular landmass shapes on it (geographic opacification on slit lamp). The bucket is crying and holding its eye in pain (painful, affects vision). On the floor are ROD-SHAPED objects like rods/sticks (rod-shaped fibers on electron microscopy). The Bowman membrane shown as a SHEET of paper being torn (sheets appearance on light microscopy). A paint jar labeled MASSON TRICHROME with red color (stains red with Masson trichrome). A DNA double helix labeled TGFBI BIGH3 in the corner. Bold fun cartoon style, colorful, educational, labeled objects, Sketchy Medical aesthetic.

!

400, message: Got more than 4194304 bytes when reading: b'data: {"candidates": [{"content": {"role": "model","parts": [{"inlineData": {"mimeType": "image/png"...'.

We encountered an error while processing your request. Please try again or reach out to us for help.

?

There seems to be a persistent backend error with the image generation tool right now - it's generating the image successfully but the response is too large to deliver back to you. This is a technical issue on the platform side, not with your request.
Here's what I suggest:
Option 1 - Try later: The image tool may recover. We can retry in a new session.
Option 2 - I build it as a downloadable file: I can create the Sketchy-style mnemonic as a PNG or PDF directly in the sandbox using Python (with all the visual elements, labeled diagrams, colors, characters) and give you a download link. This would work reliably right now.
Option 3 - Text mnemonic: You already have the full story-based mnemonic I wrote earlier, which you can visualize yourself or use with any drawing tool.

Would you like me to go ahead with Option 2 - generate a proper illustrated mnemonic image file using Python and give you a download link? I can make it colorful and organized with all the facts from your screenshot.

Generate the images as downloadable PNG files using Python

Running Command

mkdir -p /tmp/workspace/corneal-dystrophies && python3 -c "from PIL import Image; print('Pillow OK')"

Writing File

~/corneal-dystrophies/rbcd.py

from PIL import Image, ImageDraw, ImageFont
import math, os

W, H = 1400, 900
img = Image.new("RGB", (W, H), "#FFFDF0")
draw = ImageDraw.Draw(img)

# ── font helpers ──────────────────────────────────────────────────────────────
def font(size, bold=False):
    candidates = [
        "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf" if bold else
        "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
        "/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf" if bold else
        "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf",
    ]
    for p in candidates:
        if os.path.exists(p):
            return ImageFont.truetype(p, size)
    return ImageFont.load_default()

def txt(draw, text, xy, size=18, color="#222", bold=False, anchor="la"):
    draw.text(xy, text, font=font(size, bold), fill=color, anchor=anchor)

# ── BACKGROUND SECTIONS ───────────────────────────────────────────────────────
# Sky blue top strip
draw.rectangle([0, 0, W, 80], fill="#D0EEFF")
# Warm ground strip
draw.rectangle([0, H-120, W, H], fill="#C8E6C9")

# ── TITLE BANNER ──────────────────────────────────────────────────────────────
draw.rounded_rectangle([30, 10, 780, 70], radius=18, fill="#B71C1C")
txt(draw, "REIS-BÜCKLERS Corneal Dystrophy  (RBCD)", (50, 38), size=26, color="white", bold=True)

# ── GENE BADGE ────────────────────────────────────────────────────────────────
draw.rounded_rectangle([820, 15, 1050, 65], radius=14, fill="#1565C0")
txt(draw, "Gene: TGFBI (BIGH3)", (835, 38), size=20, color="white", bold=True)
draw.rounded_rectangle([1070, 15, 1250, 65], radius=14, fill="#6A1B9A")
txt(draw, "Inheritance: AD", (1085, 38), size=20, color="white", bold=True)

# ══════════════════════════════════════════════════════════════════════════════
# 1. BUCKET CHARACTER  (left)
# ══════════════════════════════════════════════════════════════════════════════
bx, by = 110, 200   # bucket center-top

# bucket body (trapezoid)
draw.polygon([(bx-55, by+40),(bx+55, by+40),(bx+45, by+130),(bx-45, by+130)],
             fill="#FFD600", outline="#222", width=3)
# bucket rim
draw.rectangle([bx-58, by+35, bx+58, by+50], fill="#FFC107", outline="#222", width=2)
# bucket handle
draw.arc([bx-40, by-10, bx+40, by+40], start=0, end=180, fill="#222", width=4)
# face
draw.ellipse([bx-30, by+55, bx+30, by+100], fill="#FFE082", outline="#222", width=2)
# crying eyes
draw.ellipse([bx-18, by+65, bx-8, by+75], fill="white", outline="#222", width=1)
draw.ellipse([bx+8,  by+65, bx+18, by+75], fill="white", outline="#222", width=1)
draw.ellipse([bx-15, by+68, bx-10, by+73], fill="#1565C0")  # pupils
draw.ellipse([bx+10, by+68, bx+15, by+73], fill="#1565C0")
# tears
draw.line([bx-13, by+75, bx-16, by+88], fill="#64B5F6", width=3)
draw.line([bx+13, by+75, bx+16, by+88], fill="#64B5F6", width=3)
# mouth (frown)
draw.arc([bx-12, by+82, bx+12, by+98], start=200, end=340, fill="#222", width=3)
# arms
draw.line([bx-55, by+70, bx-90, by+100], fill="#FFD600", width=8)
draw.line([bx+55, by+70, bx+90, by+100], fill="#FFD600", width=8)
# label
txt(draw, "🪣 BUCKET = Bücklers", (bx-60, by+145), size=16, color="#B71C1C", bold=True)
txt(draw, "Childhood onset", (bx-50, by+168), size=15, color="#333")

# ══════════════════════════════════════════════════════════════════════════════
# 2. GEOGRAPHIC MAP  (center-left)
# ══════════════════════════════════════════════════════════════════════════════
mx, my = 330, 130
draw.rounded_rectangle([mx, my, mx+220, my+200], radius=8, fill="#E3F2FD", outline="#1565C0", width=3)
txt(draw, "🗺 GEOGRAPHIC MAP", (mx+10, my+8), size=15, color="#1565C0", bold=True)
# landmass blobs (grey-white geographic opacities)
for ox, oy, ow, oh in [(mx+25,my+45,90,55),(mx+100,my+60,70,40),(mx+50,my+100,80,45),(mx+130,my+110,60,35)]:
    draw.ellipse([ox,oy,ox+ow,oy+oh], fill="#B0BEC5", outline="#78909C", width=2)
txt(draw, "Grey-white Geographic", (mx+10, my+158), size=14, color="#333")
txt(draw, "Subepithelial Opacities", (mx+10, my+175), size=14, color="#333")
txt(draw, "(Dense centrally)", (mx+30, my+192), size=13, color="#555", bold=False)

# ══════════════════════════════════════════════════════════════════════════════
# 3. BOWMAN LAYER — SHEETS  (center)
# ══════════════════════════════════════════════════════════════════════════════
sx, sy = 600, 120
draw.rounded_rectangle([sx, sy, sx+230, sy+210], radius=8, fill="#FFF8E1", outline="#F57F17", width=3)
txt(draw, "📄 SHEETS (LM)", (sx+10, sy+8), size=15, color="#F57F17", bold=True)
# sheet stack
for i in range(4):
    draw.rectangle([sx+20+i*6, sy+45+i*6, sx+200+i*2, sy+80+i*6],
                   fill="white", outline="#BDBDBD", width=2)
txt(draw, "Bowman layer replaced", (sx+12, sy+120), size=14, color="#333")
txt(draw, "by connective tissue", (sx+12, sy+137), size=14, color="#333")
txt(draw, "→ 'Sheets' on LM", (sx+20, sy+158), size=14, color="#E65100", bold=True)

# ══════════════════════════════════════════════════════════════════════════════
# 4. ROD-SHAPED FIBRES  (EM)
# ══════════════════════════════════════════════════════════════════════════════
rx, ry = 880, 120
draw.rounded_rectangle([rx, ry, rx+220, ry+210], radius=8, fill="#F3E5F5", outline="#6A1B9A", width=3)
txt(draw, "🔬 ROD FIBRES (EM)", (rx+10, ry+8), size=15, color="#6A1B9A", bold=True)
for i, (rox, roy, angle) in enumerate([
    (rx+30, ry+60, 15),(rx+70, ry+50, -10),(rx+110, ry+65, 20),
    (rx+50, ry+100, 5),(rx+90, ry+110, -15),(rx+130, ry+95, 10),
    (rx+40, ry+140, 8),(rx+100, ry+145, -12),(rx+150, ry+130, 18),
]):
    # draw rod as thick rounded rectangle rotated-ish via polygon
    rad = math.radians(angle)
    cx, cy, rl = rox+15, roy+6, 28
    pts = []
    for dx, dy in [(-rl,-4),(rl,-4),(rl,4),(-rl,4)]:
        pts.append((cx + dx*math.cos(rad)-dy*math.sin(rad),
                    cy + dx*math.sin(rad)+dy*math.cos(rad)))
    draw.polygon(pts, fill="#CE93D8", outline="#6A1B9A", width=1)
txt(draw, "Rod-shaped fibres", (rx+20, ry+170), size=14, color="#333")
txt(draw, "on Electron Microscopy", (rx+10, ry+187), size=13, color="#333")

# ══════════════════════════════════════════════════════════════════════════════
# 5. MASSON TRICHROME STAIN  (bottom center)
# ══════════════════════════════════════════════════════════════════════════════
stx, sty = 600, 380
draw.rounded_rectangle([stx, sty, stx+230, sty+160], radius=8, fill="#FFEBEE", outline="#B71C1C", width=3)
txt(draw, "🧪 MASSON TRICHROME", (stx+10, sty+10), size=15, color="#B71C1C", bold=True)
# paint jar
draw.ellipse([stx+70, sty+45, stx+160, sty+130], fill="#EF9A9A", outline="#B71C1C", width=3)
draw.rectangle([stx+85, sty+30, stx+145, sty+55], fill="#FFCDD2", outline="#B71C1C", width=2)
txt(draw, "RED", (stx+100, sty+78), size=22, color="#B71C1C", bold=True)
txt(draw, "Stains Red", (stx+75, sty+138), size=15, color="#B71C1C", bold=True)

# ══════════════════════════════════════════════════════════════════════════════
# 6. PAINFUL EYE + VISION LOSS  (bottom left)
# ══════════════════════════════════════════════════════════════════════════════
ex, ey = 50, 450
draw.rounded_rectangle([ex, ey, ex+200, ey+160], radius=8, fill="#FCE4EC", outline="#880E4F", width=3)
txt(draw, "👁 SYMPTOMS", (ex+10, ey+10), size=15, color="#880E4F", bold=True)
# eye shape
draw.arc([ex+30, ey+50, ex+170, ey+120], start=200, end=340, fill="#222", width=4)
draw.arc([ex+30, ey+50, ex+170, ey+120], start=20, end=160, fill="#222", width=4)
draw.ellipse([ex+85, ey+68, ex+115, ey+102], fill="#1565C0")
draw.ellipse([ex+90, ey+73, ex+110, ey+97], fill="#111")
# lightning bolts for pain
for lx, ly in [(ex+25, ey+55),(ex+160, ey+55)]:
    draw.polygon([(lx,ly),(lx+8,ly+12),(lx+4,ly+12),(lx+10,ly+26),(lx+2,ly+14),(lx+6,ly+14)],
                 fill="#FFD600", outline="#F57F17", width=1)
txt(draw, "Painful ✓  Vision loss ✓", (ex+10, ey+128), size=14, color="#880E4F", bold=True)
txt(draw, "Recurrent erosions", (ex+20, ey+148), size=13, color="#555")

# ══════════════════════════════════════════════════════════════════════════════
# 7. RETICULAR PATTERN  (bottom right)
# ══════════════════════════════════════════════════════════════════════════════
netx, nety = 880, 380
draw.rounded_rectangle([netx, nety, netx+220, nety+160], radius=8, fill="#E8F5E9", outline="#1B5E20", width=3)
txt(draw, "🕸 RETICULAR (with age)", (netx+8, nety+10), size=14, color="#1B5E20", bold=True)
# draw net/grid denser in center
for gx in range(netx+20, netx+210, 20):
    draw.line([gx, nety+35, gx, nety+140], fill="#81C784", width=1)
for gy in range(nety+35, nety+145, 18):
    draw.line([netx+20, gy, netx+210, gy], fill="#81C784", width=1)
# central denser blob
draw.ellipse([netx+75, nety+60, netx+150, nety+115], fill="#A5D6A7", outline="#388E3C", width=2)
txt(draw, "Dense centrally", (netx+45, nety+128), size=14, color="#1B5E20")
txt(draw, "→ Reticular pattern", (netx+30, nety+145), size=14, color="#1B5E20")

# ══════════════════════════════════════════════════════════════════════════════
# 8. TREATMENT BOX
# ══════════════════════════════════════════════════════════════════════════════
tx, ty = 330, 370
draw.rounded_rectangle([tx, ty, tx+220, ty+160], radius=8, fill="#E1F5FE", outline="#01579B", width=3)
txt(draw, "💊 TREATMENT", (tx+10, ty+10), size=15, color="#01579B", bold=True)
# laser shape
draw.rectangle([tx+80, ty+45, tx+140, ty+70], fill="#FF6F00", outline="#E65100", width=2)
draw.polygon([(tx+140,ty+52),(tx+180,ty+57),(tx+140,ty+62)], fill="#FFEB3B", outline="#F57F17")
draw.line([tx+180, ty+57, tx+210, ty+45], fill="#FFEB3B", width=3)
txt(draw, "Excimer Laser PTK", (tx+18, ty+100), size=14, color="#01579B", bold=True)
txt(draw, "Superficial keratectomy", (tx+10, ty+120), size=13, color="#333")
txt(draw, "Corneal graft (severe)", (tx+10, ty+138), size=13, color="#333")

# ══════════════════════════════════════════════════════════════════════════════
# CONNECTING ARROWS (simple lines)
# ══════════════════════════════════════════════════════════════════════════════
# bucket → map
draw.line([bx+70, by+80, mx, my+100], fill="#9E9E9E", width=2)
# bucket → eye
draw.line([bx, by+200, ex+100, ey], fill="#9E9E9E", width=2)

# ══════════════════════════════════════════════════════════════════════════════
# BOTTOM LEGEND BAR
# ══════════════════════════════════════════════════════════════════════════════
draw.rectangle([0, H-50, W, H], fill="#B71C1C")
items = [
    ("RBCD = CBD type 1", 30),
    ("Bowman layer dystrophy", 230),
    ("TGFBI gene (AD)", 460),
    ("LM: Sheets", 640),
    ("EM: Rod-shaped fibres", 800),
    ("Stain: Masson Trichrome → RED", 1020),
]
for label, lx in items:
    txt(draw, label, (lx, H-30), size=15, color="white", bold=True)

# ══════════════════════════════════════════════════════════════════════════════
out = "/tmp/workspace/corneal-dystrophies/RBCD_mnemonic.png"
img.save(out, "PNG")
print(f"Saved: {out}  size={os.path.getsize(out)//1024}KB")
Running Command

python3 /tmp/workspace/corneal-dystrophies/rbcd.py

Writing File

~/corneal-dystrophies/tbcd.py

from PIL import Image, ImageDraw, ImageFont
import math, os

W, H = 1400, 900
img = Image.new("RGB", (W, H), "#F1FFF4")
draw = ImageDraw.Draw(img)

def font(size, bold=False):
    candidates = [
        "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf" if bold else
        "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
        "/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf" if bold else
        "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf",
    ]
    for p in candidates:
        if os.path.exists(p):
            return ImageFont.truetype(p, size)
    return ImageFont.load_default()

def txt(draw, text, xy, size=18, color="#222", bold=False, anchor="la"):
    draw.text(xy, text, font=font(size, bold), fill=color, anchor=anchor)

# Background
draw.rectangle([0, 0, W, 80], fill="#DCEDC8")
draw.rectangle([0, H-120, W, H], fill="#F9FBE7")

# ── TITLE ─────────────────────────────────────────────────────────────────────
draw.rounded_rectangle([30, 10, 800, 70], radius=18, fill="#2E7D32")
txt(draw, "THIEL-BEHNKE Corneal Dystrophy  (TBCD)", (50, 38), size=26, color="white", bold=True)

draw.rounded_rectangle([830, 15, 1060, 65], radius=14, fill="#1565C0")
txt(draw, "Gene: TGFBI (BIGH3)", (845, 38), size=20, color="white", bold=True)
draw.rounded_rectangle([1080, 15, 1270, 65], radius=14, fill="#6A1B9A")
txt(draw, "Inheritance: AD", (1095, 38), size=20, color="white", bold=True)

# ══════════════════════════════════════════════════════════════════════════════
# 1. BEE CHARACTER  (Behnke = Bee-nke)
# ══════════════════════════════════════════════════════════════════════════════
bx, by = 110, 200

# bee body (oval)
draw.ellipse([bx-45, by+30, bx+45, by+130], fill="#FFD600", outline="#222", width=3)
# bee stripes
for sy2 in [by+55, by+75, by+95, by+115]:
    draw.rectangle([bx-45, sy2, bx+45, sy2+10], fill="#222")
# bee head
draw.ellipse([bx-25, by, bx+25, by+45], fill="#FFD600", outline="#222", width=3)
# antennae
draw.line([bx-10, by, bx-25, by-25], fill="#222", width=3)
draw.ellipse([bx-30, by-32, bx-18, by-20], fill="#FF8F00")
draw.line([bx+10, by, bx+25, by-25], fill="#222", width=3)
draw.ellipse([bx+18, by-32, bx+30, by-20], fill="#FF8F00")
# eyes (calmer - no tears)
draw.ellipse([bx-16, by+8, bx-6, by+18], fill="white", outline="#222", width=1)
draw.ellipse([bx+6,  by+8, bx+16, by+18], fill="white", outline="#222", width=1)
draw.ellipse([bx-13, by+11, bx-8, by+16], fill="#333")
draw.ellipse([bx+8,  by+11, bx+13, by+16], fill="#333")
# smile (milder)
draw.arc([bx-12, by+22, bx+12, by+36], start=20, end=160, fill="#222", width=3)
# wings
draw.ellipse([bx-80, by+20, bx-20, by+80], fill="#B3E5FC", outline="#29B6F6", width=2)
draw.ellipse([bx+20, by+20, bx+80, by+80], fill="#B3E5FC", outline="#29B6F6", width=2)
# label
txt(draw, "🐝 BEE = Behnke", (bx-55, by+148), size=16, color="#2E7D32", bold=True)
txt(draw, "Childhood onset", (bx-48, by+168), size=15, color="#333")
txt(draw, "(milder than RBCD)", (bx-55, by+186), size=14, color="#555")

# ══════════════════════════════════════════════════════════════════════════════
# 2. HONEYCOMB PATTERN  (slit lamp appearance)
# ══════════════════════════════════════════════════════════════════════════════
hx, hy = 300, 120
draw.rounded_rectangle([hx, hy, hx+240, hy+220], radius=8, fill="#FFFDE7", outline="#F9A825", width=3)
txt(draw, "🍯 HONEYCOMB (SL)", (hx+10, hy+8), size=15, color="#F9A825", bold=True)

# draw hexagonal honeycomb grid
def hex_pts(cx, cy, r):
    return [(cx + r*math.cos(math.radians(60*i-30)),
             cy + r*math.sin(math.radians(60*i-30))) for i in range(6)]

hex_r = 22
cols = [(hx+60, hx+105, hx+150, hx+195)]
hex_centers = []
for row in range(4):
    offset = 0 if row % 2 == 0 else hex_r * math.cos(math.radians(30))
    for col in range(3):
        cx = hx + 55 + col * int(hex_r * 1.73) + int(offset)
        cy = hy + 50 + row * int(hex_r * 1.5)
        if hy+40 < cy < hy+190:
            draw.polygon(hex_pts(cx, cy, hex_r), fill="#FFF9C4", outline="#F9A825", width=2)

txt(draw, "'Honeycomb' opacification", (hx+8, hy+178), size=13, color="#555")
txt(draw, "Tiny rings, network pattern", (hx+8, hy+195), size=13, color="#555")
txt(draw, "Central cornea", (hx+40, hy+210), size=13, color="#F9A825", bold=True)

# ══════════════════════════════════════════════════════════════════════════════
# 3. SAW-TOOTHED BOWMAN LAYER  (Light Microscopy)
# ══════════════════════════════════════════════════════════════════════════════
sx, sy = 590, 120
draw.rounded_rectangle([sx, sy, sx+230, sy+220], radius=8, fill="#FFF3E0", outline="#E65100", width=3)
txt(draw, "🔬 SAW-TOOTHED (LM)", (sx+8, sy+8), size=14, color="#E65100", bold=True)

# Draw a saw-tooth line
saw_pts = []
start_x = sx + 20
end_x = sx + 210
y_base = sy + 110
tooth_w = 25
tooth_h = 30
x = start_x
while x < end_x:
    saw_pts.extend([(x, y_base), (x + tooth_w//2, y_base - tooth_h), (x + tooth_w, y_base)])
    x += tooth_w
draw.line(saw_pts, fill="#E65100", width=4)

# Bowman layer label lines
draw.rectangle([sx+20, sy+45, sx+210, sy+60], fill="#FFCC80", outline="#E65100", width=1)
txt(draw, "Bowman layer", (sx+55, sy+48), size=12, color="#333")
draw.rectangle([sx+20, sy+130, sx+210, sy+145], fill="#FFCC80", outline="#E65100", width=1)
txt(draw, "Stroma", (sx+90, sy+133), size=12, color="#333")

txt(draw, "Saw-toothed pattern", (sx+28, sy+165), size=14, color="#E65100", bold=True)
txt(draw, "on Light Microscopy", (sx+32, sy+183), size=13, color="#333")

# ══════════════════════════════════════════════════════════════════════════════
# 4. CURLY FIBRES (Electron Microscopy)
# ══════════════════════════════════════════════════════════════════════════════
cx2, cy2 = 875, 120
draw.rounded_rectangle([cx2, cy2, cx2+230, cy2+220], radius=8, fill="#F3E5F5", outline="#6A1B9A", width=3)
txt(draw, "🔬 CURLY FIBRES (EM)", (cx2+10, cy2+8), size=14, color="#6A1B9A", bold=True)

# draw curly worm-like fibres
import random
random.seed(42)
for i in range(8):
    start_x2 = cx2 + 20 + random.randint(0, 160)
    start_y2 = cy2 + 45 + random.randint(0, 130)
    pts = [(start_x2, start_y2)]
    angle2 = random.uniform(0, math.pi*2)
    for step in range(12):
        angle2 += random.uniform(-0.8, 0.8)
        pts.append((pts[-1][0] + math.cos(angle2)*8,
                    pts[-1][1] + math.sin(angle2)*6))
    # clip and draw
    clipped = [(max(cx2+5, min(cx2+225, px)), max(cy2+40, min(cy2+210, py))) for px,py in pts]
    if len(clipped) > 1:
        draw.line(clipped, fill="#CE93D8", width=4)

txt(draw, "CURLY fibres", (cx2+55, cy2+175), size=16, color="#6A1B9A", bold=True)
txt(draw, "on Electron Microscopy", (cx2+15, cy2+195), size=13, color="#333")

# ══════════════════════════════════════════════════════════════════════════════
# 5. MILDER THAN RBCD  (comparison box)
# ══════════════════════════════════════════════════════════════════════════════
mx2, my2 = 300, 385
draw.rounded_rectangle([mx2, my2, mx2+230, my2+150], radius=8, fill="#E8F5E9", outline="#2E7D32", width=3)
txt(draw, "⚖ MILDER THAN RBCD", (mx2+10, my2+10), size=14, color="#2E7D32", bold=True)
# RBCD (bigger, darker)
draw.ellipse([mx2+20, my2+50, mx2+90, my2+120], fill="#B0BEC5", outline="#546E7A", width=3)
txt(draw, "RBCD", (mx2+38, my2+128), size=13, color="#546E7A", bold=True)
# TBCD (smaller, lighter)
draw.ellipse([mx2+120, my2+65, mx2+175, my2+115], fill="#DCEDC8", outline="#558B2F", width=2)
txt(draw, "TBCD", (mx2+131, my2+118), size=13, color="#558B2F", bold=True)
txt(draw, "(less severe)", (mx2+70, my2+135), size=12, color="#555")
# CBD2 badge
draw.rounded_rectangle([mx2+150, my2+10, mx2+225, my2+36], radius=8, fill="#558B2F")
txt(draw, "CBD type 2", (mx2+158, my2+20), size=12, color="white", bold=True)

# ══════════════════════════════════════════════════════════════════════════════
# 6. TREATMENT  (often not needed)
# ══════════════════════════════════════════════════════════════════════════════
tx2, ty2 = 590, 385
draw.rounded_rectangle([tx2, ty2, tx2+230, ty2+150], radius=8, fill="#ECEFF1", outline="#546E7A", width=3)
txt(draw, "💊 TREATMENT", (tx2+10, ty2+10), size=15, color="#546E7A", bold=True)
# big X / not always sign
draw.ellipse([tx2+70, ty2+40, tx2+160, ty2+120], fill="#CFD8DC", outline="#546E7A", width=2)
draw.line([tx2+85, ty2+55, tx2+145, ty2+105], fill="#F44336", width=6)
draw.line([tx2+145, ty2+55, tx2+85, ty2+105], fill="#F44336", width=6)
txt(draw, "NOT always necessary", (tx2+12, ty2+126), size=13, color="#F44336", bold=True)
txt(draw, "PTK/keratectomy if needed", (tx2+8, ty2+143), size=12, color="#333")

# ══════════════════════════════════════════════════════════════════════════════
# 7. PAINFUL EYE  (same as RBCD — both painful)
# ══════════════════════════════════════════════════════════════════════════════
ex2, ey2 = 875, 385
draw.rounded_rectangle([ex2, ey2, ex2+230, ey2+150], radius=8, fill="#FCE4EC", outline="#880E4F", width=3)
txt(draw, "👁 SYMPTOMS", (ex2+10, ey2+10), size=15, color="#880E4F", bold=True)
# eye shape
draw.arc([ex2+30, ey2+40, ex2+200, ey2+120], start=200, end=340, fill="#222", width=4)
draw.arc([ex2+30, ey2+40, ex2+200, ey2+120], start=20, end=160, fill="#222", width=4)
draw.ellipse([ex2+100, ey2+58, ex2+130, ey2+90], fill="#1565C0")
draw.ellipse([ex2+105, ey2+63, ex2+125, ey2+85], fill="#111")
# small tears (milder)
draw.line([ex2+105, ey2+90, ex2+100, ey2+105], fill="#64B5F6", width=3)
draw.line([ex2+125, ey2+90, ex2+130, ey2+105], fill="#64B5F6", width=3)
txt(draw, "Painful ✓  Vision loss ✓", (ex2+20, ey2+118), size=14, color="#880E4F", bold=True)
txt(draw, "Recurrent erosions (milder)", (ex2+10, ey2+136), size=12, color="#555")

# ══════════════════════════════════════════════════════════════════════════════
# BOTTOM LEGEND BAR
# ══════════════════════════════════════════════════════════════════════════════
draw.rectangle([0, H-50, W, H], fill="#2E7D32")
items = [
    ("TBCD = CBD type 2", 30),
    ("Bowman layer dystrophy", 230),
    ("TGFBI gene (AD)", 470),
    ("LM: Saw-toothed", 650),
    ("EM: Curly fibres", 840),
    ("No stain noted  |  Milder than RBCD", 1020),
]
for label, lx in items:
    txt(draw, label, (lx, H-30), size=15, color="white", bold=True)

out = "/tmp/workspace/corneal-dystrophies/TBCD_mnemonic.png"
img.save(out, "PNG")
print(f"Saved: {out}  size={os.path.getsize(out)//1024}KB")
Running Command

python3 /tmp/workspace/corneal-dystrophies/tbcd.py

Both mnemonic images are ready for download:

🪣 Reis-Bücklers (RBCD)

RBCD mnemonic

Image · PNG

🐝 Thiel-Behnke (TBCD)

TBCD mnemonic

Image · PNG


What's in each image:
ElementRBCD imageTBCD image
Main character🪣 Bucket (Bücklers)🐝 Bee (Behnke)
SL appearanceGeographic map blobsHoneycomb hexagons
LM BowmanSheets of paperSaw-toothed line
EM fibresRod-shaped fibresCurly worm fibres
StainMasson Trichrome - RED jar
SeverityFull sizeSmaller (milder)
TreatmentLaser gunBig red ✗ (not always needed)
Gene/inheritanceTGFBI / AD badgeTGFBI / AD badge
Let me know if you want any changes to the layout, colors, or content - or if you'd like more topics done the same way!
This is a shared conversation. Sign in to Orris to start your own chat.