~/usmle-neuro/build_sheet.py
#!/usr/bin/env python3
"""
USMLE Study Sheet: Midbrain, Cerebellum & Dural Sinuses
Printable A4 PDF with cross-section diagrams and clinical syndromes
"""
import math
from reportlab.lib.pagesizes import A4, letter
from reportlab.lib import colors
from reportlab.lib.units import cm, mm, inch
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.platypus import Flowable
from reportlab.graphics.shapes import Drawing, Circle, Rect, Line, Polygon, String, Ellipse, Path
from reportlab.graphics import renderPDF
from reportlab.graphics.shapes import Group
import reportlab.graphics.shapes as shapes
# ββ Colour palette ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
C_BG = colors.HexColor('#F8F9FA')
C_DARK = colors.HexColor('#1A1A2E')
C_ACCENT = colors.HexColor('#16213E')
C_BLUE = colors.HexColor('#0F3460')
C_RED = colors.HexColor('#E94560')
C_GOLD = colors.HexColor('#F5A623')
C_GREEN = colors.HexColor('#27AE60')
C_PURPLE = colors.HexColor('#8E44AD')
C_TEAL = colors.HexColor('#1ABC9C')
C_ORANGE = colors.HexColor('#E67E22')
C_LIGHTBLUE = colors.HexColor('#AED6F1')
C_LIGHTRED = colors.HexColor('#FADBD8')
C_LIGHTYELLOW = colors.HexColor('#FEF9E7')
C_LIGHTGREEN = colors.HexColor('#D5F5E3')
C_LIGHTPURPLE = colors.HexColor('#E8DAEF')
C_LIGHTGREY = colors.HexColor('#ECF0F1')
C_HEADER_BG = colors.HexColor('#1A1A2E')
C_SUBHEADER = colors.HexColor('#16213E')
C_WHITE = colors.white
C_PINK = colors.HexColor('#FDEDEC')
PAGE_W, PAGE_H = A4
# ββ Styles βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
styles = getSampleStyleSheet()
def make_style(name, parent='Normal', **kw):
s = ParagraphStyle(name, parent=styles[parent], **kw)
return s
H1 = make_style('H1', fontSize=18, leading=22, textColor=C_WHITE,
spaceAfter=4, fontName='Helvetica-Bold', alignment=TA_CENTER)
H2 = make_style('H2', fontSize=13, leading=16, textColor=C_WHITE,
spaceAfter=3, fontName='Helvetica-Bold', alignment=TA_LEFT)
H3 = make_style('H3', fontSize=10, leading=13, textColor=C_BLUE,
spaceAfter=2, fontName='Helvetica-Bold')
BODY = make_style('BODY', fontSize=8, leading=10.5, textColor=C_DARK,
spaceAfter=2, fontName='Helvetica')
BODY_SM = make_style('BODY_SM', fontSize=7.2, leading=9.5, textColor=C_DARK,
fontName='Helvetica')
BOLD_SM = make_style('BOLD_SM', fontSize=7.5, leading=9.5, textColor=C_DARK,
fontName='Helvetica-Bold')
PEARL = make_style('PEARL', fontSize=7.5, leading=10, textColor=C_DARK,
fontName='Helvetica', leftIndent=6,
borderPad=4, backColor=C_LIGHTYELLOW)
TABLE_HDR = make_style('TABLE_HDR', fontSize=7.5, leading=9.5,
textColor=C_WHITE, fontName='Helvetica-Bold',
alignment=TA_CENTER)
TABLE_CELL = make_style('TABLE_CELL', fontSize=7, leading=9,
textColor=C_DARK, fontName='Helvetica')
TABLE_CELL_C = make_style('TABLE_CELL_C', fontSize=7, leading=9,
textColor=C_DARK, fontName='Helvetica',
alignment=TA_CENTER)
MNEMONIC = make_style('MNEMONIC', fontSize=8, leading=10.5, textColor=C_PURPLE,
fontName='Helvetica-Bold', alignment=TA_CENTER)
CAPTION = make_style('CAPTION', fontSize=7, leading=9, textColor=colors.grey,
fontName='Helvetica-Oblique', alignment=TA_CENTER)
# ββ Coloured banner helper ββββββββββββββββββββββββββββββββββββββββββββββββββββ
class ColorBanner(Flowable):
def __init__(self, text, width, height=18, bg=C_HEADER_BG, style=H2):
super().__init__()
self.text = text
self.bw = width
self.bh = height
self.bg = bg
self.style = style
def wrap(self, aw, ah):
return self.bw, self.bh
def draw(self):
c = self.canv
c.setFillColor(self.bg)
c.roundRect(0, 0, self.bw, self.bh, 4, fill=1, stroke=0)
c.setFillColor(C_WHITE)
c.setFont(self.style.fontName, self.style.fontSize)
c.drawCentredString(self.bw / 2, (self.bh - self.style.fontSize) / 2 + 1, self.text)
class SectionBanner(Flowable):
"""Full-width coloured section header"""
def __init__(self, text, width, height=22, bg=C_BLUE):
super().__init__()
self.text = text
self.bw = width
self.bh = height
self.bg = bg
def wrap(self, aw, ah):
return self.bw, self.bh
def draw(self):
c = self.canv
c.setFillColor(self.bg)
c.rect(0, 0, self.bw, self.bh, fill=1, stroke=0)
c.setFillColor(C_WHITE)
c.setFont('Helvetica-Bold', 11)
c.drawString(8, (self.bh - 11) / 2 + 1, self.text)
# ββ Midbrain cross-section diagram βββββββββββββββββββββββββββββββββββββββββββ
class MidbrainDiagram(Flowable):
"""Schematic cross-section of the midbrain at level of superior colliculus"""
def __init__(self, w=220, h=190, title="Rostral Midbrain (Superior Colliculus Level)"):
super().__init__()
self.dw = w
self.dh = h
self.title = title
def wrap(self, aw, ah):
return self.dw, self.dh
def draw(self):
c = self.canv
cx, cy = self.dw / 2, self.dh / 2 - 10
# Background
c.setFillColor(colors.HexColor('#F0F4F8'))
c.roundRect(0, 0, self.dw, self.dh - 14, 8, fill=1, stroke=0)
# Title
c.setFillColor(C_BLUE)
c.rect(0, self.dh - 14, self.dw, 14, fill=1, stroke=0)
c.setFillColor(C_WHITE)
c.setFont('Helvetica-Bold', 7)
c.drawCentredString(self.dw / 2, self.dh - 10, self.title)
# Outer midbrain outline (oval)
c.setStrokeColor(C_DARK)
c.setLineWidth(1.5)
c.setFillColor(colors.HexColor('#FDFEFE'))
c.ellipse(cx - 72, cy - 62, cx + 72, cy + 62, fill=1, stroke=1)
# Cerebral aqueduct (Sylvian aqueduct) - small oval at top
c.setFillColor(colors.HexColor('#AED6F1'))
c.setStrokeColor(C_BLUE)
c.setLineWidth(1)
c.ellipse(cx - 7, cy + 28, cx + 7, cy + 44, fill=1, stroke=1)
c.setFillColor(C_BLUE)
c.setFont('Helvetica', 5.5)
c.drawCentredString(cx, cy + 34, 'Aq.')
# Tectum (posterior - top region)
c.setFillColor(colors.HexColor('#D5F5E3'))
c.setStrokeColor(C_GREEN)
c.setLineWidth(0.8)
# draw a region above the aqueduct
p = c.beginPath()
p.moveTo(cx - 30, cy + 28)
p.curveTo(cx - 50, cy + 52, cx + 50, cy + 52, cx + 30, cy + 28)
p.curveTo(cx + 10, cy + 30, cx - 10, cy + 30, cx - 30, cy + 28)
p.close()
c.drawPath(p, fill=1, stroke=1)
c.setFillColor(C_GREEN)
c.setFont('Helvetica-Bold', 6)
c.drawCentredString(cx, cy + 46, 'TECTUM')
c.setFont('Helvetica', 5.5)
c.drawCentredString(cx, cy + 40, '(Sup. Colliculus)')
# Periaqueductal grey
c.setFillColor(colors.HexColor('#FDEBD0'))
c.setStrokeColor(C_ORANGE)
c.ellipse(cx - 18, cy + 14, cx + 18, cy + 50, fill=1, stroke=1)
c.setFillColor(C_ORANGE)
c.setFont('Helvetica', 5.5)
c.drawCentredString(cx, cy + 19, 'PAG')
# Oculomotor nucleus (CN III)
c.setFillColor(colors.HexColor('#FADBD8'))
c.setStrokeColor(C_RED)
c.setLineWidth(1)
c.ellipse(cx - 9, cy + 5, cx + 9, cy + 18, fill=1, stroke=1)
c.setFillColor(C_RED)
c.setFont('Helvetica-Bold', 5.5)
c.drawCentredString(cx, cy + 10, 'CN III nuc')
# Edinger-Westphal
c.setFillColor(colors.HexColor('#E8DAEF'))
c.setStrokeColor(C_PURPLE)
c.ellipse(cx - 7, cy + 18, cx + 7, cy + 28, fill=1, stroke=1)
c.setFillColor(C_PURPLE)
c.setFont('Helvetica', 5)
c.drawCentredString(cx, cy + 22, 'E-W')
# Red nucleus (left and right)
for side, lx in [(-1, cx - 26), (1, cx + 26)]:
c.setFillColor(colors.HexColor('#FADBD8'))
c.setStrokeColor(C_RED)
c.circle(lx, cy + 8, 12, fill=1, stroke=1)
c.setFillColor(C_RED)
c.setFont('Helvetica-Bold', 5.5)
c.drawCentredString(lx, cy + 6, 'Red')
c.drawCentredString(lx, cy + 11, 'Nuc')
# Substantia nigra (curved band)
c.setFillColor(colors.HexColor('#2C3E50'))
c.setStrokeColor(colors.black)
c.setLineWidth(0.5)
for side, sx in [(-1, -1), (1, 1)]:
bx = cx + side * 20
p = c.beginPath()
p.moveTo(bx - side * 12, cy - 8)
p.curveTo(bx - side * 16, cy - 22, bx + side * 16, cy - 22, bx + side * 12, cy - 8)
p.curveTo(bx + side * 8, cy - 4, bx - side * 8, cy - 4, bx - side * 12, cy - 8)
p.close()
c.drawPath(p, fill=1, stroke=1)
c.setFillColor(C_WHITE)
c.setFont('Helvetica-Bold', 5.5)
c.drawCentredString(cx - 20, cy - 14, 'SN')
c.drawCentredString(cx + 20, cy - 14, 'SN')
# Crus cerebri (anterior, bilateral large ovals)
for side, bx in [(-1, cx - 36), (1, cx + 36)]:
c.setFillColor(colors.HexColor('#D6EAF8'))
c.setStrokeColor(C_BLUE)
c.setLineWidth(1)
c.ellipse(bx - 22, cy - 54, bx + 22, cy - 22, fill=1, stroke=1)
c.setFillColor(C_BLUE)
c.setFont('Helvetica-Bold', 5.5)
c.drawCentredString(bx, cy - 42, 'Crus')
c.drawCentredString(bx, cy - 36, 'Cerebri')
c.setFont('Helvetica', 4.8)
c.drawCentredString(bx, cy - 30, '(motor tracts)')
# Medial lemniscus
for side, lx in [(-1, cx - 20), (1, cx + 20)]:
c.setFillColor(colors.HexColor('#A9DFBF'))
c.setStrokeColor(C_GREEN)
c.rect(lx - 8, cy - 8, 16, 10, fill=1, stroke=1)
c.setFillColor(C_GREEN)
c.setFont('Helvetica', 4.5)
c.drawCentredString(lx, cy - 1, 'Med')
c.drawCentredString(lx, cy - 5.5, 'Lemn')
# CN III nerve exits
for side, ex, ey, angle in [(-1, cx - 72, cy - 20, 30), (1, cx + 72, cy - 20, -30)]:
c.setStrokeColor(C_RED)
c.setLineWidth(1.5)
c.line(cx + side * 18, cy + 4, ex, ey)
c.setFillColor(C_RED)
c.setFont('Helvetica-Bold', 6.5)
tx = ex - 12 if side == -1 else ex + 1
c.drawString(tx, ey - 5, 'CN III')
# Labels on outside right
label_x = self.dw - 2
c.setFillColor(C_DARK)
c.setFont('Helvetica', 5.5)
labels = [
(cy + 50, 'Tectum (Superior Colliculus)'),
(cy + 22, 'E-W nucleus (parasymp)'),
(cy + 8, 'CN III nucleus (somatic motor)'),
(cy - 14, 'Substantia Nigra (DA)'),
(cy - 38, 'Crus Cerebri (motor)'),
]
for ly, txt in labels:
c.line(label_x - 32, ly, label_x - 2, ly)
c.drawRightString(label_x, ly - 2, txt)
# ββ Caudal Midbrain cross-section diagram ββββββββββββββββββββββββββββββββββββ
class CaudalMidbrainDiagram(Flowable):
"""Schematic cross-section at level of inferior colliculus"""
def __init__(self, w=220, h=190, title="Caudal Midbrain (Inferior Colliculus Level)"):
super().__init__()
self.dw = w
self.dh = h
self.title = title
def wrap(self, aw, ah):
return self.dw, self.dh
def draw(self):
c = self.canv
cx, cy = self.dw / 2, self.dh / 2 - 10
c.setFillColor(colors.HexColor('#F0F4F8'))
c.roundRect(0, 0, self.dw, self.dh - 14, 8, fill=1, stroke=0)
c.setFillColor(C_RED)
c.rect(0, self.dh - 14, self.dw, 14, fill=1, stroke=0)
c.setFillColor(C_WHITE)
c.setFont('Helvetica-Bold', 7)
c.drawCentredString(self.dw / 2, self.dh - 10, self.title)
# Outer outline
c.setStrokeColor(C_DARK)
c.setLineWidth(1.5)
c.setFillColor(colors.HexColor('#FDFEFE'))
c.ellipse(cx - 72, cy - 62, cx + 72, cy + 62, fill=1, stroke=1)
# Aqueduct
c.setFillColor(colors.HexColor('#AED6F1'))
c.setStrokeColor(C_BLUE)
c.setLineWidth(1)
c.ellipse(cx - 7, cy + 28, cx + 7, cy + 44, fill=1, stroke=1)
c.setFillColor(C_BLUE)
c.setFont('Helvetica', 5.5)
c.drawCentredString(cx, cy + 34, 'Aq.')
# Inferior colliculus tectum
c.setFillColor(colors.HexColor('#FDEBD0'))
c.setStrokeColor(C_ORANGE)
p = c.beginPath()
p.moveTo(cx - 30, cy + 28)
p.curveTo(cx - 50, cy + 52, cx + 50, cy + 52, cx + 30, cy + 28)
p.curveTo(cx + 10, cy + 30, cx - 10, cy + 30, cx - 30, cy + 28)
p.close()
c.drawPath(p, fill=1, stroke=1)
c.setFillColor(C_ORANGE)
c.setFont('Helvetica-Bold', 6)
c.drawCentredString(cx, cy + 46, 'TECTUM')
c.setFont('Helvetica', 5.5)
c.drawCentredString(cx, cy + 40, '(Inf. Colliculus)')
# PAG
c.setFillColor(colors.HexColor('#FDEBD0'))
c.setStrokeColor(C_ORANGE)
c.ellipse(cx - 18, cy + 14, cx + 18, cy + 50, fill=1, stroke=1)
# CN IV nucleus
c.setFillColor(colors.HexColor('#E8DAEF'))
c.setStrokeColor(C_PURPLE)
c.ellipse(cx - 9, cy + 5, cx + 9, cy + 18, fill=1, stroke=1)
c.setFillColor(C_PURPLE)
c.setFont('Helvetica-Bold', 5.5)
c.drawCentredString(cx, cy + 10, 'CN IV nuc')
# Mesencephalic nucleus V (bilateral small dots)
for sx in [cx - 22, cx + 22]:
c.setFillColor(colors.HexColor('#D5F5E3'))
c.setStrokeColor(C_TEAL)
c.circle(sx, cy + 22, 7, fill=1, stroke=1)
c.setFillColor(C_TEAL)
c.setFont('Helvetica', 4.8)
c.drawCentredString(sx, cy + 20, 'Mes V')
# Substantia nigra
c.setFillColor(colors.HexColor('#2C3E50'))
c.setStrokeColor(colors.black)
c.setLineWidth(0.5)
for side in [-1, 1]:
bx = cx + side * 20
p = c.beginPath()
p.moveTo(bx - side * 12, cy - 8)
p.curveTo(bx - side * 16, cy - 22, bx + side * 16, cy - 22, bx + side * 12, cy - 8)
p.curveTo(bx + side * 8, cy - 4, bx - side * 8, cy - 4, bx - side * 12, cy - 8)
p.close()
c.drawPath(p, fill=1, stroke=1)
c.setFillColor(C_WHITE)
c.setFont('Helvetica-Bold', 5.5)
c.drawCentredString(cx - 20, cy - 14, 'SN')
c.drawCentredString(cx + 20, cy - 14, 'SN')
# Crus cerebri
for side, bx in [(-1, cx - 36), (1, cx + 36)]:
c.setFillColor(colors.HexColor('#D6EAF8'))
c.setStrokeColor(C_BLUE)
c.setLineWidth(1)
c.ellipse(bx - 22, cy - 54, bx + 22, cy - 22, fill=1, stroke=1)
c.setFillColor(C_BLUE)
c.setFont('Helvetica-Bold', 5.5)
c.drawCentredString(bx, cy - 42, 'Crus')
c.drawCentredString(bx, cy - 36, 'Cerebri')
# CN IV exits POSTERIORLY - arrow from CN IV nucleus
c.setStrokeColor(C_PURPLE)
c.setLineWidth(1.5)
c.line(cx, cy + 18, cx, cy + 62)
# Then curves around - simplified arrow going up and around
c.setFillColor(C_PURPLE)
c.setFont('Helvetica-Bold', 6)
c.drawCentredString(cx + 30, cy + 60, 'CN IV exits')
c.drawCentredString(cx + 30, cy + 54, 'DORSALLY')
c.setFont('Helvetica', 5)
c.drawCentredString(cx + 30, cy + 48, '(only CN dorsal exit)')
# ββ Cavernous sinus diagram βββββββββββββββββββββββββββββββββββββββββββββββββββ
class CavernousSinusDiagram(Flowable):
def __init__(self, w=230, h=170):
super().__init__()
self.dw = w
self.dh = h
def wrap(self, aw, ah):
return self.dw, self.dh
def draw(self):
c = self.canv
# Background
c.setFillColor(colors.HexColor('#F8F9FA'))
c.roundRect(0, 0, self.dw, self.dh, 6, fill=1, stroke=0)
# Title
c.setFillColor(colors.HexColor('#8E44AD'))
c.rect(0, self.dh - 14, self.dw, 14, fill=1, stroke=0)
c.setFillColor(C_WHITE)
c.setFont('Helvetica-Bold', 7)
c.drawCentredString(self.dw / 2, self.dh - 10, 'CAVERNOUS SINUS - Coronal Cross-Section')
cy = self.dh / 2 - 8
# Sella turcica / pituitary in middle
c.setFillColor(colors.HexColor('#FAD7A0'))
c.setStrokeColor(C_ORANGE)
c.setLineWidth(1)
c.roundRect(self.dw / 2 - 22, cy - 20, 44, 34, 4, fill=1, stroke=1)
c.setFillColor(C_DARK)
c.setFont('Helvetica-Bold', 6.5)
c.drawCentredString(self.dw / 2, cy + 8, 'PITUITARY')
c.drawCentredString(self.dw / 2, cy + 1, '(Sella Turcica)')
c.setFont('Helvetica', 5.5)
c.drawCentredString(self.dw / 2, cy - 7, 'Diaphragma')
c.drawCentredString(self.dw / 2, cy - 12, 'Sellae (dura roof)')
# Left cavernous sinus
lx = 52
c.setFillColor(colors.HexColor('#AED6F1'))
c.setStrokeColor(C_BLUE)
c.setLineWidth(1.5)
c.roundRect(lx - 38, cy - 38, 76, 72, 8, fill=1, stroke=1)
c.setFillColor(C_BLUE)
c.setFont('Helvetica-Bold', 6.5)
c.drawCentredString(lx, cy + 26, 'LEFT')
c.drawCentredString(lx, cy + 20, 'CAVERNOUS')
c.drawCentredString(lx, cy + 14, 'SINUS')
# Right cavernous sinus
rx = self.dw - 52
c.setFillColor(colors.HexColor('#AED6F1'))
c.setStrokeColor(C_BLUE)
c.roundRect(rx - 38, cy - 38, 76, 72, 8, fill=1, stroke=1)
c.setFillColor(C_BLUE)
c.setFont('Helvetica-Bold', 6.5)
c.drawCentredString(rx, cy + 26, 'RIGHT')
c.drawCentredString(rx, cy + 20, 'CAVERNOUS')
c.drawCentredString(rx, cy + 14, 'SINUS')
# ICA inside each sinus
for sx in [lx, rx]:
c.setFillColor(colors.HexColor('#E74C3C'))
c.setStrokeColor(colors.darkred)
c.circle(sx, cy - 5, 9, fill=1, stroke=1)
c.setFillColor(C_WHITE)
c.setFont('Helvetica-Bold', 5.5)
c.drawCentredString(sx, cy - 7, 'ICA')
# CN VI inside each sinus (close to ICA)
for sx in [lx + 14, rx - 14]:
c.setFillColor(colors.HexColor('#F9E79F'))
c.setStrokeColor(colors.goldenrod)
c.circle(sx, cy - 5, 7, fill=1, stroke=1)
c.setFillColor(C_DARK)
c.setFont('Helvetica-Bold', 5.5)
c.drawCentredString(sx, cy - 7, 'VI')
# Lateral wall contents - left side (listed outside)
lw_labels = ['III (CN3)', 'IV (CN4)', 'V1 (ophthal)', 'V2 (maxill)']
c.setFillColor(C_DARK)
c.setFont('Helvetica', 5.5)
for i, lbl in enumerate(lw_labels):
y = cy + 12 - i * 11
c.setFillColor(colors.HexColor('#D5F5E3'))
c.setStrokeColor(C_GREEN)
c.rect(4, y - 4, 38, 9, fill=1, stroke=1)
c.setFillColor(C_DARK)
c.setFont('Helvetica', 5.5)
c.drawString(6, y - 1, lbl)
# Same on right
for i, lbl in enumerate(lw_labels):
y = cy + 12 - i * 11
c.setFillColor(colors.HexColor('#D5F5E3'))
c.setStrokeColor(C_GREEN)
c.rect(self.dw - 42, y - 4, 38, 9, fill=1, stroke=1)
c.setFillColor(C_DARK)
c.setFont('Helvetica', 5.5)
c.drawString(self.dw - 40, y - 1, lbl)
# Lateral wall label
c.setFillColor(C_GREEN)
c.setFont('Helvetica-Bold', 5.5)
c.drawCentredString(23, cy - 38 + 4, 'LATERAL')
c.drawCentredString(23, cy - 38 - 2, 'WALL')
c.drawCentredString(self.dw - 23, cy - 38 + 4, 'LATERAL')
c.drawCentredString(self.dw - 23, cy - 38 - 2, 'WALL')
# Intercavernous sinus
c.setStrokeColor(C_BLUE)
c.setLineWidth(1.5)
c.line(lx + 38, cy, rx - 38, cy)
c.setFillColor(C_BLUE)
c.setFont('Helvetica', 5.5)
c.drawCentredString(self.dw / 2, cy + 4, 'Intercavernous sinus')
# ββ Cerebellar peduncle diagram βββββββββββββββββββββββββββββββββββββββββββββββ
class CerebellarPeduncles(Flowable):
def __init__(self, w=230, h=130):
super().__init__()
self.dw = w
self.dh = h
def wrap(self, aw, ah):
return self.dw, self.dh
def draw(self):
c = self.canv
c.setFillColor(colors.HexColor('#F8F9FA'))
c.roundRect(0, 0, self.dw, self.dh, 6, fill=1, stroke=0)
# Title
c.setFillColor(C_TEAL)
c.rect(0, self.dh - 14, self.dw, 14, fill=1, stroke=0)
c.setFillColor(C_WHITE)
c.setFont('Helvetica-Bold', 7)
c.drawCentredString(self.dw / 2, self.dh - 10, 'CEREBELLAR PEDUNCLES')
cy = self.dh / 2 - 6
cx = self.dw / 2
# Cerebellum (big right oval)
c.setFillColor(colors.HexColor('#D5F5E3'))
c.setStrokeColor(C_GREEN)
c.setLineWidth(1.5)
c.ellipse(cx + 20, cy - 42, cx + 110, cy + 42, fill=1, stroke=1)
c.setFillColor(C_GREEN)
c.setFont('Helvetica-Bold', 8)
c.drawCentredString(cx + 65, cy + 5, 'CEREBELLUM')
# Brainstem (left rect)
c.setFillColor(colors.HexColor('#D6EAF8'))
c.setStrokeColor(C_BLUE)
c.setLineWidth(1.5)
c.roundRect(8, cy - 38, 55, 76, 6, fill=1, stroke=1)
c.setFillColor(C_BLUE)
c.setFont('Helvetica-Bold', 7)
c.drawCentredString(35, cy + 28, 'MIDBRAIN')
c.drawCentredString(35, cy + 8, 'PONS')
c.drawCentredString(35, cy - 16, 'MEDULLA')
# Superior cerebellar peduncle (top)
c.setFillColor(colors.HexColor('#FDEDEC'))
c.setStrokeColor(C_RED)
c.setLineWidth(2)
c.roundRect(cx - 14, cy + 16, cx - 14 + 50, 18, 4, fill=1, stroke=1)
c.setFillColor(C_RED)
c.setFont('Helvetica-Bold', 6)
c.drawCentredString(cx + 11, cy + 22, 'SUPERIOR ped.')
c.setFont('Helvetica', 5)
c.drawCentredString(cx + 11, cy + 17, 'OUTPUT (efferent) β midbrain/thalamus')
# Middle cerebellar peduncle (middle)
c.setFillColor(colors.HexColor('#EBF5FB'))
c.setStrokeColor(C_BLUE)
c.setLineWidth(2)
c.roundRect(cx - 14, cy - 5, cx - 14 + 50, 18, 4, fill=1, stroke=1)
c.setFillColor(C_BLUE)
c.setFont('Helvetica-Bold', 6)
c.drawCentredString(cx + 11, cy + 3, 'MIDDLE ped. (ONLY AFFERENT)')
c.setFont('Helvetica', 5)
c.drawCentredString(cx + 11, cy - 2, 'Input from contralat. pontine nuclei')
# Inferior cerebellar peduncle (bottom)
c.setFillColor(colors.HexColor('#E8F8F5'))
c.setStrokeColor(C_TEAL)
c.setLineWidth(2)
c.roundRect(cx - 14, cy - 26, cx - 14 + 50, 18, 4, fill=1, stroke=1)
c.setFillColor(C_TEAL)
c.setFont('Helvetica-Bold', 6)
c.drawCentredString(cx + 11, cy - 18, 'INFERIOR ped. (mixed)')
c.setFont('Helvetica', 5)
c.drawCentredString(cx + 11, cy - 23, 'Input: spinal cord, olive, vestib.')
# Arrows
c.setStrokeColor(C_RED)
c.setLineWidth(1.5)
c.line(63, cy + 25, cx - 14, cy + 25) # sup - bidirectional but mostly out
c.setStrokeColor(C_BLUE)
c.line(63, cy + 4, cx - 14, cy + 4) # middle in only
c.setStrokeColor(C_TEAL)
c.line(63, cy - 17, cx - 14, cy - 17) # inferior
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
# BUILD THE PDF
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
def build_pdf(path):
doc = SimpleDocTemplate(
path,
pagesize=A4,
leftMargin=1.2 * cm, rightMargin=1.2 * cm,
topMargin=1.2 * cm, bottomMargin=1.2 * cm,
title="USMLE Neuro Study Sheet - Midbrain, Cerebellum, Dural Sinuses",
author="Orris AI"
)
W = PAGE_W - 2.4 * cm # usable width
story = []
# ββ MASTER HEADER βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
header_table = Table(
[[Paragraph('π§ USMLE NEURO HIGH-YIELD', H1),
Paragraph('Midbrain Β· Cerebellum Β· Dural Sinuses', H2)]],
colWidths=[W * 0.5, W * 0.5]
)
header_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, -1), C_HEADER_BG),
('ROWBACKGROUNDS', (0, 0), (-1, -1), [C_HEADER_BG]),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('TOPPADDING', (0, 0), (-1, -1), 8),
('BOTTOMPADDING', (0, 0), (-1, -1), 8),
('LEFTPADDING', (0, 0), (-1, -1), 10),
('RIGHTPADDING', (0, 0), (-1, -1), 10),
('ROUNDEDCORNERS', (0, 0), (-1, -1), [6, 6, 0, 0]),
]))
story.append(header_table)
story.append(Spacer(1, 4))
# ββ SECTION 1: MIDBRAIN DIAGRAMS ββββββββββββββββββββββββββββββββββββββββββ
story.append(SectionBanner('SECTION 1 - MIDBRAIN ANATOMY & CROSS-SECTIONS', W, bg=C_BLUE))
story.append(Spacer(1, 4))
diag_table = Table(
[[MidbrainDiagram(w=int(W * 0.48), h=190),
CaudalMidbrainDiagram(w=int(W * 0.48), h=190)]],
colWidths=[W * 0.5, W * 0.5]
)
diag_table.setStyle(TableStyle([
('VALIGN', (0, 0), (-1, -1), 'TOP'),
('LEFTPADDING', (0, 0), (-1, -1), 2),
('RIGHTPADDING', (0, 0), (-1, -1), 2),
]))
story.append(diag_table)
story.append(Spacer(1, 4))
# Key structures table
story.append(ColorBanner('KEY MIDBRAIN NUCLEI', W, height=14, bg=C_ACCENT))
story.append(Spacer(1, 3))
nuc_data = [
[Paragraph('<b>Nucleus</b>', TABLE_HDR),
Paragraph('<b>Location</b>', TABLE_HDR),
Paragraph('<b>CN / Function</b>', TABLE_HDR),
Paragraph('<b>USMLE Pearl</b>', TABLE_HDR)],
[Paragraph('CN III (Oculomotor)', TABLE_CELL),
Paragraph('Rostral midbrain tegmentum', TABLE_CELL),
Paragraph('SR, IR, MR, IO, LPS muscles', TABLE_CELL),
Paragraph('"Down & out" + ptosis + dilated pupil = CN III palsy', TABLE_CELL)],
[Paragraph('Edinger-Westphal', TABLE_CELL),
Paragraph('Dorsal to CN III nucleus', TABLE_CELL),
Paragraph('Parasymp β ciliary m., sphincter pupillae', TABLE_CELL),
Paragraph('Pupillary constriction + accommodation; compressed FIRST in uncal herniation', TABLE_CELL)],
[Paragraph('CN IV (Trochlear)', TABLE_CELL),
Paragraph('Caudal midbrain tegmentum', TABLE_CELL),
Paragraph('Superior oblique muscle', TABLE_CELL),
Paragraph('Only CN exiting DORSALLY; complete decussation; longest intracranial CN; SO4 / LR6', TABLE_CELL)],
[Paragraph('Red Nucleus', TABLE_CELL),
Paragraph('Midbrain tegmentum', TABLE_CELL),
Paragraph('Involuntary movement center β rubrospinal tract (flexor tone)', TABLE_CELL),
Paragraph('Receives dentate output β relays to thalamus; lesion = contralateral tremor (Benedikt)', TABLE_CELL)],
[Paragraph('Substantia Nigra', TABLE_CELL),
Paragraph('Between crus & tegmentum', TABLE_CELL),
Paragraph('Dopamine (nigrostriatal pathway)', TABLE_CELL),
Paragraph("Lost in Parkinson's β depigmentation; resting tremor, rigidity, bradykinesia", TABLE_CELL)],
[Paragraph('Mesencephalic V', TABLE_CELL),
Paragraph('Lateral midbrain', TABLE_CELL),
Paragraph('Proprioception from jaw muscles', TABLE_CELL),
Paragraph('ONLY primary sensory neurons in the CNS (not in ganglion)', TABLE_CELL)],
]
nuc_tbl = Table(nuc_data, colWidths=[W * 0.18, W * 0.17, W * 0.28, W * 0.37])
nuc_tbl.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), C_BLUE),
('ROWBACKGROUNDS', (0, 1), (-1, -1), [C_WHITE, C_LIGHTGREY]),
('GRID', (0, 0), (-1, -1), 0.4, colors.lightgrey),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('TOPPADDING', (0, 0), (-1, -1), 3),
('BOTTOMPADDING', (0, 0), (-1, -1), 3),
('LEFTPADDING', (0, 0), (-1, -1), 4),
('RIGHTPADDING', (0, 0), (-1, -1), 4),
]))
story.append(nuc_tbl)
story.append(Spacer(1, 5))
# ββ SECTION 2: CLINICAL SYNDROMES βββββββββββββββββββββββββββββββββββββββββ
story.append(SectionBanner('SECTION 2 - MIDBRAIN CLINICAL SYNDROMES (HIGH-YIELD)', W, bg=C_RED))
story.append(Spacer(1, 4))
syn_data = [
[Paragraph('<b>Syndrome</b>', TABLE_HDR),
Paragraph('<b>Lesion Site</b>', TABLE_HDR),
Paragraph('<b>Signs & Symptoms</b>', TABLE_HDR),
Paragraph('<b>Common Cause</b>', TABLE_HDR)],
[Paragraph('WEBER', TABLE_CELL),
Paragraph('Crus cerebri + CN III fascicles', TABLE_CELL),
Paragraph('Ipsilateral CN III palsy (ββ eye, ptosis, mydriasis) + Contralateral hemiplegia', TABLE_CELL),
Paragraph('PCA / SCA infarct', TABLE_CELL)],
[Paragraph('BENEDIKT', TABLE_CELL),
Paragraph('Tegmentum: Red nucleus + CN III fascicles', TABLE_CELL),
Paragraph('Ipsilateral CN III palsy + Contralateral tremor/choreiform movements (red nucleus)', TABLE_CELL),
Paragraph('Paramedian midbrain infarct', TABLE_CELL)],
[Paragraph('CLAUDE', TABLE_CELL),
Paragraph('Red nuc + SCP + CN III', TABLE_CELL),
Paragraph('CN III palsy + contralateral ataxia (SCP involvement)', TABLE_CELL),
Paragraph('Rare midbrain infarct', TABLE_CELL)],
[Paragraph('PARINAUD\n(Dorsal Midbrain)', TABLE_CELL),
Paragraph('Superior colliculi / pretectum', TABLE_CELL),
Paragraph('β Gaze palsy, convergence-retraction nystagmus, light-near dissociation, Collier sign (lid retract), "sunset sign" in babies', TABLE_CELL),
Paragraph('Pineal tumor, hydrocephalus, MS', TABLE_CELL)],
[Paragraph('UNCAL HERNIATION', TABLE_CELL),
Paragraph('CN III compressed at tentorial notch', TABLE_CELL),
Paragraph('Ipsilateral dilated pupil (FIRST sign) β then CN III palsy, contralateral hemiplegia (Kernohan notch = ipsi hemiplegia)', TABLE_CELL),
Paragraph('Epidural/subdural hematoma, large infarct, tumor', TABLE_CELL)],
]
syn_tbl = Table(syn_data, colWidths=[W * 0.15, W * 0.20, W * 0.40, W * 0.25])
syn_tbl.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), C_RED),
('ROWBACKGROUNDS', (0, 1), (-1, -1), [C_LIGHTRED, C_WHITE, C_LIGHTRED, C_WHITE, C_LIGHTRED]),
('GRID', (0, 0), (-1, -1), 0.4, colors.lightgrey),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('TOPPADDING', (0, 0), (-1, -1), 3),
('BOTTOMPADDING', (0, 0), (-1, -1), 3),
('LEFTPADDING', (0, 0), (-1, -1), 4),
('RIGHTPADDING', (0, 0), (-1, -1), 4),
('FONTNAME', (0, 1), (0, -1), 'Helvetica-Bold'),
('FONTSIZE', (0, 1), (0, -1), 7.5),
('TEXTCOLOR', (0, 1), (0, -1), C_RED),
]))
story.append(syn_tbl)
story.append(Spacer(1, 5))
# Mnemonic box
mnem_data = [[
Paragraph('π <b>Weber</b> = W for "Walk away" (contralateral leg weak) + CN III | '
'<b>Benedikt</b> = B for "Bouncy" (tremor/involuntary movements) + CN III | '
'<b>Parinaud</b> = look UP at the Pineal gland (upward gaze palsy)', MNEMONIC),
]]
mnem_tbl = Table(mnem_data, colWidths=[W])
mnem_tbl.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#F9F0FF')),
('BOX', (0, 0), (-1, -1), 1, C_PURPLE),
('TOPPADDING', (0, 0), (-1, -1), 5),
('BOTTOMPADDING', (0, 0), (-1, -1), 5),
('LEFTPADDING', (0, 0), (-1, -1), 8),
('RIGHTPADDING', (0, 0), (-1, -1), 8),
]))
story.append(mnem_tbl)
# ββ PAGE BREAK βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(PageBreak())
# ββ SECTION 3: CEREBELLUM βββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(SectionBanner('SECTION 3 - CEREBELLUM: ANATOMY, CIRCUITS & DISORDERS', W, bg=C_GREEN))
story.append(Spacer(1, 4))
# Peduncles diagram + functional subdivisions table side by side
ped_func_table = Table(
[[CerebellarPeduncles(w=int(W * 0.46), h=130),
Spacer(6, 1),
# Functional subdivisions as mini-table inside
Table([
[Paragraph('<b>Functional Subdivisions</b>', TABLE_HDR)],
[Table([
[Paragraph('<b>Division</b>', BOLD_SM), Paragraph('<b>Location</b>', BOLD_SM), Paragraph('<b>Input</b>', BOLD_SM), Paragraph('<b>Function</b>', BOLD_SM), Paragraph('<b>Lesion</b>', BOLD_SM)],
[Paragraph('Vestibulocerebellum', TABLE_CELL), Paragraph('Flocculonodular lobe', TABLE_CELL), Paragraph('Vestibular nuclei', TABLE_CELL), Paragraph('Balance, eye mvmt, gaze stab.', TABLE_CELL), Paragraph('Truncal ataxia, nystagmus', TABLE_CELL)],
[Paragraph('Spinocerebellum', TABLE_CELL), Paragraph('Vermis + Intermediate', TABLE_CELL), Paragraph('Spinal cord', TABLE_CELL), Paragraph('Motor execution (ongoing)', TABLE_CELL), Paragraph('Gait ataxia / limb ataxia', TABLE_CELL)],
[Paragraph('Pontocerebellum', TABLE_CELL), Paragraph('Lateral hemispheres', TABLE_CELL), Paragraph('Cerebral cortex via pons', TABLE_CELL), Paragraph('Motor PLANNING, sequencing', TABLE_CELL), Paragraph('Intention tremor, dysmetria', TABLE_CELL)],
], colWidths=[W * 0.09, W * 0.10, W * 0.10, W * 0.10, W * 0.10])],
], colWidths=[W * 0.52], rowHeights=[14, None])
]],
colWidths=[W * 0.46, 6, W * 0.52]
)
ped_func_table.setStyle(TableStyle([
('VALIGN', (0, 0), (-1, -1), 'TOP'),
('LEFTPADDING', (0, 0), (-1, -1), 2),
('RIGHTPADDING', (0, 0), (-1, -1), 2),
]))
story.append(ped_func_table)
story.append(Spacer(1, 5))
# Cerebellar cortex layers
story.append(ColorBanner('CEREBELLAR CORTEX LAYERS & CIRCUITS (ALWAYS TESTED)', W, height=14, bg=C_ACCENT))
story.append(Spacer(1, 3))
cortex_data = [
[Paragraph('<b>Layer</b>', TABLE_HDR),
Paragraph('<b>Cell Types</b>', TABLE_HDR),
Paragraph('<b>Neurotransmitter</b>', TABLE_HDR),
Paragraph('<b>What it does</b>', TABLE_HDR)],
[Paragraph('Molecular (outer)', TABLE_CELL),
Paragraph('Stellate cells, basket cells, parallel fibers (granule axons)', TABLE_CELL),
Paragraph('GABA (stellate, basket β Purkinje) INHIBITORY', TABLE_CELL),
Paragraph('Modulate Purkinje cell output; parallel fibers carry excitation along the axis', TABLE_CELL)],
[Paragraph('Purkinje cell (middle)', TABLE_CELL),
Paragraph('Purkinje cells ONLY', TABLE_CELL),
Paragraph('GABA - ALWAYS INHIBITORY β deep nuclei', TABLE_CELL),
Paragraph('SOLE OUTPUT of cerebellar cortex; inhibit deep cerebellar nuclei', TABLE_CELL)],
[Paragraph('Granular (inner)', TABLE_CELL),
Paragraph('Granule cells (excit.), Golgi cells (inhib.)', TABLE_CELL),
Paragraph('Glutamate (granule); GABA (Golgi)', TABLE_CELL),
Paragraph('Granule cells: ONLY excitatory neurons in cerebellar cortex; relay mossy fiber input', TABLE_CELL)],
]
cortex_tbl = Table(cortex_data, colWidths=[W * 0.18, W * 0.27, W * 0.25, W * 0.30])
cortex_tbl.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), C_GREEN),
('ROWBACKGROUNDS', (0, 1), (-1, -1), [C_LIGHTGREEN, C_WHITE, C_LIGHTGREEN]),
('GRID', (0, 0), (-1, -1), 0.4, colors.lightgrey),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('TOPPADDING', (0, 0), (-1, -1), 3),
('BOTTOMPADDING', (0, 0), (-1, -1), 3),
('LEFTPADDING', (0, 0), (-1, -1), 4),
('RIGHTPADDING', (0, 0), (-1, -1), 4),
]))
story.append(cortex_tbl)
story.append(Spacer(1, 4))
# Deep cerebellar nuclei + input fibers side by side
left_col = [
ColorBanner('DEEP CEREBELLAR NUCLEI (latβmed)', int(W * 0.48), height=14, bg=C_TEAL),
Spacer(1, 3),
Table([
[Paragraph('<b>Nucleus</b>', TABLE_HDR),
Paragraph('<b>Peduncle Out</b>', TABLE_HDR),
Paragraph('<b>Projects To</b>', TABLE_HDR),
Paragraph('<b>Lesion</b>', TABLE_HDR)],
[Paragraph('Dentate', TABLE_CELL), Paragraph('Superior', TABLE_CELL),
Paragraph('VL Thalamus β cortex; red nuc', TABLE_CELL), Paragraph('β fine dexterity, delayed initiation', TABLE_CELL)],
[Paragraph('Emboliform', TABLE_CELL), Paragraph('Superior', TABLE_CELL),
Paragraph('Red nucleus (rubrospinal)', TABLE_CELL), Paragraph('Action tremor, limb ataxia', TABLE_CELL)],
[Paragraph('Globose', TABLE_CELL), Paragraph('Superior', TABLE_CELL),
Paragraph('Red nucleus', TABLE_CELL), Paragraph('Truncal titubation', TABLE_CELL)],
[Paragraph('Fastigial', TABLE_CELL), Paragraph('β
INFERIORβ
', TABLE_CELL),
Paragraph('Vestibular nuclei, reticular', TABLE_CELL), Paragraph('Abasia, gait ataxia', TABLE_CELL)],
], colWidths=[int(W * 0.12), int(W * 0.10), int(W * 0.14), int(W * 0.12)])
]
right_col = [
ColorBanner('INPUT FIBERS', int(W * 0.46), height=14, bg=C_PURPLE),
Spacer(1, 3),
Table([
[Paragraph('<b>Fiber</b>', TABLE_HDR),
Paragraph('<b>Origin</b>', TABLE_HDR),
Paragraph('<b>Synapse On</b>', TABLE_HDR),
Paragraph('<b>Effect</b>', TABLE_HDR)],
[Paragraph('Mossy fibers', TABLE_CELL), Paragraph('Spinocereb., pontocerebell., vestibulocerebell.', TABLE_CELL),
Paragraph('Granule cells', TABLE_CELL), Paragraph('Simple spikes in Purkinje cells', TABLE_CELL)],
[Paragraph('Climbing fibers', TABLE_CELL), Paragraph('Inferior olivary nucleus (contralateral)', TABLE_CELL),
Paragraph('Purkinje cell dendrites DIRECTLY', TABLE_CELL), Paragraph('Complex spikes; motor learning/error correction; 1 climbing fiber per Purkinje cell', TABLE_CELL)],
], colWidths=[int(W * 0.10), int(W * 0.14), int(W * 0.11), int(W * 0.11)])
]
# apply table styles
for col_content in [left_col, right_col]:
for item in col_content:
if isinstance(item, Table):
item.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), C_TEAL if col_content is left_col else C_PURPLE),
('ROWBACKGROUNDS', (0, 1), (-1, -1), [C_WHITE, C_LIGHTGREY]),
('GRID', (0, 0), (-1, -1), 0.4, colors.lightgrey),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('TOPPADDING', (0, 0), (-1, -1), 2),
('BOTTOMPADDING', (0, 0), (-1, -1), 2),
('LEFTPADDING', (0, 0), (-1, -1), 3),
('RIGHTPADDING', (0, 0), (-1, -1), 3),
]))
nuc_two_col = Table(
[[item for item in left_col], [item for item in right_col]],
colWidths=[W * 0.5, W * 0.5]
)
# Actually nest differently
nuclei_tbl = Table(
[[Table([[i] for i in left_col], colWidths=[W * 0.49]),
Table([[i] for i in right_col], colWidths=[W * 0.47])]],
colWidths=[W * 0.5, W * 0.5]
)
nuclei_tbl.setStyle(TableStyle([
('VALIGN', (0, 0), (-1, -1), 'TOP'),
('LEFTPADDING', (0, 0), (-1, -1), 2),
('RIGHTPADDING', (0, 0), (-1, -1), 2),
]))
story.append(nuclei_tbl)
story.append(Spacer(1, 4))
# Cerebellar disorders
story.append(ColorBanner('CEREBELLAR DISORDERS & SIGNS', W, height=14, bg=C_RED))
story.append(Spacer(1, 3))
signs_data = [
['Ataxia', 'Dysmetria (finger-nose)', 'Dysdiadochokinesia', 'Intention tremor',
'Scanning speech', 'Hypotonia', 'Nystagmus', 'Rebound phenomenon'],
['Loss of coordination; wide-based gait; resembles intoxication; IPSILATERAL to lesion',
'Overshoot/undershoot target; test with finger-nose-finger or heel-knee-shin',
'Inability to perform rapid alternating movements (pronate/supinate rapidly)',
'Tremor during voluntary movement, worst near target; β resting tremor of Parkinson',
'Slurred, irregular, explosive cadence',
'Decreased resistance to passive stretch',
'Horizontal; fast phase away from lesion',
'Inability to stop movement when resistance removed; forearm example'],
]
col_w = W / 8
signs_tbl = Table(
[[Paragraph(s, BOLD_SM) for s in signs_data[0]],
[Paragraph(s, BODY_SM) for s in signs_data[1]]],
colWidths=[col_w] * 8
)
signs_tbl.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), C_ORANGE),
('BACKGROUND', (0, 1), (-1, 1), colors.HexColor('#FEF9E7')),
('GRID', (0, 0), (-1, -1), 0.4, colors.lightgrey),
('FONTCOLOR', (0, 0), (-1, 0), C_WHITE),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('TOPPADDING', (0, 0), (-1, -1), 3),
('BOTTOMPADDING', (0, 0), (-1, -1), 3),
('LEFTPADDING', (0, 0), (-1, -1), 3),
('RIGHTPADDING', (0, 0), (-1, -1), 3),
]))
story.append(signs_tbl)
story.append(Spacer(1, 4))
# Joubert vs Dandy-Walker
congen_data = [
[Paragraph('<b>Syndrome</b>', TABLE_HDR),
Paragraph('<b>Genetics</b>', TABLE_HDR),
Paragraph('<b>Pathology</b>', TABLE_HDR),
Paragraph('<b>Key Features</b>', TABLE_HDR),
Paragraph('<b>Imaging Hallmark</b>', TABLE_HDR)],
[Paragraph('Joubert', TABLE_CELL),
Paragraph('AR; ciliopathy genes', TABLE_CELL),
Paragraph('Absent/hypoplastic vermis + malformed brainstem', TABLE_CELL),
Paragraph('Hypotonia, ataxia, abnormal eye mvmts, breathing irregularity', TABLE_CELL),
Paragraph('"Molar Tooth Sign" on MRI (elongated SCPs)', TABLE_CELL)],
[Paragraph('Dandy-Walker', TABLE_CELL),
Paragraph('Multifactorial', TABLE_CELL),
Paragraph('Absent/hypoplastic vermis + cystic dilation of 4th ventricle + enlarged posterior fossa', TABLE_CELL),
Paragraph('Hydrocephalus, slow motor dev., convulsions, βICP', TABLE_CELL),
Paragraph('Large posterior fossa cyst on MRI/CT; absent vermis', TABLE_CELL)],
[Paragraph('Friedreich Ataxia', TABLE_CELL),
Paragraph('AR; GAA repeat in frataxin (chr 9)', TABLE_CELL),
Paragraph('Degeneration: dorsal columns + spinocereb. tracts + corticospinal tracts', TABLE_CELL),
Paragraph('Progressive ataxia, absent DTRs + extensor plantar, cardiomyopathy, diabetes, pes cavus', TABLE_CELL),
Paragraph('Spinal cord atrophy; onset adolescence; cardiomyopathy = #1 cause of death', TABLE_CELL)],
]
congen_tbl = Table(congen_data, colWidths=[W * 0.13, W * 0.12, W * 0.22, W * 0.27, W * 0.26])
congen_tbl.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#8E44AD')),
('ROWBACKGROUNDS', (0, 1), (-1, -1), [C_LIGHTPURPLE, C_WHITE, C_LIGHTPURPLE]),
('GRID', (0, 0), (-1, -1), 0.4, colors.lightgrey),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('TOPPADDING', (0, 0), (-1, -1), 3),
('BOTTOMPADDING', (0, 0), (-1, -1), 3),
('LEFTPADDING', (0, 0), (-1, -1), 4),
('RIGHTPADDING', (0, 0), (-1, -1), 4),
]))
story.append(congen_tbl)
# ββ PAGE BREAK βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
story.append(PageBreak())
# ββ SECTION 4: DURAL SINUSES ββββββββββββββββββββββββββββββββββββββββββββββ
story.append(SectionBanner('SECTION 4 - DURAL SEPTA & DURAL VENOUS SINUSES', W, bg=C_PURPLE))
story.append(Spacer(1, 4))
# Dural septa table + cavernous sinus diagram side by side
septa_rows = [
[Paragraph('<b>Septum</b>', TABLE_HDR),
Paragraph('<b>Location</b>', TABLE_HDR),
Paragraph('<b>Separates</b>', TABLE_HDR),
Paragraph('<b>Clinical Note</b>', TABLE_HDR)],
[Paragraph('Falx cerebri', TABLE_CELL), Paragraph('Vertical midline; attached crista galli β int. occipital protuberance', TABLE_CELL),
Paragraph('Left & right cerebral hemispheres', TABLE_CELL), Paragraph('Superior sagittal sinus along its superior border; inferior sagittal sinus along inferior border', TABLE_CELL)],
[Paragraph('Tentorium cerebelli', TABLE_CELL), Paragraph('Horizontal shelf; anchored to petrous ridges', TABLE_CELL),
Paragraph('Supratentorial (cerebrum) from infratentorial (cerebellum/brainstem)', TABLE_CELL),
Paragraph('TENTORIAL NOTCH = gap where brainstem passes; site of uncal herniation & CN III compression', TABLE_CELL)],
[Paragraph('Falx cerebelli', TABLE_CELL), Paragraph('Posterior fossa midline vertical fold', TABLE_CELL),
Paragraph('Left & right cerebellar hemispheres', TABLE_CELL), Paragraph('Occipital sinus runs in its root', TABLE_CELL)],
[Paragraph('Diaphragma sellae', TABLE_CELL), Paragraph('Horizontal over sella turcica', TABLE_CELL),
Paragraph('Covers pituitary fossa; pituitary stalk passes through it', TABLE_CELL),
Paragraph('Pituitary adenoma may bulge through this; restricts expansion of pituitary', TABLE_CELL)],
]
septa_tbl = Table(septa_rows, colWidths=[W * 0.14, W * 0.24, W * 0.22, W * 0.38])
septa_tbl.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), C_PURPLE),
('ROWBACKGROUNDS', (0, 1), (-1, -1), [C_LIGHTPURPLE, C_WHITE]),
('GRID', (0, 0), (-1, -1), 0.4, colors.lightgrey),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('TOPPADDING', (0, 0), (-1, -1), 3),
('BOTTOMPADDING', (0, 0), (-1, -1), 3),
('LEFTPADDING', (0, 0), (-1, -1), 4),
('RIGHTPADDING', (0, 0), (-1, -1), 4),
]))
story.append(septa_tbl)
story.append(Spacer(1, 5))
# Cavernous sinus diagram + sinuses table
story.append(ColorBanner('CAVERNOUS SINUS (β
β
β
HIGHEST YIELD)', W, height=14, bg=C_PURPLE))
story.append(Spacer(1, 3))
cav_diag_tbl = Table(
[[CavernousSinusDiagram(w=int(W * 0.45), h=170),
Table([
[Paragraph('<b>CONTENTS - MEMORIZE</b>', TABLE_HDR)],
[Paragraph('<b>INSIDE the sinus:</b>', BOLD_SM)],
[Paragraph('β’ Internal Carotid Artery (ICA) - with sympathetic plexus', TABLE_CELL)],
[Paragraph('β’ CN VI (Abducens) - MOST VULNERABLE to compression', TABLE_CELL)],
[Paragraph('<b>LATERAL WALL (superior to inferior):</b>', BOLD_SM)],
[Paragraph('β’ CN III (Oculomotor)', TABLE_CELL)],
[Paragraph('β’ CN IV (Trochlear)', TABLE_CELL)],
[Paragraph('β’ V1 (Ophthalmic branch CN V)', TABLE_CELL)],
[Paragraph('β’ V2 (Maxillary branch CN V)', TABLE_CELL)],
[Paragraph('<b>Mnemonic: "O TOM CAT" or "3, 4, V1, V2 in wall; 6 + ICA inside"</b>', MNEMONIC)],
[Paragraph('<b>CONNECTIONS:</b>', BOLD_SM)],
[Paragraph('β’ Angular/facial vein β superior ophthalmic v. β cavernous sinus (infection spread!)', TABLE_CELL)],
[Paragraph('β’ Intercavernous sinuses (LβR communication)', TABLE_CELL)],
[Paragraph('β’ β Inferior petrosal sinus β Internal jugular vein', TABLE_CELL)],
[Paragraph('β’ β Superior petrosal sinus β Sigmoid sinus', TABLE_CELL)],
[Paragraph('<b>CAVERNOUS SINUS THROMBOSIS:</b>', BOLD_SM)],
[Paragraph('Proptosis + chemosis + painful ophthalmoplegia; CN VI palsy FIRST; bilateral (intercavernous); source = facial/sinus infection', TABLE_CELL)],
], colWidths=[W * 0.51])
]],
colWidths=[W * 0.46, W * 0.54]
)
cav_diag_tbl.setStyle(TableStyle([
('VALIGN', (0, 0), (-1, -1), 'TOP'),
('LEFTPADDING', (0, 0), (-1, -1), 2),
('RIGHTPADDING', (0, 0), (-1, -1), 2),
]))
story.append(cav_diag_tbl)
story.append(Spacer(1, 5))
# All dural sinuses table
story.append(ColorBanner('ALL DURAL VENOUS SINUSES', W, height=14, bg=C_BLUE))
story.append(Spacer(1, 3))
sinuses_data = [
[Paragraph('<b>Sinus</b>', TABLE_HDR),
Paragraph('<b>Location</b>', TABLE_HDR),
Paragraph('<b>Drains Into</b>', TABLE_HDR),
Paragraph('<b>Clinical Significance</b>', TABLE_HDR)],
[Paragraph('Superior Sagittal', TABLE_CELL), Paragraph('Superior border of falx cerebri', TABLE_CELL),
Paragraph('Confluence of sinuses', TABLE_CELL), Paragraph('Receives bridging veins; most common site DVT β βICP, seizures', TABLE_CELL)],
[Paragraph('Inferior Sagittal', TABLE_CELL), Paragraph('Inferior border of falx cerebri', TABLE_CELL),
Paragraph('Straight sinus', TABLE_CELL), Paragraph('Joins great cerebral vein at the straight sinus', TABLE_CELL)],
[Paragraph('Straight Sinus', TABLE_CELL), Paragraph('Junction: falx cerebri + tentorium', TABLE_CELL),
Paragraph('Confluence of sinuses', TABLE_CELL), Paragraph('Receives: inferior sagittal sinus + Vein of Galen', TABLE_CELL)],
[Paragraph('Confluence (Torcular)', TABLE_CELL), Paragraph('Internal occipital protuberance', TABLE_CELL),
Paragraph('Transverse sinuses', TABLE_CELL), Paragraph('Meeting point of sup. sagittal, straight, occipital sinuses', TABLE_CELL)],
[Paragraph('Transverse', TABLE_CELL), Paragraph('Posterior edge of tentorium', TABLE_CELL),
Paragraph('Sigmoid sinus', TABLE_CELL), Paragraph('Bilateral; thrombosis β βICP, headache', TABLE_CELL)],
[Paragraph('Sigmoid', TABLE_CELL), Paragraph('S-shaped; petrous temporal bone', TABLE_CELL),
Paragraph('Internal jugular vein (jugular foramen)', TABLE_CELL), Paragraph('Near mastoid; mastoiditis can cause thrombosis (Gradenigo syndrome area)', TABLE_CELL)],
[Paragraph('Cavernous', TABLE_CELL), Paragraph('Sides of sella turcica', TABLE_CELL),
Paragraph('Via inf. petrosal sinus β IJV; via sup. petrosal β sigmoid', TABLE_CELL), Paragraph('See above - highest yield sinus', TABLE_CELL)],
[Paragraph('Superior Petrosal', TABLE_CELL), Paragraph('Superior petrous bone', TABLE_CELL),
Paragraph('Cavernous β sigmoid sinus', TABLE_CELL), Paragraph('Bridge between cavernous and sigmoid sinuses', TABLE_CELL)],
[Paragraph('Inferior Petrosal', TABLE_CELL), Paragraph('Inferior petrous bone', TABLE_CELL),
Paragraph('Cavernous β IJV', TABLE_CELL), Paragraph('Also receives labyrinthine veins from inner ear', TABLE_CELL)],
[Paragraph('Occipital', TABLE_CELL), Paragraph('Root of falx cerebelli', TABLE_CELL),
Paragraph('Confluence of sinuses', TABLE_CELL), Paragraph('Connects marginal sinus to confluence', TABLE_CELL)],
[Paragraph('Marginal', TABLE_CELL), Paragraph('Around foramen magnum', TABLE_CELL),
Paragraph('Vertebral venous plexus', TABLE_CELL), Paragraph('Connects dural sinuses to vertebral venous system', TABLE_CELL)],
]
sinuses_tbl = Table(sinuses_data, colWidths=[W * 0.15, W * 0.22, W * 0.25, W * 0.38])
sinuses_tbl.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, 0), C_BLUE),
('ROWBACKGROUNDS', (0, 1), (-1, -1), [C_LIGHTBLUE, C_WHITE]),
('GRID', (0, 0), (-1, -1), 0.4, colors.lightgrey),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('TOPPADDING', (0, 0), (-1, -1), 2),
('BOTTOMPADDING', (0, 0), (-1, -1), 2),
('LEFTPADDING', (0, 0), (-1, -1), 4),
('RIGHTPADDING', (0, 0), (-1, -1), 4),
]))
story.append(sinuses_tbl)
story.append(Spacer(1, 5))
# ββ FINAL QUICK-REVIEW FLASH BOX ββββββββββββββββββββββββββββββββββββββββββ
story.append(ColorBanner('RAPID-FIRE USMLE PEARLS', W, height=14, bg=C_GOLD))
story.append(Spacer(1, 3))
pearls = [
'β
CN III palsy = "DOWN and OUT" eye + PTOSIS + DILATED pupil (parasympathetics on outside = compressed first)',
'β
CN IV = only CN exiting DORSALLY; only CN with complete decussation; palsy = head tilt AWAY from lesion',
'β
PURKINJE CELLS = sole output of cerebellar cortex; always INHIBITORY (GABA); receive mossy (simple spikes) & climbing (complex spikes) input',
'β
FASTIGIAL nucleus = only deep nucleus whose efferents exit via INFERIOR cerebellar peduncle (all others = SUPERIOR)',
'β
MIDDLE cerebellar peduncle = AFFERENT ONLY (pontine nuclei β cerebellum); largest peduncle',
'β
SUPERIOR cerebellar peduncle = primarily OUTPUT (decussates in midbrain under inferior colliculus)',
'β
CAVERNOUS SINUS lateral wall (superiorβinferior): CN III, IV, V1, V2 | INSIDE: ICA + CN VI',
'β
CN VI is MOST VULNERABLE in cavernous sinus (runs freely, not protected by lateral wall)',
'β
Facial vein β superior ophthalmic vein β cavernous sinus: route of intracranial infection spread from face',
'β
WEBER = ventral midbrain (crus) = CN III + contralateral hemiplegia | BENEDIKT = tegmentum = CN III + contralateral tremor',
'β
PARINAUD = superior colliculi/pretectum: upward gaze palsy + light-near dissociation + convergence-retraction nystagmus (pineal gland tumor)',
'β
DANDY-WALKER = absent vermis + cystic 4th ventricle + βICP | JOUBERT = absent vermis + molar tooth sign on MRI',
'β
Cerebellar ataxia = IPSILATERAL; Romberg NEGATIVE (falls with eyes OPEN too); vs sensory ataxia = Romberg POSITIVE',
'β
PICA infarct = Wallenberg (lateral medullary) syndrome: ipsilateral face + contralateral body pain/temp loss + ataxia + Horner + dysphagia',
'β
Vein of Galen β Straight sinus β Confluence β Transverse β Sigmoid β Internal Jugular Vein',
]
pearl_rows = [[Paragraph(p, BODY_SM)] for p in pearls]
pearl_tbl = Table(pearl_rows, colWidths=[W])
pearl_tbl.setStyle(TableStyle([
('ROWBACKGROUNDS', (0, 0), (-1, -1), [C_LIGHTYELLOW, C_WHITE]),
('LEFTPADDING', (0, 0), (-1, -1), 6),
('RIGHTPADDING', (0, 0), (-1, -1), 6),
('TOPPADDING', (0, 0), (-1, -1), 2),
('BOTTOMPADDING', (0, 0), (-1, -1), 2),
('BOX', (0, 0), (-1, -1), 0.8, C_GOLD),
('LINEBELOW', (0, 0), (-1, -2), 0.2, colors.lightgrey),
]))
story.append(pearl_tbl)
story.append(Spacer(1, 6))
# Footer note
story.append(Paragraph(
'USMLE Study Sheet β Midbrain, Cerebellum & Dural Sinuses | Generated by Orris AI | Good luck on your exam!',
make_style('footer', fontSize=6.5, leading=9, textColor=colors.grey,
fontName='Helvetica-Oblique', alignment=TA_CENTER)
))
doc.build(story)
print(f"PDF written to: {path}")
if __name__ == '__main__':
build_pdf('/tmp/workspace/usmle-neuro/USMLE_Neuro_StudySheet.pdf')