I have my MPT practical exam for that I want PG level assessment , how to diagnose & management along with recent advances & also discription like anatomy of Stroke ( including all type according to tertiary seperately explain)
"stroke" AND "rehabilitation" AND "physiotherapy"
"ischemic stroke" AND "management" AND "thrombolysis"
stroke rehabilitation physiotherapy recent advances 2024 2025 robot-assisted tDCS rTMS
Note: The anatomy of the Circle of Willis is highly variable; incomplete circles reduce collateral flow during occlusion.
| Artery Occluded | Key Deficits |
|---|---|
| ACA | Contralateral leg > arm weakness, abulia, urinary incontinence, grasp/suck reflexes, apraxia of gait |
| MCA (main trunk) | Contralateral face + arm > leg weakness + sensory loss, homonymous hemianopsia, aphasia (dominant), neglect (non-dominant), gaze deviation toward lesion |
| PCA | Contralateral homonymous hemianopsia, CN III palsy (ipsilateral), thalamic pain, memory disturbance |
| Basilar artery | "Locked-in syndrome," quadriplegia, coma, ocular palsies |
| PICA (Wallenberg/Lateral Medullary syndrome) | Vertigo, Horner syndrome, ipsilateral facial numbness + loss of corneal reflex, contralateral pain/temperature loss, dysphagia, dysphonia |
| Lacunar (small vessels) | Pure motor hemiplegia, pure sensory stroke, ataxic hemiparesis, clumsy hand-dysarthria |


| Modifiable | Non-Modifiable |
|---|---|
| Hypertension (strongest) | Age (75% occur >75 yrs) |
| Atrial fibrillation | Male sex |
| Diabetes mellitus | Race (Black, Asian higher risk) |
| Dyslipidemia | Family history/genetics |
| Smoking | Prior stroke/TIA |
| Physical inactivity | |
| Obesity/poor nutrition | |
| Alcohol (heavy use) |
| Domain | Assessment Tool |
|---|---|
| Neurological status | NIHSS, GCS |
| Motor function | Fugl-Meyer Assessment (FMA) - upper/lower limb (0-66/34) |
| Tone/Spasticity | Modified Ashworth Scale (MAS), Modified Tardieu Scale |
| Balance | Berg Balance Scale (BBS), Trunk Impairment Scale |
| Gait | Functional Ambulation Category (FAC), 10-Metre Walk Test, 6-Minute Walk Test, Timed Up-and-Go (TUG) |
| Upper limb | Action Research Arm Test (ARAT), Box & Blocks, Grip strength |
| ADL/Function | Barthel Index, FIM (Functional Independence Measure), modified Rankin Scale (mRS) |
| Cognition | MMSE, MoCA |
| Depression | PHQ-9, Hamilton Depression Rating Scale |
| Dysphagia | Bedside Swallow Assessment, MASA, FEES |
| Neuroplasticity stage | Brunnstrom Stage of Recovery (I-VI) |
| Pain | VAS, NRS, DN4 (neuropathic pain) |
| Complication | Timeframe | Management |
|---|---|---|
| Cerebral edema / herniation | Days 1-5 | Mannitol, hypertonic saline, hemicraniectomy (malignant MCA) |
| Aspiration pneumonia | Early | Swallow screen, positioning, antibiotics |
| DVT/PE | Any time | LMWH, compression stockings, early mobilization |
| Post-stroke depression | Weeks-months | SSRIs (also aid motor recovery), counseling |
| Spasticity | Weeks-months | Stretching, splinting, Botulinum toxin A, baclofen |
| Shoulder subluxation/pain | Subacute | Sling, taping, FES, intra-articular corticosteroid |
| Falls | Chronic | Balance training, home modification |
| Post-stroke seizures | Any | AEDs only for clinical seizures |
| Central post-stroke pain | Months | Amitriptyline, lamotrigine, gabapentin |
| Urinary incontinence | Common | Bladder training, pelvic floor exercises |
| Type | Pathology | Imaging | Key Feature | Treatment |
|---|---|---|---|---|
| Ischemic - Thrombotic | In-situ atherosclerosis | CT normal early; MRI DWI bright | Stuttering onset, atherosclerosis risk factors | tPA + thrombectomy |
| Ischemic - Embolic | Cardioembolism | CT normal; DWI territorial infarct | Sudden onset, AF, valvular disease | tPA; anticoagulation |
| Lacunar | Small vessel lipohyalinosis | MRI shows small deep lesion | Pure motor/sensory; no cortical signs | Antiplatelet, BP control |
| ICH | Hypertension/CAA | CT: hyperdense lesion | Vomiting, LOC, gradual progression | BP control, reverse coag |
| SAH | Ruptured aneurysm | CT: blood in cisterns | "Thunderclap headache" | Nimodipine, clip/coil |
| TIA | Any ischemic mechanism | DWI negative | Resolving deficits <24h | Dual antiplatelet, ABCD2 |
Recent evidence note: The 2025 Cochrane review (PMID: 39932103) provides updated evidence that physical rehabilitation approaches significantly improve gait and upper limb function. The 2025 Cochrane VR review (PMID: 40537150) confirms VR as an effective adjunct. The 2026 ESO guideline update on blood pressure management revises targets for both ischemic stroke and ICH.
Make a PDF quick reference guide with assessment tools and scales
ls -la /home/daytona/workspace/ 2>/dev/null || mkdir -p /home/daytona/workspace && ls -la /home/daytona/workspace/
mkdir -p /home/daytona/workspace/stroke-ref-guide && python3 -c "import reportlab; print('reportlab ok')" && python3 -c "from reportlab.lib.pagesizes import A4; print('A4 ok')"
~/stroke-ref-guide/make_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, PageBreak
)
from reportlab.platypus.flowables import BalancedColumns
from reportlab.graphics.shapes import Drawing, Rect, String
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
import os
OUTPUT = "/home/daytona/workspace/stroke-ref-guide/Stroke_Quick_Reference_Guide.pdf"
# ── Color palette ──────────────────────────────────────────────────────────
C_HEADER = colors.HexColor("#1a3a5c") # deep navy
C_ISCHEMIC = colors.HexColor("#1565C0") # blue
C_HEMOR = colors.HexColor("#B71C1C") # red
C_SAH = colors.HexColor("#6A1B9A") # purple
C_TIA = colors.HexColor("#00695C") # teal
C_ASSESS = colors.HexColor("#E65100") # orange
C_REHAB = colors.HexColor("#2E7D32") # green
C_GOLD = colors.HexColor("#F9A825") # amber accent
C_LIGHT1 = colors.HexColor("#E3F2FD") # pale blue
C_LIGHT2 = colors.HexColor("#FFEBEE") # pale red
C_LIGHT3 = colors.HexColor("#F3E5F5") # pale purple
C_LIGHT4 = colors.HexColor("#E0F2F1") # pale teal
C_LIGHT5 = colors.HexColor("#FFF8E1") # pale amber
C_LIGHTG = colors.HexColor("#E8F5E9") # pale green
C_ROW_ALT = colors.HexColor("#F5F5F5") # light grey
C_WHITE = colors.white
C_BLACK = colors.black
C_DARK = colors.HexColor("#212121")
# ── Document setup ─────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=1.4*cm, leftMargin=1.4*cm,
topMargin=1.6*cm, bottomMargin=1.4*cm,
title="Stroke Quick Reference Guide – MPT Exam",
author="Orris Medical"
)
W, H = A4
CONTENT_W = W - 2.8*cm
styles = getSampleStyleSheet()
def sty(name, **kw):
return ParagraphStyle(name, **kw)
BASE = sty("base", fontName="Helvetica", fontSize=8, leading=11, textColor=C_DARK)
BASEB = sty("baseb", fontName="Helvetica-Bold", fontSize=8, leading=11, textColor=C_DARK)
SMALL = sty("small", fontName="Helvetica", fontSize=7, leading=10, textColor=C_DARK)
SMB = sty("smb", fontName="Helvetica-Bold", fontSize=7, leading=10, textColor=C_DARK)
def H1(text, bg=C_HEADER):
return Table(
[[Paragraph(f"<font color='white'><b>{text}</b></font>",
sty("h1p", fontName="Helvetica-Bold", fontSize=13, leading=16,
textColor=C_WHITE, alignment=TA_CENTER))]],
colWidths=[CONTENT_W],
style=TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING",(0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("ROUNDEDCORNERS", (0,0), (-1,-1), [4,4,4,4]),
])
)
def H2(text, color=C_HEADER):
return Table(
[[Paragraph(f"<font color='white'><b>{text}</b></font>",
sty("h2p", fontName="Helvetica-Bold", fontSize=9.5, leading=13,
textColor=C_WHITE))]],
colWidths=[CONTENT_W],
style=TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING",(0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 8),
])
)
def H3(text, color=C_HEADER):
return Paragraph(f"<font color='#{color.hexval()[2:] if hasattr(color,'hexval') else '1a3a5c'}'><b>{text}</b></font>",
sty("h3p", fontName="Helvetica-Bold", fontSize=8.5, leading=12))
def colorH3(text, hexcolor):
return Paragraph(f"<font color='{hexcolor}'><b>{text}</b></font>",
sty("ch3", fontName="Helvetica-Bold", fontSize=8.5, leading=12))
def sp(h=4): return Spacer(1, h)
def hr(color=C_HEADER, w=0.5): return HRFlowable(width="100%", thickness=w, color=color, spaceAfter=3, spaceBefore=2)
def plain_table(data, col_widths, bg_header=C_HEADER, row_colors=True, fontsize=7.5):
"""Generic styled table. First row = header."""
ts = [
("BACKGROUND", (0,0), (-1,0), bg_header),
("TEXTCOLOR", (0,0), (-1,0), C_WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), fontsize),
("LEADING", (0,0), (-1,-1), fontsize+2.5),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING",(0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#BDBDBD")),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("ROWBACKGROUNDS", (0,1), (-1,-1), [C_WHITE, C_ROW_ALT] if row_colors else [C_WHITE]),
("FONTNAME", (0,1), (-1,-1), "Helvetica"),
("TEXTCOLOR", (0,1), (-1,-1), C_DARK),
]
cells = []
for i, row in enumerate(data):
cells.append([Paragraph(str(c), sty(f"tc{i}", fontName="Helvetica-Bold" if i==0 else "Helvetica",
fontSize=fontsize, leading=fontsize+2.5,
textColor=C_WHITE if i==0 else C_DARK)) for c in row])
return Table(cells, colWidths=col_widths, style=TableStyle(ts), repeatRows=1)
# ══════════════════════════════════════════════════════════════════════
# BUILD CONTENT
# ══════════════════════════════════════════════════════════════════════
story = []
# ── COVER HEADER ──────────────────────────────────────────────────────
cover = Table(
[[Paragraph("<font color='white'><b>STROKE</b></font>",
sty("cov1", fontName="Helvetica-Bold", fontSize=28, leading=32, textColor=C_WHITE, alignment=TA_CENTER)),
Paragraph("<font color='white'>Quick Reference Guide</font><br/>"
"<font color='#BBDEFB'>Assessment Scales & Tools for MPT Exam</font>",
sty("cov2", fontName="Helvetica", fontSize=11, leading=16, textColor=C_WHITE))]],
colWidths=[4*cm, CONTENT_W - 4*cm],
style=TableStyle([
("BACKGROUND", (0,0), (-1,-1), C_HEADER),
("TOPPADDING", (0,0), (-1,-1), 14),
("BOTTOMPADDING", (0,0), (-1,-1), 14),
("LEFTPADDING", (0,0), (0,0), 16),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("LINEBELOW", (0,0), (-1,-1), 3, C_GOLD),
])
)
story.append(cover)
story.append(sp(8))
# ── SECTION 1: STROKE TYPES OVERVIEW ──────────────────────────────────
story.append(H2("1. STROKE CLASSIFICATION AT A GLANCE", C_HEADER))
story.append(sp(4))
type_data = [
["TYPE", "SUBTYPE", "% ALL STROKES", "KEY FEATURE", "CT FINDING"],
["ISCHEMIC", "Thrombotic (large vessel)", "~50%", "Gradual onset, atherosclerosis RF", "Normal early → hypodensity 24-48h"],
["ISCHEMIC", "Embolic (cardioembolic)", "~20%", "Sudden onset, AF/valvular disease", "Territorial infarct, cortical"],
["ISCHEMIC", "Lacunar (small vessel)", "~17%", "Pure motor/sensory, no cortical signs", "Small deep lesion; may miss on CT"],
["HEMORRHAGIC", "Intracerebral (ICH)", "~10%", "Vomiting, LOC, gradual progression", "Hyperdense lesion 40-100 HU"],
["HEMORRHAGIC", "Subarachnoid (SAH)", "~3%", "'Thunderclap headache' worst ever", "Blood in cisterns/sulci"],
["TIA", "Any ischemic mechanism", "<1 min-24h", "Full resolution, no infarct on DWI", "CT normal; MRI DWI negative"],
]
col_w = [2.4*cm, 3.8*cm, 2.5*cm, 5.2*cm, 4.6*cm]
t = plain_table(type_data, col_w, bg_header=C_HEADER, fontsize=7)
story.append(t)
story.append(sp(8))
# ── SECTION 2: PREHOSPITAL SCALES ─────────────────────────────────────
story.append(H2("2. PREHOSPITAL STROKE RECOGNITION SCALES", C_ISCHEMIC))
story.append(sp(4))
# 2-col layout: FAST box + CPSS box
fast_rows = [
[Paragraph("<b>FAST</b>", sty("fs1", fontName="Helvetica-Bold", fontSize=9, textColor=C_ISCHEMIC))],
[Paragraph("<b>F</b> – Face: Unilateral droop/asymmetry", SMALL)],
[Paragraph("<b>A</b> – Arm: Unilateral weakness/drift", SMALL)],
[Paragraph("<b>S</b> – Speech: Slurred/absent/wrong words", SMALL)],
[Paragraph("<b>T</b> – Time: Call emergency immediately", SMALL)],
[Paragraph("Sensitivity ~72% | Specificity ~83%", sty("fs2", fontName="Helvetica-Oblique", fontSize=7, textColor=colors.grey))],
]
fast_t = Table(fast_rows, colWidths=[CONTENT_W*0.30],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), C_LIGHT1),
("BOX",(0,0),(-1,-1),1,C_ISCHEMIC),
("TOPPADDING",(0,0),(-1,-1),3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1),6),
]))
cpss_rows = [
[Paragraph("<b>CPSS</b> – Cincinnati Prehospital Stroke Scale", sty("cs1", fontName="Helvetica-Bold", fontSize=9, textColor=C_ISCHEMIC))],
[Paragraph("<b>1.</b> Facial droop: Ask to smile → unilateral droop = abnormal", SMALL)],
[Paragraph("<b>2.</b> Arm drift: Eyes closed, hold arms 10s → one drifts = abnormal", SMALL)],
[Paragraph("<b>3.</b> Speech: Repeat 'The sky is blue' → slurred/wrong/none = abnormal", SMALL)],
[Paragraph("If <b>ANY 1</b> of 3 abnormal → 72% probability of stroke", SMALL)],
[Paragraph("Sensitivity ~66% | Specificity ~87%", sty("cs2", fontName="Helvetica-Oblique", fontSize=7, textColor=colors.grey))],
]
cpss_t = Table(cpss_rows, colWidths=[CONTENT_W*0.46],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), C_LIGHT1),
("BOX",(0,0),(-1,-1),1,C_ISCHEMIC),
("TOPPADDING",(0,0),(-1,-1),3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1),6),
]))
lapss_rows = [
[Paragraph("<b>LAPSS</b> – Los Angeles", sty("ls1", fontName="Helvetica-Bold", fontSize=9, textColor=C_ISCHEMIC))],
[Paragraph("All YES + ≥1 asymmetry →", SMALL)],
[Paragraph("Sens <b>91%</b> Spec <b>97%</b>", SMALL)],
[Paragraph("1. Age >45 2. No seizure hx 3. Ambulatory baseline 4. Glucose 60-400 5. Asymmetry: face/grip/arm", SMALL)],
]
lapss_t = Table(lapss_rows, colWidths=[CONTENT_W*0.20],
style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), C_LIGHT1),
("BOX",(0,0),(-1,-1),1,C_ISCHEMIC),
("TOPPADDING",(0,0),(-1,-1),3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1),6),
]))
pre_row = Table([[fast_t, sp(0), cpss_t, sp(0), lapss_t]],
colWidths=[CONTENT_W*0.30, 0.4*cm, CONTENT_W*0.46, 0.4*cm, CONTENT_W*0.20],
style=TableStyle([("VALIGN",(0,0),(-1,-1),"TOP")]))
story.append(pre_row)
story.append(sp(8))
# ── SECTION 3: NIHSS ───────────────────────────────────────────────────
story.append(H2("3. NIH STROKE SCALE (NIHSS) — Score 0–42", C_ISCHEMIC))
story.append(sp(4))
nihss_data = [
["ITEM", "DOMAIN TESTED", "SCORE RANGE", "KEY NOTE"],
["1A", "Level of consciousness (LOC)", "0-3", "0=alert; 3=reflex only/unresponsive"],
["1B", "LOC questions (month/age)", "0-2", "0=both correct; 2=both wrong"],
["1C", "LOC commands (close eyes/grip)", "0-2", "0=both performed; 2=neither"],
["2", "Horizontal gaze", "0-2", "0=normal; 2=forced deviation"],
["3", "Visual fields", "0-3", "0=no loss; 3=bilateral blindness"],
["4", "Facial palsy", "0-3", "0=normal; 3=complete paralysis"],
["5", "Arm motor (R + L separately)", "0-4 each", "0=no drift; 4=no movement"],
["6", "Leg motor (R + L separately)", "0-4 each", "0=no drift; 4=no movement"],
["7", "Limb ataxia", "0-2", "0=absent; 2=both limbs ataxic"],
["8", "Sensory", "0-2", "0=normal; 2=severe loss"],
["9", "Best language/aphasia", "0-3", "0=no aphasia; 3=mute/global aphasia"],
["10", "Dysarthria", "0-2", "0=normal; 2=unintelligible/anarthria"],
["11", "Extinction/inattention", "0-2", "0=no abnormality; 2=profound neglect"],
]
nihss_t = plain_table(nihss_data, [1*cm, 4.2*cm, 2.8*cm, CONTENT_W-8*cm], bg_header=C_ISCHEMIC, fontsize=7.2)
story.append(nihss_t)
story.append(sp(4))
# NIHSS severity bands
sev_data = [
["NIHSS SCORE", "SEVERITY", "CLINICAL IMPLICATION"],
["0", "Normal", "No deficit"],
["1–4", "Minor stroke", "tPA eligibility: only if disabling symptoms"],
["5–15", "Moderate stroke", "Standard tPA candidate window"],
["16–20", "Moderate-severe", "High risk; LVO likely"],
["21–42", "Severe stroke", "Consider thrombectomy; poor prognosis"],
]
sev_t = plain_table(sev_data, [2.6*cm, 3.2*cm, CONTENT_W-5.8*cm], bg_header=C_ISCHEMIC, fontsize=7.5)
story.append(sev_t)
story.append(sp(8))
# ── SECTION 4: ABCD2 SCORE ────────────────────────────────────────────
story.append(H2("4. ABCD² SCORE — TIA Risk Stratification", C_TIA))
story.append(sp(4))
abcd2_data = [
["PARAMETER", "CRITERIA", "POINTS"],
["A – Age", "≥60 years", "1"],
["B – Blood Pressure", "SBP ≥140 or DBP ≥90 mmHg", "1"],
["C – Clinical features","Unilateral weakness", "2"],
["", "Speech disturbance only", "1"],
["D – Duration", "≥60 minutes", "2"],
["", "10–59 minutes", "1"],
["D – Diabetes", "Diabetes mellitus present", "1"],
["TOTAL RANGE", "", "0–7"],
]
abcd2_t = plain_table(abcd2_data, [3.5*cm, 7.5*cm, 2*cm], bg_header=C_TIA, fontsize=7.5)
story.append(abcd2_t)
story.append(sp(3))
risk_data = [
["SCORE", "2-DAY STROKE RISK", "RISK CATEGORY", "ACTION"],
["0–3", "~1%", "LOW", "Outpatient workup within 24–48h"],
["4–5", "~4%", "MODERATE", "Urgent evaluation; admit or expedite"],
["6–7", "~8%", "HIGH", "Admit; dual antiplatelet + imaging same day"],
]
risk_t = plain_table(risk_data, [2*cm, 3*cm, 3*cm, CONTENT_W-8*cm], bg_header=C_TIA, fontsize=7.5)
story.append(risk_t)
story.append(sp(8))
# ── SECTION 5: FUGL-MEYER ASSESSMENT ─────────────────────────────────
story.append(H2("5. FUGL-MEYER ASSESSMENT (FMA)", C_REHAB))
story.append(sp(4))
fma_rows = [
["DOMAIN", "MAX SCORE", "CONTENT"],
["Upper Extremity", "66", "Shoulder, elbow, forearm, wrist, hand, coordination/speed"],
["Lower Extremity", "34", "Hip, knee, ankle, coordination/speed"],
["Balance", "14", "Sitting/standing balance in 7 positions"],
["Sensation", "24", "Light touch, proprioception – 4 limb segments"],
["Passive ROM", "44", "8 joints tested (pain + ROM)"],
["TOTAL", "226", "Most common use: UE (66) + LE (34) = Motor domain (100)"],
]
fma_t = plain_table(fma_rows, [3.5*cm, 2.5*cm, CONTENT_W-6*cm], bg_header=C_REHAB, fontsize=7.5)
story.append(fma_t)
story.append(sp(3))
# FMA severity bands
fma_sev = [
["UE SCORE (0–66)", "SEVERITY"],
["0–22", "Severe impairment"],
["23–42", "Moderate impairment"],
["43–52", "Mild-moderate impairment"],
["53–66", "Mild / near normal"],
]
fma_sev_t = plain_table(fma_sev, [4*cm, CONTENT_W-4*cm], bg_header=C_REHAB, fontsize=7.5)
story.append(fma_sev_t)
story.append(sp(8))
# ── SECTION 6: BRUNNSTROM STAGES ─────────────────────────────────────
story.append(H2("6. BRUNNSTROM STAGES OF RECOVERY", C_REHAB))
story.append(sp(4))
brunn_data = [
["STAGE", "ARM", "HAND", "LEG", "TONE"],
["I", "Flaccidity, no movement", "No active movement", "Flaccidity", "Hypotonia"],
["II", "Synergy begins, spasticity appears", "Minimal finger flexion", "Flexor synergy minimal", "Increasing"],
["III","Full flexor synergy (voluntary)", "Mass grasp possible", "Full flexor/extensor synergy", "Spasticity peak"],
["IV", "Mix of synergy possible", "Lateral pinch, release", "Knee flex in sitting, ankle DF", "Decreasing"],
["V", "Independent of synergy", "Palmar pinch, cylindrical grip", "Isolated knee flex/ext", "Minimal"],
["VI", "Near normal, isolated", "All grips, normal speed","Normal gait pattern", "Normal"],
]
brunn_t = plain_table(brunn_data, [1.2*cm, 4.2*cm, 4*cm, 4*cm, 2.2*cm], bg_header=C_REHAB, fontsize=7)
story.append(brunn_t)
story.append(sp(8))
# ── SECTION 7: MODIFIED ASHWORTH SCALE ───────────────────────────────
story.append(H2("7. MODIFIED ASHWORTH SCALE (MAS) — Spasticity", C_ASSESS))
story.append(sp(4))
mas_data = [
["GRADE", "DESCRIPTION", "CLINICAL FINDING"],
["0", "No increase in muscle tone", "No resistance throughout ROM"],
["1", "Slight increase", "Catch and release at end of ROM"],
["1+", "Slight increase (>half ROM)", "Catch followed by slight resistance <half ROM"],
["2", "Marked increase", "More pronounced but limb easily moved"],
["3", "Considerable increase", "Passive movement difficult"],
["4", "Rigid in flexion/extension", "Limb rigid; passive movement impossible"],
]
mas_t = plain_table(mas_data, [1.5*cm, 5*cm, CONTENT_W-6.5*cm], bg_header=C_ASSESS, fontsize=7.5)
story.append(mas_t)
story.append(sp(8))
# ── SECTION 8: BERG BALANCE SCALE ─────────────────────────────────────
story.append(H2("8. BERG BALANCE SCALE (BBS) — 0–56", C_ASSESS))
story.append(sp(4))
bbs_items = [
["ITEM", "TASK", "SCORE (0-4)"],
["1", "Sitting to standing", "0=needs assist; 4=stands without hands"],
["2", "Standing unsupported", "0=unable 30s; 4=safe 2 min"],
["3", "Sitting unsupported (feet flat)", "0=unable 10s; 4=safe 2 min"],
["4", "Standing to sitting", "0=needs assist; 4=controlled"],
["5", "Transfers (chair to chair)", "0=needs 2 people; 4=safe with minor hand use"],
["6", "Standing with eyes closed", "0=needs help; 4=safe 10s"],
["7", "Standing with feet together", "0=needs help; 4=safe 1 min"],
["8", "Reach forward with arm outstretched","0=loses balance; 4=>25 cm safely"],
["9", "Pick up object from floor", "0=cannot; 4=easily and safely"],
["10", "Turn to look behind", "0=needs assist; 4=looks behind both sides"],
["11", "Turn 360°", "0=needs assist; 4=safely <4s"],
["12", "Stool tapping (alternating feet)", "0=needs assist; 4=8 taps <20s"],
["13", "Tandem standing", "0=loses balance; 4=safe 30s"],
["14", "One-leg standing", "0=cannot; 4=lifts leg independently >10s"],
]
bbs_t = plain_table(bbs_items, [1.2*cm, 5.5*cm, CONTENT_W-6.7*cm], bg_header=C_ASSESS, fontsize=7)
story.append(bbs_t)
story.append(sp(3))
bbs_risk = [
["BBS SCORE", "FALL RISK", "CLINICAL NOTE"],
["0–20", "HIGH", "Wheelchair dependent"],
["21–40", "MODERATE", "Ambulatory with assistance"],
["41–56", "LOW", "Functional balance; MCID = 4–6 points"],
]
bbs_risk_t = plain_table(bbs_risk, [2.5*cm, 3*cm, CONTENT_W-5.5*cm], bg_header=C_ASSESS, fontsize=7.5)
story.append(bbs_risk_t)
story.append(sp(8))
# ── SECTION 9: MODIFIED RANKIN SCALE ─────────────────────────────────
story.append(H2("9. MODIFIED RANKIN SCALE (mRS) — Disability Outcome", C_HEMOR))
story.append(sp(4))
mrs_data = [
["SCORE", "DESCRIPTION", "INDEPENDENCE"],
["0", "No symptoms", "Fully independent"],
["1", "No significant disability", "Able to carry out usual duties; symptoms present"],
["2", "Slight disability", "Unable to carry all previous activities; independent in ADLs"],
["3", "Moderate disability", "Requires some help; walks unassisted"],
["4", "Moderate-severe disability","Unable to walk unassisted; requires help with ADLs"],
["5", "Severe disability", "Bedridden, incontinent, constant nursing care required"],
["6", "Death", "—"],
]
mrs_t = plain_table(mrs_data, [1.5*cm, 5.5*cm, CONTENT_W-7*cm], bg_header=C_HEMOR, fontsize=7.5)
story.append(mrs_t)
story.append(sp(3))
story.append(Paragraph(
"<b>MCID</b> = 1 point | <b>Favourable outcome</b> in trials = mRS ≤2 | "
"<b>Used in</b>: thrombectomy trials (DAWN, DEFUSE-3), thrombolysis (NINDS), TIA follow-up",
sty("mrs_note", fontName="Helvetica", fontSize=7.5, leading=11, textColor=C_DARK)))
story.append(sp(8))
# ── SECTION 10: FUNCTIONAL OUTCOME MEASURES ───────────────────────────
story.append(H2("10. FUNCTIONAL & GAIT OUTCOME MEASURES", C_REHAB))
story.append(sp(4))
func_data = [
["SCALE / TEST", "DOMAIN", "DETAILS / NORMS", "MCID"],
["Barthel Index (BI)", "ADL",
"10 items; 0–100; 0=fully dependent, 100=fully independent. Items: feeding, bathing, grooming, dressing, bladder, bowel, toilet, transfers, mobility, stairs",
"≥10 pts"],
["FIM (Functional Independence Measure)", "ADL + Cognition",
"18 items (motor 13, cognitive 5); 1–7 per item; 18–126; Level 1=total assist; 7=complete independence",
"22 pts"],
["Functional Ambulation Category (FAC)", "Gait",
"0=non-functional; 1=needs physical support; 2=continuous support; 3=intermittent support; 4=supervision; 5=independent (all surfaces)",
"1 level"],
["10-Metre Walk Test (10MWT)", "Gait speed",
"Comfortable pace: community ambulation >0.8 m/s; <0.4 m/s = limited household walker",
"0.10 m/s"],
["6-Minute Walk Test (6MWT)", "Endurance",
"Healthy adults ≈ 400–700m; post-stroke community walkers ≈ 200–400m",
"34–54 m"],
["Timed Up and Go (TUG)", "Mobility/Balance",
"≤10s = normal; 11–20s = mild impairment; >20s = significant impairment/fall risk",
"2.9s"],
["Trunk Impairment Scale (TIS)", "Trunk control",
"3 subscales: static sitting (0-7), dynamic sitting (0-10), coordination (0-6); max 23",
"2 pts"],
["Action Research Arm Test (ARAT)", "UL Function",
"4 subtests: grasp, grip, pinch, gross; 0–57; 0=cannot perform; 3=normal",
"5.7 pts"],
["Stroke-Specific Quality of Life (SS-QOL)", "QOL",
"12 domains, 49 items; 49–245; higher = better quality of life",
"1 pts"],
]
func_t = plain_table(func_data, [3.5*cm, 2.5*cm, 9.5*cm, 1.8*cm], bg_header=C_REHAB, fontsize=7)
story.append(func_t)
story.append(sp(8))
# ── SECTION 11: SPASTICITY & TONE ─────────────────────────────────────
story.append(H2("11. SPASTICITY ASSESSMENT — MODIFIED TARDIEU SCALE (MTS)", C_ASSESS))
story.append(sp(4))
tardieu_text = [
[Paragraph("<b>Components Measured</b>", SMDB := sty("smdb", fontName="Helvetica-Bold", fontSize=7.5, leading=11)),
Paragraph("<b>Quality of Muscle Reaction (R)</b>", SMDB),
Paragraph("<b>Angle of Catch (X)</b>", SMDB)],
[Paragraph("Measured at 2 speeds:<br/>V1 = as slow as possible (no stretch reflex)<br/>V3 = as fast as possible<br/>Angle of catch at V3 minus V1 = Spasticity angle (dynamic component)", SMALL),
Paragraph("0 = No resistance<br/>1 = Slight resistance, no catch<br/>2 = Clear catch, releases<br/>3 = Fatigable clonus <10s<br/>4 = Non-fatigable clonus ≥10s<br/>5 = Immovable", SMALL),
Paragraph("R1 = Angle of catch at fast speed<br/>R2 = ROM at slow speed<br/>Spasticity angle = R2 – R1<br/>>10° = significant spasticity<br/>Preferred over MAS for dynamic spasticity", SMALL)],
]
trd_t = Table(tardieu_text,
colWidths=[CONTENT_W/3, CONTENT_W/3, CONTENT_W/3],
style=TableStyle([
("BACKGROUND",(0,0),(-1,0), C_ASSESS),
("BACKGROUND",(0,1),(-1,1), colors.HexColor("#FFF3E0")),
("TEXTCOLOR",(0,0),(-1,0), C_WHITE),
("GRID",(0,0),(-1,-1),0.4,colors.HexColor("#BDBDBD")),
("TOPPADDING",(0,0),(-1,-1),4),
("BOTTOMPADDING",(0,0),(-1,-1),4),
("LEFTPADDING",(0,0),(-1,-1),6),
("VALIGN",(0,0),(-1,-1),"TOP"),
]))
story.append(trd_t)
story.append(sp(8))
# ── SECTION 12: HUNT-HESS + FISHER ────────────────────────────────────
story.append(H2("12. SAH GRADING SCALES", C_SAH))
story.append(sp(4))
col_left = CONTENT_W * 0.48
col_right = CONTENT_W * 0.48
gap = CONTENT_W * 0.04
hh_data = [
["HUNT-HESS GRADE", "CLINICAL DESCRIPTION", "30-DAY MORTALITY"],
["I", "Asymptomatic or mild headache, slight nuchal rigidity", "~30%"],
["II", "Moderate-severe HA, nuchal rigidity, no neuro deficit (except CN palsy)", "~40%"],
["III", "Drowsiness, confusion, mild focal deficit", "~50%"],
["IV", "Stupor, moderate-severe hemiparesis, early decerebrate", "~80%"],
["V", "Deep coma, decerebrate posturing, moribund", "~90%"],
]
hh_t = plain_table(hh_data, [2*cm, col_left-4*cm, 2.8*cm], bg_header=C_SAH, fontsize=7)
fisher_data = [
["FISHER GRADE", "CT FINDING", "VASOSPASM RISK"],
["1", "No blood detected", "Low"],
["2", "Diffuse thin SAH (<1mm)", "Low"],
["3", "Localized clot/thick layer (>1mm)", "HIGH (most predictive)"],
["4", "ICH or IVH with diffuse or no subarachnoid", "Moderate"],
["MODIFIED FISHER", "Grade 3: diffuse thick SAH + IVH = highest vasospasm risk", ""],
]
fish_t = plain_table(fisher_data, [2.5*cm, col_right-5*cm, 2.5*cm], bg_header=C_SAH, fontsize=7)
sah_row = Table([[hh_t, Spacer(gap, 1), fish_t]],
colWidths=[col_left, gap, col_right],
style=TableStyle([("VALIGN",(0,0),(-1,-1),"TOP")]))
story.append(sah_row)
story.append(sp(8))
# ── SECTION 13: ICH SCORE ─────────────────────────────────────────────
story.append(H2("13. ICH SCORE — Intracerebral Hemorrhage Severity", C_HEMOR))
story.append(sp(4))
ich_data = [
["COMPONENT", "CRITERIA", "POINTS"],
["GCS", "3–4", "2"],
["", "5–12", "1"],
["", "13–15", "0"],
["ICH Volume", "≥30 mL", "1"],
["", "<30 mL", "0"],
["Intraventricular Hemorrhage", "Yes", "1"],
["", "No", "0"],
["Infratentorial origin","Yes", "1"],
["", "No", "0"],
["Age", "≥80 years", "1"],
["", "<80 years", "0"],
["TOTAL", "", "0–6"],
]
ich_score_t = plain_table(ich_data, [5*cm, 4*cm, 2*cm], bg_header=C_HEMOR, fontsize=7.5)
ich_mort = [
["ICH SCORE", "30-DAY MORTALITY"],
["0", "0%"],
["1", "13%"],
["2", "26%"],
["3", "72%"],
["4", "97%"],
["5–6", "~100%"],
]
ich_mort_t = plain_table(ich_mort, [3.5*cm, CONTENT_W-11*cm], bg_header=C_HEMOR, fontsize=7.5)
ich_row = Table([[ich_score_t, Spacer(0.4*cm, 1), ich_mort_t]],
colWidths=[11*cm, 0.4*cm, CONTENT_W-11.4*cm],
style=TableStyle([("VALIGN",(0,0),(-1,-1),"TOP")]))
story.append(ich_row)
story.append(sp(8))
# ── SECTION 14: COGNITIVE / DEPRESSION ────────────────────────────────
story.append(H2("14. COGNITIVE & DEPRESSION SCREENING", colors.HexColor("#4527A0")))
story.append(sp(4))
cog_data = [
["SCALE", "WHAT IT MEASURES", "ITEMS/RANGE", "CUTOFF / NOTES"],
["MMSE (Mini-Mental State Exam)", "Global cognition", "30 items; 0–30", "<24 = cognitive impairment; takes ~10 min; insensitive to mild deficits"],
["MoCA (Montreal Cognitive Assessment)", "Mild cognitive impairment", "30 items; 0–30", "<26 = MCI; preferred over MMSE in post-stroke; tests executive function"],
["PHQ-9 (Patient Health Questionnaire)", "Post-stroke depression", "9 items; 0–27", "0–4 minimal; 5–9 mild; 10–14 moderate; 15+ severe depression"],
["HDRS (Hamilton Depression Rating)", "Depression severity", "17 items; 0–52", "<7 normal; 8–13 mild; 14–18 moderate; ≥19 severe"],
["MMSE Orientation (post-stroke)", "Orientation to time/place", "10 pts subtest", "Often impaired early; key for legal capacity assessment"],
]
cog_t = plain_table(cog_data, [3.5*cm, 3.5*cm, 3*cm, CONTENT_W-10*cm], bg_header=colors.HexColor("#4527A0"), fontsize=7)
story.append(cog_t)
story.append(sp(8))
# ── SECTION 15: DYSPHAGIA ─────────────────────────────────────────────
story.append(H2("15. DYSPHAGIA ASSESSMENT IN STROKE", C_ASSESS))
story.append(sp(4))
dys_data = [
["TOOL", "TYPE", "KEY DETAILS"],
["Bedside Swallow Assessment (BSA)", "Screening", "Water swallow test; 10-20 mL bolus; observe drooling, coughing, voice change"],
["MASA (Mann Assessment Swallowing Ability)", "Clinical", "24 items; 0–200; <178 = dysphagia; <170 = aspiration risk"],
["FEES (Flexible Endoscopic Evaluation of Swallowing)", "Gold standard", "Direct visualization; identifies silent aspiration; conducted by SLT"],
["MBSS/Videofluoroscopy", "Radiological", "Modified Barium Swallow; evaluates all phases; gold standard for oral/pharyngeal phases"],
["Dysphagia Outcome Severity Scale (DOSS)", "Outcome", "7-point scale: 1=nothing by mouth; 7=normal in all situations"],
["Functional Oral Intake Scale (FOIS)", "Outcome", "7 levels: 1=tube feeding only; 7=total oral intake, no restrictions"],
]
dys_t = plain_table(dys_data, [4*cm, 3*cm, CONTENT_W-7*cm], bg_header=C_ASSESS, fontsize=7.2)
story.append(dys_t)
story.append(sp(8))
# ── SECTION 16: SHOULDER PAIN / UPPER LIMB ───────────────────────────
story.append(H2("16. UPPER LIMB & SHOULDER SPECIFIC TOOLS", C_REHAB))
story.append(sp(4))
ul_data = [
["TOOL", "MEASURES", "RANGE / CUTOFF"],
["Box & Block Test (BBT)", "Manual dexterity, unilateral gross motor", "Count blocks transferred in 60s; norm >50; MCID = 5.5 blocks"],
["Grip Strength (Dynamometer)", "Hand grip force", "% difference unaffected vs. affected; MCID = 2.9 kg"],
["Chedoke McMaster Stroke Assessment", "Motor recovery (impairment + activity)", "7-point scale per stage; 6 sections; correlates with Brunnstrom"],
["Shoulder Pain and Disability Index (SPADI)", "Shoulder pain + disability", "0–100; 0=no disability; MCID = 13 pts; VAS + 13 items"],
["Visual Analogue Scale (VAS)", "Pain intensity", "0–10 cm line; MCID = 1.5 cm; simple, widely used"],
["Numeric Rating Scale (NRS)", "Pain intensity", "0–10; 0=no pain; 10=worst imaginable; MCID = 2 pts"],
["Wolf Motor Function Test (WMFT)", "UL function speed + quality (post-CIMT)", "17 timed tasks; functional ability scale 0-5 per task"],
]
ul_t = plain_table(ul_data, [4*cm, 4*cm, CONTENT_W-8*cm], bg_header=C_REHAB, fontsize=7.2)
story.append(ul_t)
story.append(sp(8))
# ── SECTION 17: IMAGING QUICK REF ─────────────────────────────────────
story.append(H2("17. NEUROIMAGING QUICK REFERENCE", C_HEADER))
story.append(sp(4))
img_data = [
["MODALITY", "FINDING IN STROKE", "USE / TIMING"],
["Non-contrast CT (NCCT)", "Ischemic: normal <6h; hypodensity 24-48h; hyperdense artery sign. ICH: hyperdense 40-100HU. SAH: blood in cisterns", "First-line; excludes hemorrhage; done within 25 min of arrival"],
["CT Angiography (CTA)", "LVO identification; aneurysm; dissection; stenosis", "Immediate if LVO suspected; guides thrombectomy decision"],
["CT Perfusion (CTP)", "Core (CBF<30%) vs. penumbra (Tmax>6s) mismatch", "Extends thrombectomy window to 24h (DAWN/DEFUSE-3)"],
["MRI DWI", "Bright on DWI + dark on ADC = acute ischemia (within minutes)", "Most sensitive for early ischemia; gold standard"],
["MRI FLAIR", "Bright lesion = infarct older than 4.5h (DWI+/FLAIR- = wake-up stroke)", "FLAIR-DWI mismatch guides late-window tPA"],
["MRA", "Non-invasive vessel imaging; stenosis, aneurysm, dissection", "Pre-discharge in TIA; planning revascularization"],
["ASPECTS Score", "10-point CT scoring of MCA territory; ≤6 = large infarct", "Thrombectomy: ASPECTS ≥6 favored; some trials accept ≥3"],
["DSA (angiography)", "Gold standard for aneurysm, AVM, vasculitis", "Pre-clipping/coiling for SAH; definitivevessel imaging"],
]
img_t = plain_table(img_data, [3.2*cm, 6.5*cm, CONTENT_W-9.7*cm], bg_header=C_HEADER, fontsize=7)
story.append(img_t)
story.append(sp(8))
# ── SECTION 18: THROMBOLYSIS ELIGIBILITY ─────────────────────────────
story.append(H2("18. IV tPA (ALTEPLASE) — ELIGIBILITY CHECKLIST", C_ISCHEMIC))
story.append(sp(4))
incl_rows = [
["INCLUSION CRITERIA", "EXCLUSION CRITERIA (ABSOLUTE)"],
["Ischemic stroke with measurable neurological deficit",
"Any prior intracranial hemorrhage"],
["Onset of symptoms ≤4.5 hours (tissue damage threshold)",
"CT showing multilobar infarction (hypodensity >1/3 MCA territory)"],
["Age ≥18 years",
"Active internal bleeding (excluding menses)"],
["BP <185/110 after treatment (if needed)",
"SBP >185 or DBP >110 (refractory to treatment)"],
["Blood glucose 50–400 mg/dL",
"Platelets <100,000; INR >1.7; aPTT >40s; PT >15s"],
["Disabling neurological deficit",
"Major surgery or serious trauma within 14 days"],
["",
"Recent intracranial/spinal surgery, head trauma (<3 months)"],
["DOSE: Alteplase 0.9 mg/kg (max 90mg)", "10% IV bolus + 90% over 60 min"],
]
incl_t = Table(
[[Paragraph(row[0], sty(f"il{i}0", fontName="Helvetica" if i>0 else "Helvetica-Bold",
fontSize=7.5, leading=11,
textColor=C_WHITE if i==0 else (colors.HexColor("#1A237E") if row[0] else C_DARK)))
for j, cell in enumerate(row)
for row in [row]] for i, row in enumerate(incl_rows)],
colWidths=[CONTENT_W/2 - 0.2*cm, CONTENT_W/2 - 0.2*cm],
style=TableStyle([
("BACKGROUND",(0,0),(-1,0), C_ISCHEMIC),
("TEXTCOLOR",(0,0),(-1,0), C_WHITE),
("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"),
("FONTSIZE",(0,0),(-1,-1),7.5),
("LEADING",(0,0),(-1,-1),11),
("GRID",(0,0),(-1,-1),0.4,colors.HexColor("#BDBDBD")),
("VALIGN",(0,0),(-1,-1),"TOP"),
("TOPPADDING",(0,0),(-1,-1),3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1),5),
("BACKGROUND",(0,-1),(-1,-1), C_LIGHT1),
("FONTNAME",(0,-1),(-1,-1),"Helvetica-Bold"),
("ROWBACKGROUNDS",(0,1),(-1,-2),[C_WHITE, C_ROW_ALT]),
])
)
# Rebuild as simpler table
rows_incl = []
for i, row in enumerate(incl_rows):
c1 = Paragraph(row[0], sty(f"i1{i}", fontName="Helvetica-Bold" if i==0 or i==len(incl_rows)-1 else "Helvetica",
fontSize=7.5, leading=11, textColor=C_WHITE if i==0 else C_DARK))
c2 = Paragraph(row[1], sty(f"i2{i}", fontName="Helvetica-Bold" if i==0 else "Helvetica",
fontSize=7.5, leading=11, textColor=C_WHITE if i==0 else C_DARK))
rows_incl.append([c1, c2])
incl_final = Table(rows_incl,
colWidths=[CONTENT_W/2 - 0.1*cm, CONTENT_W/2 - 0.1*cm],
style=TableStyle([
("BACKGROUND",(0,0),(-1,0), C_ISCHEMIC),
("BACKGROUND",(0,-1),(-1,-1), C_LIGHT1),
("GRID",(0,0),(-1,-1),0.4,colors.HexColor("#BDBDBD")),
("VALIGN",(0,0),(-1,-1),"TOP"),
("TOPPADDING",(0,0),(-1,-1),3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1),5),
("ROWBACKGROUNDS",(0,1),(-1,-2),[C_WHITE, C_ROW_ALT]),
("FONTNAME",(0,-1),(-1,-1),"Helvetica-Bold"),
("TEXTCOLOR",(0,-1),(-1,-1), C_ISCHEMIC),
]))
story.append(incl_final)
story.append(sp(8))
# ── SECTION 19: RECENT ADVANCES BOX ───────────────────────────────────
story.append(H2("19. RECENT ADVANCES IN STROKE REHABILITATION (2023–2026)", C_REHAB))
story.append(sp(4))
adv_data = [
["ADVANCE", "EVIDENCE / KEY POINTS"],
["Robot-Assisted Therapy (RAT)",
"Cochrane SR 2025 (PMID 39932103): RAT improves UL function + gait vs. conventional therapy. High-intensity repetitive training drives neuroplasticity. Devices: Lokomat (gait), Armeo/Myomo (UL)."],
["Virtual Reality (VR)",
"Cochrane SR 2025 (PMID 40537150): VR improves arm function, balance & gait in chronic stroke. Clinically meaningful gains on FMA. Enhanced engagement via immersive feedback. Best combined with RAT."],
["Non-Invasive Brain Stimulation (NIBS)",
"rTMS (high-frequency ipsilesional M1 or inhibitory contralesional M1) + tDCS (anodal over ipsilesional motor cortex). Meta-analysis 2023 (PMID 38082316): tDCS improves post-stroke dysphagia."],
["Tenecteplase (TNK)",
"Single IV bolus thrombolytic; non-inferior to alteplase in multiple trials. Simpler logistics; longer half-life. Now endorsed in AHA guidelines as acceptable alternative."],
["Extended Thrombectomy Window (up to 24h)",
"DAWN trial (6–24h, clinical-imaging mismatch) + DEFUSE-3 (6–16h, perfusion mismatch): thrombectomy beneficial well beyond 6h in selected patients. CT perfusion guides selection."],
["Remote Ischemic Conditioning (RIC)",
"SR 2024 (PMID 38457772): limb ischemia/reperfusion cycles (4×5 min cuff inflation) reduce infarct size. Benefit greatest when combined with reperfusion therapy."],
["Brain-Computer Interface (BCI)",
"EEG motor imagery → robotic hand movement feedback → reinforces neuroplasticity. FDA-cleared devices emerging (e.g. IpsiHand). Motor intention training without physical movement."],
["Functional Electrical Stimulation (FES)",
"Stimulates peripheral nerves to produce functional movement. Bioness H200 (hand opening), L300 (foot drop correction). Can be EMG-triggered (neuroprosthetic approach)."],
["AI-Assisted Imaging",
"Automated ASPECTS scoring, LVO detection on CTA, perfusion analysis (RapidAI). Reduces door-to-needle time. Identifies mismatch for extended window thrombectomy."],
["2025 ESO BP Guidelines (PMID 42095756)",
"Updated ESO 2026 targets: acute ischemic stroke pre-thrombolysis <185/110; ICH with SBP 150–220 → target 140 mmHg; avoidance of aggressive lowering in non-thrombolysis candidates."],
]
adv_t = plain_table(adv_data, [4*cm, CONTENT_W-4*cm], bg_header=C_REHAB, fontsize=7.2)
story.append(adv_t)
story.append(sp(8))
# ── FOOTER NOTE ───────────────────────────────────────────────────────
footer_style = sty("footer", fontName="Helvetica-Oblique", fontSize=6.5, leading=9,
textColor=colors.grey, alignment=TA_CENTER)
story.append(HRFlowable(width="100%", thickness=0.5, color=C_HEADER))
story.append(sp(3))
story.append(Paragraph(
"Sources: Bradley & Daroff's Neurology in Clinical Practice | Tintinalli's Emergency Medicine | "
"ROSEN's Emergency Medicine | Frameworks for Internal Medicine | "
"Cochrane Database Syst Rev 2025 (PMID 39932103, 40537150) | "
"ESO Guidelines 2026 (PMID 42095756) | Remote Ischemic Conditioning SR 2024 (PMID 38457772)",
footer_style
))
story.append(sp(2))
story.append(Paragraph(
"Orris Medical — Stroke Quick Reference Guide | MPT Exam Preparation | June 2026",
footer_style
))
# ── BUILD PDF ─────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF created: {OUTPUT}")
cd /home/daytona/workspace/stroke-ref-guide && python3 make_pdf.py 2>&1
~/stroke-ref-guide/make_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/stroke-ref-guide/make_pdf.py'
cd /home/daytona/workspace/stroke-ref-guide && python3 make_pdf.py 2>&1
cd /home/daytona/workspace/stroke-ref-guide && python3 -c " from reportlab.platypus import Paragraph from reportlab.lib.styles import ParagraphStyle from reportlab.lib.colors import black sty = lambda n, **kw: ParagraphStyle(n, **kw) BASE = sty('base', fontName='Helvetica', fontSize=8, leading=11, textColor=black) mas_data = [ ['GRADE', 'DESCRIPTION', 'CLINICAL FINDING'], ['0', 'No increase in muscle tone', 'No resistance throughout ROM'], ['1', 'Slight increase', 'Catch and release at end of ROM'], ['1+', 'Slight increase (>half ROM)', 'Catch followed by slight resistance <half ROM'], ['2', 'Marked increase', 'More pronounced but limb easily moved'], ['3', 'Considerable increase', 'Passive movement difficult'], ['4', 'Rigid in flexion/extension', 'Limb rigid; passive movement impossible'], ] for i, row in enumerate(mas_data): for j, c in enumerate(row): try: p = Paragraph(str(c), BASE) except Exception as e: print(f'Error at row {i} col {j}: repr={repr(c)}') print(e) print('done') " 2>&1
~/stroke-ref-guide/make_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/stroke-ref-guide/make_pdf.py'
~/stroke-ref-guide/make_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/stroke-ref-guide/make_pdf.py'
cd /home/daytona/workspace/stroke-ref-guide && python3 make_pdf.py 2>&1
~/stroke-ref-guide/make_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/stroke-ref-guide/make_pdf.py'
~/stroke-ref-guide/make_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/stroke-ref-guide/make_pdf.py'
~/stroke-ref-guide/make_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/stroke-ref-guide/make_pdf.py'
cd /home/daytona/workspace/stroke-ref-guide && python3 make_pdf.py 2>&1
cd /home/daytona/workspace/stroke-ref-guide && python3 -c " # Find which table has negative width by adding a try/except wrapper import reportlab from reportlab.lib.pagesizes import A4 W, H = A4 from reportlab.lib.units import cm CONTENT_W = W - 2.8*cm print('CONTENT_W =', CONTENT_W) # Check SAH row widths col_left = CONTENT_W * 0.48 col_right = CONTENT_W * 0.48 gap = CONTENT_W * 0.04 print('sah_row total:', col_left + gap + col_right, 'vs', CONTENT_W) # HH table hh_cols = [2*cm, col_left-4*cm, 2.8*cm] print('hh_cols sum:', sum(hh_cols), 'vs col_left:', col_left) " 2>&1
~/stroke-ref-guide/make_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/stroke-ref-guide/make_pdf.py'
~/stroke-ref-guide/make_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/stroke-ref-guide/make_pdf.py'