Hyperkinetic movement disorders
"hyperkinetic movement disorders" classification management
"movement disorders" chorea dystonia tremor
For postgraduate theory exam answer in pdf format
mkdir -p /home/daytona/workspace/hyperkinetic-movements && ls /home/daytona/work…
~/hyperkinetic-movements/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.platypus import ListFlowable, ListItem
OUTPUT = "/home/daytona/workspace/hyperkinetic-movements/Hyperkinetic_Movement_Disorders_PG.pdf"
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=2*cm, leftMargin=2*cm,
topMargin=2.2*cm, bottomMargin=2*cm,
title="Hyperkinetic Movement Disorders – PG Theory Answer",
author="Orris Medical"
)
W = A4[0] - 4*cm # usable width
# ── Styles ──────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def sty(name, parent="Normal", **kw):
s = ParagraphStyle(name, parent=styles[parent], **kw)
return s
TITLE = sty("TITLE", fontSize=17, leading=22, textColor=colors.HexColor("#1a237e"),
alignment=TA_CENTER, spaceAfter=4, fontName="Helvetica-Bold")
SUB = sty("SUB", fontSize=11, leading=14, textColor=colors.HexColor("#1565c0"),
alignment=TA_CENTER, spaceAfter=2, fontName="Helvetica-Oblique")
H1 = sty("H1", fontSize=13, leading=16, textColor=colors.white,
fontName="Helvetica-Bold", spaceAfter=4, spaceBefore=10,
leftIndent=0, backColor=colors.HexColor("#1a237e"),
borderPad=4)
H2 = sty("H2", fontSize=11, leading=14, textColor=colors.HexColor("#1a237e"),
fontName="Helvetica-Bold", spaceBefore=8, spaceAfter=3,
borderPad=2)
H3 = sty("H3", fontSize=10, leading=13, textColor=colors.HexColor("#0d47a1"),
fontName="Helvetica-Bold", spaceBefore=6, spaceAfter=2)
BODY = sty("BODY", fontSize=9.5, leading=14, alignment=TA_JUSTIFY,
spaceAfter=5)
BULLET = sty("BULLET", fontSize=9.5, leading=13, leftIndent=14, firstLineIndent=-10,
spaceAfter=3)
NBULLET = sty("NBULLET", fontSize=9.5, leading=13, leftIndent=24, firstLineIndent=-10,
spaceAfter=2)
CAPTION = sty("CAPTION", fontSize=8.5, leading=11, textColor=colors.HexColor("#555555"),
alignment=TA_CENTER, spaceAfter=4, fontName="Helvetica-Oblique")
FOOTER = sty("FOOTER", fontSize=8, textColor=colors.HexColor("#777777"),
alignment=TA_CENTER)
EMPH = sty("EMPH", fontSize=9.5, leading=13, textColor=colors.HexColor("#b71c1c"),
fontName="Helvetica-Bold", spaceAfter=3)
def h1(text): return Paragraph(f" {text}", H1)
def h2(text): return Paragraph(text, H2)
def h3(text): return Paragraph(text, H3)
def p(text): return Paragraph(text, BODY)
def b(text): return Paragraph(f"• {text}", BULLET)
def nb(text): return Paragraph(f"– {text}", NBULLET)
def sp(n=6): return Spacer(1, n)
def hr(): return HRFlowable(width="100%", thickness=0.5,
color=colors.HexColor("#1a237e"), spaceAfter=4)
def hr2(): return HRFlowable(width="100%", thickness=0.3,
color=colors.HexColor("#bbbbbb"), spaceAfter=3)
# ── Table helper ─────────────────────────────────────────────────────────────
def make_table(data, col_widths=None, header=True):
if col_widths is None:
col_widths = [W / len(data[0])] * len(data[0])
cell_style = ParagraphStyle("cell", fontSize=9, leading=12, spaceAfter=0)
hdr_style = ParagraphStyle("hdr", fontSize=9, leading=12, fontName="Helvetica-Bold",
textColor=colors.white, spaceAfter=0)
table_data = []
for r_i, row in enumerate(data):
styled_row = []
for c_i, cell in enumerate(row):
s = hdr_style if (header and r_i == 0) else cell_style
styled_row.append(Paragraph(str(cell), s))
table_data.append(styled_row)
t = Table(table_data, colWidths=col_widths, repeatRows=1 if header else 0)
cmd = [
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#1a237e")),
("ROWBACKGROUNDS",(0,1),(-1,-1), [colors.HexColor("#e8eaf6"), colors.white]),
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#bbbbbb")),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING",(0,0), (-1,-1), 5),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
]
if not header:
cmd[0] = ("BACKGROUND",(0,0),(-1,-1), colors.white)
cmd[1] = ("ROWBACKGROUNDS",(0,0),(-1,-1),[colors.HexColor("#e8eaf6"), colors.white])
t.setStyle(TableStyle(cmd))
return t
# ══════════════════════════════════════════════════════════════════════════════
# CONTENT
# ══════════════════════════════════════════════════════════════════════════════
story = []
# ── Title block ──────────────────────────────────────────────────────────────
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("HYPERKINETIC MOVEMENT DISORDERS", TITLE))
story.append(Paragraph("Postgraduate Theory Examination Answer", SUB))
story.append(hr())
story.append(Paragraph(
"<i>Sources: Bradley & Daroff's Neurology in Clinical Practice · Adams & Victor's Principles of Neurology 12e · "
"Harrison's Principles of Internal Medicine 22e · Neuroanatomy through Clinical Cases 3e · "
"Goodman & Gilman's Pharmacological Basis of Therapeutics</i>", CAPTION))
story.append(sp(4))
# ── 1. INTRODUCTION ──────────────────────────────────────────────────────────
story.append(h1("1. INTRODUCTION AND CLASSIFICATION"))
story.append(p(
"Movement disorders are neurological syndromes in which there is either an excess of movement "
"(<b>hyperkinesia</b>) or a paucity/slowness of movement (<b>hypokinesia</b>). Hyperkinetic "
"movement disorders are characterised by abnormal involuntary movements that are excessive in "
"quantity, amplitude, or speed. They arise primarily from dysfunction of the <b>basal ganglia "
"and their connections</b> with the thalamus and cortex."
))
story.append(sp(4))
# Classification table
story.append(h2("Classification of Hyperkinetic Movement Disorders"))
classif = [
["Disorder", "Key Feature", "Speed", "Rhythmicity", "Suppressibility"],
["Tremor", "Rhythmic oscillation", "Varies", "Yes", "Partial"],
["Chorea", "Random, flowing, dance-like jerks", "Fast", "No", "Partial"],
["Athetosis", "Slow, writhing, distal movements", "Slow", "No", "Partial"],
["Ballism", "Flinging, proximal, violent", "Fast", "No", "No"],
["Dystonia", "Sustained twisting contractions", "Variable", "No", "Partial (trick)"],
["Myoclonus", "Sudden, shock-like jerks", "Very fast","No", "No"],
["Tics", "Stereotyped, semi-voluntary", "Variable", "No", "Yes (temporarily)"],
["Akathisia", "Inner restlessness, urge to move", "Variable", "No", "Partial"],
]
story.append(make_table(classif, col_widths=[2.8*cm, 4.5*cm, 2.0*cm, 2.3*cm, 2.4*cm]))
story.append(sp(8))
# ── 2. PATHOPHYSIOLOGY ───────────────────────────────────────────────────────
story.append(h1("2. PATHOPHYSIOLOGY – BASAL GANGLIA CIRCUITS"))
story.append(p(
"The basal ganglia exert tonic inhibition over the thalamus via the <b>internal segment of the "
"globus pallidus (GPi)</b> and the <b>substantia nigra pars reticulata (SNpr)</b>. Two competing "
"striato-pallidal pathways modulate this inhibition:"
))
story.append(b("<b>Direct pathway</b> (D1-receptor mediated): Striatum → GPi/SNpr (inhibitory). "
"Net effect: <i>disinhibition</i> of thalamus → facilitates movement."))
story.append(b("<b>Indirect pathway</b> (D2-receptor mediated): Striatum → GPe → STN → GPi/SNpr. "
"Net effect: <i>increased</i> GPi output → inhibits thalamus → suppresses movement."))
story.append(p(
"<b>Hyperkinetic states</b> result from <b>reduced GPi output</b> → <i>excessive</i> "
"thalamocortical excitation:"
))
story.append(b("Subthalamic nucleus (STN) lesion (e.g., hemiballismus): Loss of STN excitation of "
"GPi → decreased inhibition of thalamus → violent involuntary movement."))
story.append(b("Early Huntington disease: Preferential loss of indirect-pathway neurons (enkephalin-positive) "
"→ GPe disinhibited → STN inhibited → GPi output reduced → chorea."))
story.append(b("Advanced Huntington disease: Both pathways degenerate → rigid, hypokinetic state."))
story.append(p(
"Dopamine has <b>excitatory effects</b> on D1 (direct) striatal neurons and "
"<b>inhibitory effects</b> on D2 (indirect) neurons; thus dopamine normally facilitates "
"movement. Excess dopaminergic drive (L-dopa dyskinesias, cocaine) produces choreiform "
"hyperkinesia through the same final common pathway."
))
story.append(sp(8))
# ── 3. INDIVIDUAL DISORDERS ──────────────────────────────────────────────────
story.append(h1("3. INDIVIDUAL HYPERKINETIC MOVEMENT DISORDERS"))
# 3A TREMOR
story.append(h2("A. TREMOR"))
story.append(p(
"Tremor is the <b>rhythmic oscillation</b> of a body part, produced by alternating or "
"synchronous contractions of reciprocally innervated antagonistic muscles. It is the most "
"<i>common</i> hyperkinetic movement disorder. Classification is by clinical context "
"(Bhatia et al., 2018 – IPMDS Consensus):"
))
tremor_data = [
["Type", "Characteristics", "Common Cause", "Frequency"],
["Rest tremor", "Present at rest, disappears with action; pill-rolling",
"Parkinson's disease", "3–6 Hz"],
["Postural tremor", "Elicited by holding limb against gravity", "Essential tremor, physiological", "6–12 Hz"],
["Kinetic/Action tremor","Present throughout voluntary movement", "Cerebellar disease", "3–5 Hz"],
["Intention tremor", "Worsens approaching target; terminal tremor", "Cerebellar outflow", "3–5 Hz"],
["Dystonic tremor", "Irregular, jerky; occurs in body part with dystonia; has a null point",
"Cervical dystonia", "4–7 Hz"],
["Task-specific", "Only during specific tasks", "Writer's tremor", "Variable"],
]
story.append(make_table(tremor_data, col_widths=[2.8*cm, 5.2*cm, 3.5*cm, 2.5*cm]))
story.append(sp(4))
story.append(h3("Key differentials: Parkinson's tremor vs Essential tremor"))
diff_data = [
["Feature", "Parkinson's Rest Tremor", "Essential Tremor"],
["Type", "Rest (pill-rolling)", "Postural/kinetic"],
["Frequency", "3–6 Hz", "6–12 Hz"],
["Head tremor", "Rare (jaw/lips instead)", "Common (yes/no nodding)"],
["Laterality", "Unilateral onset", "Bilateral, symmetric"],
["Alcohol", "No effect", "Temporarily improves"],
["Family history", "Less common", "Common (50% autosomal dominant)"],
["Associated features","Rigidity, bradykinesia, micrographia", "None typically"],
]
story.append(make_table(diff_data, col_widths=[3.2*cm, 4.9*cm, 4.9*cm]))
story.append(sp(4))
story.append(h3("Treatment of Tremor"))
story.append(b("<b>Essential tremor:</b> First-line – propranolol (40–320 mg/day) or primidone (250–750 mg/day); "
"Second-line – topiramate, gabapentin, alprazolam; DBS (thalamic VIM nucleus) for refractory cases."))
story.append(b("<b>Parkinsonian tremor:</b> Levodopa/carbidopa, dopamine agonists; anticholinergics (trihexyphenidyl) "
"for tremor-predominant PD; DBS (STN or GPi)."))
story.append(b("<b>Intention tremor:</b> Difficult to treat; isoniazid, clonazepam, weights; DBS (VIM)."))
story.append(sp(8))
# 3B CHOREA
story.append(h2("B. CHOREA and ATHETOSIS"))
story.append(p(
"From Greek <i>choreia</i> (\"dance\"). Chorea consists of <b>irregular, unpredictable, brief, "
"jerky movements</b> that flow randomly from one body part to another. Movements are purposeless "
"but may be incorporated into voluntary acts (parakinesia). Associated features include:"
))
story.append(b("Motor impersistence – inability to sustain tongue protrusion (trombone tongue)"))
story.append(b("Pendular reflexes – due to hypotonia"))
story.append(b("Milkmaid's grip – inability to maintain constant hand grip"))
story.append(sp(3))
story.append(p("<b>Athetosis</b> describes <i>slow</i> chorea; typically seen in cerebral palsy. The combined pattern "
"is called <b>choreoathetosis</b>."))
story.append(sp(4))
story.append(h3("Aetiology of Chorea"))
etiol_data = [
["Category", "Causes"],
["Inherited/Genetic", "Huntington disease (HTT gene CAG repeat, chr 4p); Benign hereditary chorea (NKX2-1 mutation); "
"Neuroacanthocytosis; Dentatorubropallidoluysian atrophy (DRPLA); Wilson disease"],
["Immune-mediated", "Sydenham chorea (post-streptococcal, anti-basal ganglia antibodies); Chorea gravidarum; "
"SLE; Antiphospholipid antibody syndrome; Paraneoplastic (anti-Hu, anti-CRMP)"],
["Drug-induced", "Neuroleptics (tardive dyskinesia); Levodopa excess; Oral contraceptives; "
"Phenytoin; Cocaine; Metoclopramide"],
["Metabolic/Systemic","Thyrotoxicosis; Polycythaemia vera; Hyperosmolar non-ketotic hyperglycaemia; "
"Toxoplasmosis in AIDS"],
["Structural/Vascular","Stroke; Tumour; Vascular malformation (hemichorea/hemiballismus)"],
]
story.append(make_table(etiol_data, col_widths=[3.5*cm, 10.5*cm]))
story.append(sp(4))
story.append(h3("Huntington Disease – Key Points"))
story.append(b("Autosomal dominant; unstable CAG repeat expansion (>36 repeats) in <i>HTT</i> gene on chromosome 4p16.3."))
story.append(b("Triad: Chorea + Dementia + Psychiatric disturbance (depression, irritability, psychosis)."))
story.append(b("Juvenile form (Westphal variant): Rigid, akinetic; presents before age 20."))
story.append(b("Anticipation: earlier onset and more severe disease in successive generations."))
story.append(b("Pathology: Loss of GABAergic striatal neurons (caudate and putamen); indirect pathway first."))
story.append(sp(4))
story.append(h3("Treatment of Chorea"))
story.append(b("<b>Tetrabenazine</b> (VMAT2 inhibitor) – FDA-approved for Huntington chorea; depletes dopamine in presynaptic terminals; "
"risk of depression/suicidality."))
story.append(b("<b>Deutetrabenazine / Valbenazine</b> – newer VMAT2 inhibitors with better tolerability."))
story.append(b("Dopamine receptor blockers: haloperidol, fluphenazine, olanzapine (use cautiously)."))
story.append(b("Sydenham chorea: penicillin prophylaxis; sodium valproate or carbamazepine for movements."))
story.append(b("Chorea gravidarum: usually self-limiting; haloperidol if severe."))
story.append(sp(8))
# 3C BALLISM
story.append(h2("C. BALLISM / HEMIBALLISMUS"))
story.append(p(
"Ballism consists of <b>violent, flinging, large-amplitude movements</b> of the proximal limbs. "
"When unilateral it is called <b>hemiballismus</b> (most common form); monoballismus (one limb), "
"biballismus (both sides), and paraballismus (both legs) are rare variants."
))
story.append(b("<b>Pathophysiology:</b> Lesion of the contralateral <b>subthalamic nucleus (STN)</b> "
"or its connections with the pallidum. STN normally excites GPi; its loss → reduced GPi output "
"→ disinhibition of thalamus → violent involuntary movement."))
story.append(b("<b>Most common cause:</b> Lacunar infarct of STN (hypertension, diabetes). "
"Other causes: haemorrhage, tumour, MS plaque, hyperglycaemic non-ketotic state, "
"abscess, AVM, phenytoin, dopamine agonists."))
story.append(b("<b>Clinical features:</b> Sudden onset; self-injurious flinging movements; patient exhibits "
"multiple bruises/abrasions; may resolve spontaneously over weeks."))
story.append(b("<b>Treatment:</b> Dopamine-depleting agents (tetrabenazine) or D2 blockers (haloperidol); "
"treat underlying cause; DBS/pallidotomy for refractory cases."))
story.append(sp(8))
# 3D DYSTONIA
story.append(h2("D. DYSTONIA"))
story.append(p(
"Dystonia is a disorder of <b>sustained or intermittent muscle contractions</b> causing twisting, "
"repetitive movements or abnormal postures. Key features:"
))
story.append(b("<b>Null point:</b> A position in which dystonic tremor ceases – pathognomonic of dystonic tremor."))
story.append(b("<b>Sensory trick (geste antagoniste):</b> Tactile/proprioceptive manoeuvres that transiently "
"relieve the dystonia (e.g., touching the chin in cervical dystonia)."))
story.append(b("<b>Task-specificity:</b> Dystonia occurs only during specific motor tasks (writer's cramp, musician's dystonia)."))
story.append(b("<b>Action dystonia:</b> Worsens with voluntary movement, may improve at rest."))
story.append(sp(4))
story.append(h3("Classification of Dystonia"))
dyst_data = [
["Axis", "Classification", "Examples"],
["By Distribution", "Focal", "Blepharospasm, cervical dystonia, writer's cramp, spasmodic dysphonia"],
["", "Segmental", "Blepharospasm + oromandibular = Meige syndrome"],
["", "Multifocal", "Two or more non-contiguous regions"],
["", "Generalised", "DYT1 torsion dystonia (TorsinA, 9q34)"],
["", "Hemidystonia", "Usually structural (stroke, AVM)"],
["By Aetiology","Idiopathic/Primary", "DYT1 (early-onset generalised); DYT6 (THAP1); Focal idiopathic"],
["", "Secondary/Acquired", "Perinatal injury, Wilson disease, drugs (tardive dystonia), stroke"],
["", "Heredodegenerative", "Wilson disease, Huntington, NBIA, mitochondrial disorders"],
["By Onset Age","Early-onset (<26 yr)", "More likely generalised; DYT1 most common"],
["", "Late-onset (>26 yr)", "More likely focal; cervical dystonia (most common focal dystonia)"],
]
story.append(make_table(dyst_data, col_widths=[2.8*cm, 3.6*cm, 7.6*cm]))
story.append(sp(4))
story.append(h3("Treatment of Dystonia"))
story.append(b("<b>Botulinum toxin injection</b> – treatment of choice for focal dystonia (cervical dystonia, blepharospasm, "
"spasmodic dysphonia, hemifacial spasm). Duration of effect 3–4 months."))
story.append(b("<b>Oral medications:</b> Trihexyphenidyl (high-dose anticholinergic, especially in DYT1); "
"baclofen; clonazepam; tetrabenazine."))
story.append(b("<b>Deep Brain Stimulation (DBS)</b> of GPi – highly effective for primary generalised dystonia (DYT1)."))
story.append(b("<b>Wilson disease:</b> D-penicillamine / trientine; zinc (maintenance)."))
story.append(b("<b>Dopa-responsive dystonia (DRD/DYT5, Segawa disease):</b> Dramatic response to low-dose levodopa; "
"diurnal fluctuation (worse in evening)."))
story.append(sp(8))
# 3E MYOCLONUS
story.append(h2("E. MYOCLONUS"))
story.append(p(
"Myoclonus consists of <b>sudden, brief, shock-like involuntary movements</b> caused by either "
"active muscle contraction (<i>positive myoclonus</i>) or sudden inhibition of muscle activity "
"(<i>negative myoclonus / asterixis</i>). It has the <b>broadest differential diagnosis</b> of any movement disorder."
))
story.append(h3("Etiological Classification"))
myoc_data = [
["Category", "Examples"],
["Physiological", "Hypnagogic jerks (sleep onset); hiccup (singultus); exercise-induced; anxiety"],
["Essential", "Hereditary myoclonus; sporadic; myoclonus-dystonia (DYT11, epsilon-sarcoglycan)"],
["Epileptic", "Juvenile myoclonic epilepsy (JME/Janz); Lennox-Gastaut; progressive myoclonic epilepsies; "
"Unverricht-Lundborg (Baltic myoclonus)"],
["Symptomatic", "Storage diseases (Lafora body, GM2 gangliosidosis, Batten disease); "
"post-hypoxic (Lance-Adams syndrome); uremia; liver failure; septic encephalopathy; "
"CJD (periodic myoclonus); SSPE; drugs (opioids, lithium)"],
["Cortical (most common)", "EEG: giant SEPs; time-locked with movement; treat with valproate, clonazepam, levetiracetam"],
["Subcortical", "Reticular myoclonus; generalized, axial > distal; treat with clonazepam"],
["Spinal", "Rhythmic; due to spinal cord lesion; often segmental"],
["Peripheral", "Hemifacial spasm (CN VII compression); brainstem origin"],
]
story.append(make_table(myoc_data, col_widths=[3.8*cm, 10.2*cm]))
story.append(sp(4))
story.append(h3("Treatment of Myoclonus"))
story.append(b("<b>Cortical myoclonus:</b> Sodium valproate (first-line); clonazepam; levetiracetam; piracetam."))
story.append(b("<b>Post-hypoxic (Lance-Adams):</b> Clonazepam + valproate; 5-hydroxytryptophan (serotonergic agent)."))
story.append(b("<b>Asterixis (negative myoclonus):</b> Treat underlying metabolic cause."))
story.append(sp(8))
# 3F TICS
story.append(h2("F. TICS AND TOURETTE SYNDROME"))
story.append(p(
"Tics are <b>sudden, repetitive, stereotyped movements or vocalisations</b> preceded by an "
"<b>inner urge (premonitory urge)</b> and temporarily suppressible by voluntary effort. "
"Unlike other hyperkinesias, tics can be <i>voluntarily</i> controlled briefly, albeit at the "
"cost of mounting inner tension."
))
story.append(h3("Classification of Tics (Bradley & Daroff)"))
story.append(b("<b>Simple motor tics:</b> Eye blinking, eyebrow raising, nose flaring, grimacing, head jerking, shoulder shrugging."))
story.append(b("<b>Complex motor tics:</b> Head shaking, teeth gnashing, touching, hitting, echopraxia (mimicking others), copropraxia."))
story.append(b("<b>Simple phonic tics:</b> Sniffing, grunting, throat clearing, shrieking, barking."))
story.append(b("<b>Complex phonic tics:</b> Echolalia (repeating others), palilalia (repeating own words), coprolalia (uttering obscenities – present in only ~10–15%)."))
story.append(sp(4))
story.append(h3("DSM-5 Diagnostic Criteria – Tourette Disorder (307.23)"))
story.append(b("Both multiple motor and ≥1 vocal tic(s) present at some time (not necessarily concurrently)."))
story.append(b("Tics may wax and wane but have persisted >1 year from first onset."))
story.append(b("Onset before 18 years of age."))
story.append(b("Not attributable to substance use or another medical condition."))
story.append(p(
"<b>Associated conditions:</b> ADHD (~50%), OCD (~40%), anxiety, learning disabilities, sleep disorders. "
"These comorbidities often cause more disability than the tics themselves."
))
story.append(sp(4))
story.append(h3("Treatment of Tourette Syndrome"))
story.append(b("<b>Mild tics:</b> Psychoeducation, habit reversal training, CBIT (Comprehensive Behavioural Intervention for Tics)."))
story.append(b("<b>Pharmacotherapy for tics:</b> Clonidine or guanfacine (first-line, especially with ADHD); "
"fluphenazine, haloperidol, aripiprazole, risperidone (D2 blockers); tetrabenazine; "
"topiramate; valbenazine (newer VMAT2 inhibitor)."))
story.append(b("<b>OCD component:</b> SSRIs (fluvoxamine, fluoxetine)."))
story.append(b("<b>ADHD component:</b> Clonidine preferred over stimulants (stimulants may transiently worsen tics)."))
story.append(b("<b>DBS:</b> Thalamus (centromedian-parafascicular complex) or GPi for refractory disabling tics."))
story.append(sp(8))
# ── 4. COMPARISON TABLE ──────────────────────────────────────────────────────
story.append(h1("4. DIFFERENTIAL DIAGNOSIS – COMPARISON AT A GLANCE"))
comp = [
["Feature", "Tremor", "Chorea", "Ballism", "Dystonia", "Myoclonus", "Tics"],
["Speed", "Varies", "Fast", "Very fast", "Variable", "Very fast", "Variable"],
["Rhythm", "Rhythmic", "Arrhythmic", "Arrhythmic", "Sustained", "Shock-like", "Stereotyped"],
["Distribution", "Distal", "Generalised", "Proximal", "Any", "Any", "Face/neck"],
["Suppressible", "Partial", "Partial", "No", "Trick", "No", "Yes (brief)"],
["Sleep effect", "Disappears", "Decreases", "Decreases", "Decreases", "Decreases", "Disappears"],
["Tone", "Normal", "Hypotonic", "Normal", "Increased", "Normal", "Normal"],
["Key lesion", "Various", "Striatum", "STN", "Putamen/GPi", "Cortex/brainstem","Cortico-striato-thalamic"],
]
story.append(make_table(comp, col_widths=[2.5*cm, 2.1*cm, 2.2*cm, 2.1*cm, 2.2*cm, 2.3*cm, 2.6*cm]))
story.append(sp(8))
# ── 5. INVESTIGATIONS ────────────────────────────────────────────────────────
story.append(h1("5. APPROACH AND INVESTIGATIONS"))
story.append(h3("History"))
story.append(b("Age at onset, tempo of progression, family history (autosomal dominant: HD, essential tremor, DYT1)."))
story.append(b("Drug exposure history (neuroleptics, L-dopa, OCP, cocaine, phenytoin)."))
story.append(b("Systemic illness (renal/hepatic failure → asterixis; thyroid disease → chorea/tremor)."))
story.append(b("Suppress-ability and premonitory urge (suggests tics)."))
story.append(h3("Examination"))
story.append(b("Observe at rest and during action/posture/intention."))
story.append(b("Assess for hypotonia, pendular reflexes (chorea), null point (dystonic tremor), sensory trick (dystonia)."))
story.append(b("Eye movements: supranuclear gaze palsy → PSP/Whipple's; Kayser-Fleischer rings → Wilson disease."))
story.append(h3("Investigations"))
inv_data = [
["Investigation", "Purpose"],
["MRI brain", "STN lesion (hemiballismus), caudate atrophy (HD), T2 signal in basal ganglia (Wilson, NBIA), cerebellar atrophy"],
["Genetic testing","CAG repeat in HTT (Huntington), DYT1 (torsinA), PRRT2 (paroxysmal dyskinesia)"],
["Serum copper/caeruloplasmin + 24-h urine copper", "Wilson disease (reduced caeruloplasmin, elevated urine copper)"],
["ASOT/Anti-DNase B + anti-basal ganglia Ab", "Sydenham chorea"],
["ANA, APLA screen", "SLE, antiphospholipid syndrome"],
["TFTs", "Thyrotoxicosis-associated chorea"],
["FBC + blood film","Neuroacanthocytosis (acanthocytes on smear)"],
["EEG + SEPs", "Cortical myoclonus (giant SEPs); epileptic myoclonus"],
["EMG/NCS", "Distinguish myoclonus from fasciculations; peripheral tics"],
["PET/DaTscan", "Reduced DAT uptake in Parkinson's vs. essential tremor"],
]
story.append(make_table(inv_data, col_widths=[5.5*cm, 8.5*cm]))
story.append(sp(8))
# ── 6. TREATMENT SUMMARY ─────────────────────────────────────────────────────
story.append(h1("6. TREATMENT SUMMARY"))
treat_data = [
["Disorder", "First-Line", "Second-Line / Surgical"],
["Essential tremor","Propranolol, primidone", "Topiramate, gabapentin; DBS (VIM nucleus)"],
["Chorea (HD)", "Tetrabenazine, deutetrabenazine", "Haloperidol, olanzapine; palliative care"],
["Sydenham chorea","Penicillin prophylaxis; valproate","Carbamazepine; IVIG for refractory"],
["Hemiballismus", "Tetrabenazine, haloperidol", "Treat underlying cause; DBS/pallidotomy"],
["Focal dystonia", "Botulinum toxin (injection)", "Trihexyphenidyl; DBS (GPi) for generalised"],
["DYT1 dystonia", "High-dose trihexyphenidyl", "DBS GPi (dramatic benefit)"],
["DRD (DYT5)", "Low-dose levodopa (dramatic)", "Levodopa lifetime"],
["Cortical myoclonus","Valproate, clonazepam", "Levetiracetam; piracetam"],
["Tourette tics", "Clonidine / guanfacine", "D2 blockers (aripiprazole); DBS (thalamus)"],
["Tremor (PD)", "Levodopa, dopamine agonists", "Anticholinergics; DBS STN or GPi"],
["Wilson disease (dystonia)","D-penicillamine / trientine", "Zinc maintenance; liver transplant"],
]
story.append(make_table(treat_data, col_widths=[3.5*cm, 5.5*cm, 5.0*cm]))
story.append(sp(8))
# ── 7. HIGH-YIELD EXAM POINTS ─────────────────────────────────────────────────
story.append(h1("7. HIGH-YIELD EXAM POINTS"))
story.append(b("Hemiballismus = contralateral STN lesion → disinhibition of thalamus → violent proximal flinging."))
story.append(b("Huntington disease = CAG repeat in HTT gene (chr 4p16.3); indirect pathway affected first → chorea; later both pathways → rigidity."))
story.append(b("Tetrabenazine inhibits VMAT2 → depletes presynaptic dopamine → only FDA-approved for Huntington chorea."))
story.append(b("DYT1 dystonia (TorsinA, 9q34) = most common inherited dystonia; onset < 26 years; GPi DBS highly effective."))
story.append(b("Dopa-responsive dystonia (DRD/Segawa): diurnal fluctuation, female > male, dramatic L-dopa response."))
story.append(b("Botulinum toxin = treatment of choice for focal dystonias; blocks ACh release at NMJ; effect lasts 3–4 months."))
story.append(b("Essential tremor: worsens with action/posture, improves with alcohol; propranolol first-line."))
story.append(b("Sensory trick (geste antagoniste) = pathognomonic of dystonia; touching chin relieves cervical dystonia."))
story.append(b("Tourette syndrome: tics + OCD + ADHD triad; coprolalia in only ~10–15%; mostly improves after adolescence."))
story.append(b("Sydenham chorea: post-streptococcal; anti-basal ganglia antibodies; treat with penicillin prophylaxis."))
story.append(b("Wilson disease: always exclude in any movement disorder before age 40 with psychiatric features; low caeruloplasmin."))
story.append(b("Asterixis = negative myoclonus; metabolic encephalopathy (hepatic, renal, respiratory failure)."))
story.append(b("Lance-Adams syndrome = post-hypoxic (post-cardiac arrest) cortical myoclonus; clonazepam + valproate."))
story.append(b("Neuroacanthocytosis: orolingual dystonia (eating dystonia), chorea, acanthocytes on blood film."))
story.append(sp(8))
# ── Footer note ───────────────────────────────────────────────────────────────
story.append(hr())
story.append(Paragraph(
"References: Bradley & Daroff's Neurology in Clinical Practice 8e | Adams & Victor's Principles of Neurology 12e | "
"Harrison's Principles of Internal Medicine 22e | Neuroanatomy through Clinical Cases 3e | "
"Goodman & Gilman's Pharmacological Basis of Therapeutics 14e | DSM-5",
FOOTER
))
# ── Build ─────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF generated: {OUTPUT}")
cd /home/daytona/workspace/hyperkinetic-movements && python generate_pdf.py
ls -lh /home/daytona/workspace/hyperkinetic-movements/Hyperkinetic_Movement_Diso…
Hyperkinetic Movement Disorders PG
PDF Document · PDF
| Section | Content |
|---|---|
| 1. Introduction & Classification | Master comparison table of all 8 hyperkinesias (speed, rhythm, suppressibility) |
| 2. Pathophysiology | Basal ganglia circuits - direct/indirect pathways, GPi, STN; explains WHY each disorder is hyperkinetic |
| 3. Individual Disorders | Detailed sections on Tremor, Chorea, Ballism, Dystonia, Myoclonus, and Tics - each with definition, features, aetiology table, and treatment |
| 4. Differential Diagnosis | Side-by-side comparison table across 6 disorders and 7 features |
| 5. Investigations | Structured approach - history, exam, and investigations with rationale |
| 6. Treatment Summary | Drug-by-drug and surgical options for every disorder |
| 7. High-Yield Exam Points | 14 one-liner exam facts (Huntington CAG, tetrabenazine VMAT2, GPi DBS, sensory trick, etc.) |
Create a case-based tutorial on Huntington disease diagnostic pathway
~/hyperkinetic-movements/hd_tutorial.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY, TA_RIGHT
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, PageBreak
)
OUTPUT = "/home/daytona/workspace/hyperkinetic-movements/HD_Diagnostic_Tutorial.pdf"
doc = SimpleDocTemplate(
OUTPUT, pagesize=A4,
rightMargin=2*cm, leftMargin=2*cm,
topMargin=2.2*cm, bottomMargin=2*cm,
title="Huntington Disease – Case-Based Diagnostic Tutorial",
author="Orris Medical"
)
W = A4[0] - 4*cm
# ── colour palette ────────────────────────────────────────────────────────────
NAVY = colors.HexColor("#1a237e")
BLUE = colors.HexColor("#1565c0")
LBLUE = colors.HexColor("#e8eaf6")
TEAL = colors.HexColor("#004d40")
LTEAL = colors.HexColor("#e0f2f1")
AMBER = colors.HexColor("#e65100")
LAMBER = colors.HexColor("#fff3e0")
RED = colors.HexColor("#b71c1c")
LRED = colors.HexColor("#ffebee")
GREEN = colors.HexColor("#1b5e20")
LGREEN = colors.HexColor("#e8f5e9")
GREY = colors.HexColor("#424242")
LGREY = colors.HexColor("#f5f5f5")
WHITE = colors.white
# ── styles ────────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def sty(name, parent="Normal", **kw):
return ParagraphStyle(name, parent=styles[parent], **kw)
TITLE = sty("TI", fontSize=20, leading=26, textColor=WHITE,
fontName="Helvetica-Bold", alignment=TA_CENTER, spaceAfter=2)
SUBTITLE= sty("ST", fontSize=11, leading=15, textColor=colors.HexColor("#bbdefb"),
alignment=TA_CENTER, fontName="Helvetica-Oblique", spaceAfter=2)
H1 = sty("H1", fontSize=13, leading=17, textColor=WHITE,
fontName="Helvetica-Bold", spaceAfter=4, spaceBefore=8,
backColor=NAVY, borderPad=5)
H2 = sty("H2", fontSize=11, leading=15, textColor=NAVY,
fontName="Helvetica-Bold", spaceBefore=7, spaceAfter=3)
H3 = sty("H3", fontSize=10, leading=14, textColor=TEAL,
fontName="Helvetica-Bold", spaceBefore=5, spaceAfter=2)
BODY = sty("BO", fontSize=9.5, leading=14, alignment=TA_JUSTIFY, spaceAfter=4)
BUL = sty("BU", fontSize=9.5, leading=13, leftIndent=14, firstLineIndent=-10,
spaceAfter=3)
NBUL = sty("NB", fontSize=9.5, leading=13, leftIndent=26, firstLineIndent=-10,
spaceAfter=2, textColor=GREY)
CASE = sty("CA", fontSize=10, leading=15, alignment=TA_JUSTIFY,
textColor=colors.HexColor("#212121"), spaceAfter=3,
fontName="Helvetica")
QMARK = sty("QM", fontSize=10, leading=14, textColor=AMBER,
fontName="Helvetica-Bold", spaceAfter=2)
ANS = sty("AN", fontSize=9.5, leading=13, textColor=GREEN,
fontName="Helvetica-Bold", spaceAfter=2)
CAPTION = sty("CP", fontSize=8.5, leading=11, textColor=GREY,
alignment=TA_CENTER, fontName="Helvetica-Oblique", spaceAfter=3)
FOOT = sty("FO", fontSize=8, textColor=GREY, alignment=TA_CENTER)
WARN = sty("WN", fontSize=9.5, leading=13, textColor=RED,
fontName="Helvetica-Bold", spaceAfter=2)
EMPH = sty("EM", fontSize=10, leading=14, textColor=NAVY,
fontName="Helvetica-BoldOblique", spaceAfter=3)
def h1(t): return Paragraph(f" {t}", H1)
def h2(t): return Paragraph(t, H2)
def h3(t): return Paragraph(t, H3)
def p(t): return Paragraph(t, BODY)
def b(t): return Paragraph(f"● {t}", BUL)
def nb(t): return Paragraph(f"– {t}", NBUL)
def sp(n=6): return Spacer(1, n)
def hr(): return HRFlowable(width="100%", thickness=0.6, color=NAVY, spaceAfter=4)
def hr2(): return HRFlowable(width="100%", thickness=0.3, color=colors.HexColor("#bbbbbb"), spaceAfter=3)
def case(t): return Paragraph(t, CASE)
def q(t): return Paragraph(f"? {t}", QMARK)
def ans(t): return Paragraph(f"✔ {t}", ANS)
def warn(t): return Paragraph(f"⚠ {t}", WARN)
# ── coloured box helper ───────────────────────────────────────────────────────
def colbox(rows, bg, border_col, col_widths=None):
"""Wrap a list of Paragraphs in a coloured background single-column table."""
if col_widths is None:
col_widths = [W]
data = [[r] for r in rows]
t = Table(data, colWidths=col_widths)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("BOX", (0,0), (-1,-1), 1, border_col),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
return t
def make_table(data, col_widths=None, header=True,
hdr_bg=NAVY, row_bgs=None):
if col_widths is None:
col_widths = [W/len(data[0])]*len(data[0])
if row_bgs is None:
row_bgs = [LBLUE, WHITE]
cell_s = ParagraphStyle("tc", fontSize=9, leading=12, spaceAfter=0)
hdr_s = ParagraphStyle("th", fontSize=9, leading=12,
fontName="Helvetica-Bold", textColor=WHITE, spaceAfter=0)
td = []
for ri, row in enumerate(data):
sr = []
for cell in row:
s = hdr_s if (header and ri == 0) else cell_s
sr.append(Paragraph(str(cell), s))
td.append(sr)
t = Table(td, colWidths=col_widths, repeatRows=1 if header else 0)
cmds = [
("BACKGROUND", (0,0), (-1,0), hdr_bg),
("ROWBACKGROUNDS",(0,1),(-1,-1), row_bgs),
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#bbbbbb")),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING",(0,0), (-1,-1), 4),
]
t.setStyle(TableStyle(cmds))
return t
# two-column layout helper
def two_col(left_items, right_items, lw=None, rw=None):
lw = lw or W*0.50 - 0.2*cm
rw = rw or W*0.50 - 0.2*cm
left_t = Table([[item] for item in left_items], colWidths=[lw])
right_t = Table([[item] for item in right_items], colWidths=[rw])
left_t.setStyle(TableStyle([("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),4),("TOPPADDING",(0,0),(-1,-1),0),("BOTTOMPADDING",(0,0),(-1,-1),0)]))
right_t.setStyle(TableStyle([("LEFTPADDING",(0,0),(-1,-1),4),("RIGHTPADDING",(0,0),(-1,-1),0),("TOPPADDING",(0,0),(-1,-1),0),("BOTTOMPADDING",(0,0),(-1,-1),0)]))
outer = Table([[left_t, right_t]], colWidths=[lw+0.2*cm, rw+0.2*cm])
outer.setStyle(TableStyle([("VALIGN",(0,0),(-1,-1),"TOP"),("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0),("TOPPADDING",(0,0),(-1,-1),0),("BOTTOMPADDING",(0,0),(-1,-1),0)]))
return outer
# ═══════════════════════════════════════════════════════════════════════════════
# STORY
# ═══════════════════════════════════════════════════════════════════════════════
story = []
# ── COVER BANNER ──────────────────────────────────────────────────────────────
banner_data = [[Paragraph("HUNTINGTON DISEASE", TITLE)],
[Paragraph("Case-Based Diagnostic Pathway Tutorial", SUBTITLE)],
[Paragraph("Postgraduate Neurology · Clinical Genetics · Internal Medicine", SUBTITLE)]]
banner = Table(banner_data, colWidths=[W])
banner.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("BOX", (0,0), (-1,-1), 1, BLUE),
("LEFTPADDING", (0,0), (-1,-1), 12),
("RIGHTPADDING", (0,0), (-1,-1), 12),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING",(0,0), (-1,-1), 10),
]))
story += [banner, sp(6)]
story.append(Paragraph(
"<i>Sources: Bradley & Daroff's Neurology 8e · Adams & Victor's Principles of Neurology 12e · "
"Tietz Textbook of Laboratory Medicine 7e · Robbins Basic Pathology · "
"Harrison's Internal Medicine 22e · Goldman-Cecil Medicine · Emery's Medical Genetics</i>",
CAPTION))
story.append(hr())
# ── HOW TO USE ───────────────────────────────────────────────────────────────
story.append(colbox([
Paragraph("<b>HOW TO USE THIS TUTORIAL</b>", sty("x1", fontSize=10, fontName="Helvetica-Bold", textColor=TEAL, spaceAfter=2)),
Paragraph(
"This tutorial presents <b>three progressive clinical cases</b>. Each case unfolds in stages: "
"<b>(1) vignette</b> → <b>(2) clinical questions</b> → <b>(3) teaching answer + explanation</b>. "
"Work through each question before reading the answer. A complete <b>diagnostic pathway flowchart</b>, "
"<b>CAG repeat interpretation guide</b>, <b>predictive testing protocol</b>, and "
"<b>management summary</b> follow the cases.",
sty("x2", fontSize=9.5, leading=13, spaceAfter=0))],
bg=LTEAL, border_col=TEAL))
story.append(sp(10))
# ── SECTION 1: BACKGROUND ────────────────────────────────────────────────────
story.append(h1("SECTION 1 — DISEASE OVERVIEW"))
story.append(h2("Epidemiology and Genetics"))
story.append(p(
"Huntington disease (HD; OMIM #143100) is an <b>autosomal dominant, fully penetrant "
"neurodegenerative disorder</b> caused by expansion of a CAG trinucleotide repeat in the "
"<i>HTT</i> gene on <b>chromosome 4p16.3</b>, encoding the protein <b>huntingtin</b>. "
"First described by George Huntington in 1872; the causative gene was identified in 1993."
))
epi_data = [
["Parameter", "Detail"],
["Prevalence", "3–10 per 100,000 worldwide; up to 15 per 100,000 in Western European populations"],
["Inheritance", "Autosomal dominant; fully penetrant (>39 CAG repeats); new mutations rare"],
["Mean age of onset", "45 years (range: 2–85 years); ~25% present after age 50"],
["Juvenile HD", "Onset <20 years (~5–10%); usually rigid (Westphal variant); paternal transmission"],
["Disease duration", "15–20 years from motor diagnosis to death"],
["Anticipation", "CAG repeat expands during spermatogenesis → earlier onset with paternal transmission"],
["Gene locus", "Chromosome 4p16.3; HTT gene, exon 1 CAG repeat"],
]
story.append(make_table(epi_data, col_widths=[4.5*cm, 9.5*cm]))
story.append(sp(6))
story.append(h2("CAG Repeat Interpretation (Adams & Victor 12e · Tietz Lab Medicine 7e)"))
cag_data = [
["CAG Repeat Count", "Interpretation", "Action"],
["≤26", "Normal (wild-type allele)", "No risk; no further testing"],
["27–35", "Intermediate / mutable normal allele", "Will NOT manifest HD themselves; risk of expansion in offspring (meiotic instability); genetic counselling advised"],
["36–39", "Reduced penetrance allele", "May or may not develop HD (especially if elderly); full HD possible; genetic counselling mandatory"],
["≥40", "Full penetrance allele – HD confirmed", "Will develop HD if they live long enough; predictive testing can confirm pre-symptomatically"],
["≥60", "Juvenile / very early onset", "Juvenile HD; usually rigid Westphal variant; paternal origin most common"],
]
story.append(make_table(cag_data,
col_widths=[3.0*cm, 5.5*cm, 5.5*cm],
hdr_bg=TEAL))
story.append(sp(6))
story.append(h2("Classical Triad of HD"))
story.append(two_col(
[
colbox([
Paragraph("<b>1. MOTOR</b>", sty("mx", fontSize=10, fontName="Helvetica-Bold", textColor=NAVY, spaceAfter=2)),
Paragraph("• Chorea (early) → dystonia/rigidity (late)", BUL),
Paragraph("• Motor impersistence (trombone tongue)", BUL),
Paragraph("• Milkmaid's grip (variable grip pressure)", BUL),
Paragraph("• Pendular reflexes (hypotonia)", BUL),
Paragraph("• Oculomotor: slowed saccades, impaired smooth pursuit", BUL),
Paragraph("• Dysarthria, dysphagia", BUL),
Paragraph("• Gait: drunken, wide-based stagger", BUL),
], bg=LBLUE, border_col=NAVY),
],
[
colbox([
Paragraph("<b>2. COGNITIVE</b>", sty("cx", fontSize=10, fontName="Helvetica-Bold", textColor=TEAL, spaceAfter=2)),
Paragraph("• Subcortical dementia (bradyphrenia)", BUL),
Paragraph("• Executive dysfunction (earliest change)", BUL),
Paragraph("• Impaired attention, concentration", BUL),
Paragraph("• Slowed psychomotor speed", BUL),
Paragraph("• Relatively spared memory initially", BUL),
Paragraph("• Negative emotion recognition impaired", BUL),
], bg=LTEAL, border_col=TEAL),
sp(4),
colbox([
Paragraph("<b>3. PSYCHIATRIC</b>", sty("px", fontSize=10, fontName="Helvetica-Bold", textColor=AMBER, spaceAfter=2)),
Paragraph("• Depression (~50%) – often earliest", BUL),
Paragraph("• Apathy, irritability, aggression", BUL),
Paragraph("• Anxiety, OCD-like behaviour", BUL),
Paragraph("• Psychosis (paranoid delusions ~10%)", BUL),
Paragraph("• Suicidality – risk at diagnosis", BUL),
], bg=LAMBER, border_col=AMBER),
]
))
story.append(sp(8))
story.append(h2("Pathology (Robbins Basic Pathology)"))
story.append(p(
"The mutant huntingtin protein undergoes ubiquitination and proteolysis, yielding polyglutamine-expanded "
"fragments that form <b>intranuclear inclusions</b>. The <b>medium-sized spiny neurons (MSNs)</b> of the "
"caudate and putamen — which release GABA, enkephalin, dynorphin, and substance P — are preferentially "
"destroyed. <b>Indirect pathway MSNs</b> (enkephalin-positive, D2-bearing) degenerate first, producing "
"the hyperkinetic (choreic) phenotype. As both pathways degenerate, a rigid parkinsonian state ensues."
))
story.append(b("<b>Gross pathology:</b> Striatal atrophy (caudate predominantly) → lateral ventricle dilatation (\"butterfly\" appearance on MRI); frontal > parietal cortical atrophy."))
story.append(b("<b>Microscopic:</b> Severe neuronal loss with gliosis in striatum; intranuclear ubiquitinated huntingtin inclusions."))
story.append(b("<b>Grading (Vonsattel grades 0–4):</b> Grade 0 = no macroscopic change, Grade 4 = severe striatal atrophy."))
story.append(sp(10))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 2: CASE 1
# ══════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(h1("SECTION 2 — CASE 1: THE PRESENTING PATIENT"))
story.append(colbox([
Paragraph("<b>CLINICAL VIGNETTE — Case 1</b>", sty("cv1", fontSize=11, fontName="Helvetica-Bold", textColor=NAVY, spaceAfter=4)),
Paragraph(
"Mr. A.K. is a <b>42-year-old</b> right-handed teacher who presents to the neurology outpatient clinic "
"at the insistence of his wife. She reports that over the past <b>18 months</b>, he has become "
"increasingly <b>forgetful</b>, misplacing things at work, missing appointments, and showing "
"<b>uncharacteristic irritability</b> and <b>depression</b>. She has also noticed that he "
"\"fidgets constantly\" — his fingers, shoulders, and face seem to move involuntarily. He "
"sometimes grimaces, and his speech has become slightly slurred. He denies any symptoms himself, "
"calling it \"just stress.\"", CASE),
Paragraph(
"Past history: Mild depression 3 years ago, treated with sertraline. No prior neurological illness. "
"Family history: <b>His father died at age 58, reportedly of a 'nervous breakdown with shaking.'</b> "
"A paternal uncle is in a nursing home with \"dementia and involuntary movements.\"", CASE),
Paragraph(
"Examination: Restless, minimally cooperative. Mini-Mental State Examination (MMSE) 26/30 "
"(loses points on attention and serial 7s). Irregular, unpredictable brief jerky movements of face, "
"arms, and trunk. <b>Trombone tongue sign positive</b>. <b>Milkmaid grip present</b>. Pendular knee "
"jerks. Slowed saccadic eye movements. Gait: wide-based, unsteady, drunken-like.", CASE),
], bg=LBLUE, border_col=NAVY))
story.append(sp(8))
story.append(h2("Case 1 — Questions"))
# Q1
story.append(colbox([
q("QUESTION 1 (2 marks): What is the most likely diagnosis? Name the two features in the family history that strongly support it."),
], bg=LAMBER, border_col=AMBER))
story.append(sp(4))
story.append(colbox([
ans("ANSWER 1:"),
p("<b>Most likely diagnosis: Huntington disease (HD).</b>"),
p("Supportive family history features:"),
b("His <b>father</b> died with 'shaking' and a 'nervous breakdown' — consistent with HD triad (chorea + psychiatric + cognitive) at a typical age (~58)."),
b("A <b>paternal uncle</b> is in a nursing home with dementia and involuntary movements — confirms the autosomal dominant vertical transmission pattern across two family members on the paternal side."),
p("<i>Teaching point: Autosomal dominant inheritance means 50% risk to first-degree relatives. Both a parent and a parent's sibling being affected dramatically raises pre-test probability.</i>"),
], bg=LGREEN, border_col=GREEN))
story.append(sp(6))
# Q2
story.append(colbox([
q("QUESTION 2 (3 marks): List the five cardinal examination findings that point toward HD and explain the pathophysiology of the 'trombone tongue.'"),
], bg=LAMBER, border_col=AMBER))
story.append(sp(4))
story.append(colbox([
ans("ANSWER 2 — Cardinal findings:"),
b("<b>Chorea</b> — irregular, unpredictable, random flowing movements (face, arms, trunk)"),
b("<b>Trombone tongue</b> — motor impersistence; inability to maintain sustained tongue protrusion; choreic darting interrupts volitional posture → reflects striatal dysfunction"),
b("<b>Milkmaid grip</b> — variable grip force on the examiner's fingers due to superimposed choreic movements"),
b("<b>Pendular reflexes</b> — due to hypotonia; leg swings multiple times after patellar tap"),
b("<b>Slowed saccadic eye movements</b> — early, specific finding in HD; caudate-frontal circuit dysfunction delays voluntary saccade initiation"),
p("<i>Pathophysiology of trombone tongue: Motor impersistence is the inability to sustain a voluntary motor act. The striatum suppresses unwanted movements; its degeneration allows random choreic intrusions to interrupt tongue protrusion mid-action. This is not weakness — the patient can protrude the tongue but cannot maintain it.</i>"),
], bg=LGREEN, border_col=GREEN))
story.append(sp(6))
# Q3
story.append(colbox([
q("QUESTION 3 (3 marks): What is the single most important investigation to confirm HD? How do you interpret the result?"),
], bg=LAMBER, border_col=AMBER))
story.append(sp(4))
story.append(colbox([
ans("ANSWER 3:"),
p("<b>Investigation: CAG repeat analysis of the HTT gene</b> by PCR (polymerase chain reaction) with fragment-length analysis (capillary electrophoresis). This is the <b>definitive diagnostic test</b>."),
p("<b>Interpretation of result:</b>"),
], bg=LGREEN, border_col=GREEN))
story.append(make_table([
["CAG Repeats", "Interpretation", "Clinical Implication"],
["≤26", "Normal", "Excludes HD"],
["27–35", "Intermediate allele", "Patient not at risk; offspring may have expanded allele"],
["36–39", "Reduced penetrance", "May develop HD; genetic counselling essential"],
["≥40", "Full penetrance – HD CONFIRMED", "Diagnostic; 100% will develop HD if ≥40 repeats"],
["≥60", "Juvenile HD likely", "Usually with rigid phenotype; paternal origin"],
], col_widths=[2.5*cm, 4.5*cm, 7.0*cm], hdr_bg=TEAL))
story.append(sp(6))
story.append(colbox([
p("<b>Additional investigations in a new suspected HD case:</b>"),
b("MRI brain: Caudate atrophy (\"boxcar\" or \"butterfly\" ventricles), frontal cortical atrophy — supports diagnosis but NOT confirmatory"),
b("Neuropsychological testing: Symbol Digit Modalities Test, Stroop, Trail Making Test — earliest declines detectable"),
b("Psychiatric assessment: Depression, suicidality screen (mandatory before genetic testing in at-risk individuals)"),
b("Exclude mimics: Serum copper/caeruloplasmin (Wilson disease), ASOT (Sydenham chorea), blood film (neuroacanthocytosis), TFTs, ANA/APLA"),
], bg=LRED, border_col=RED))
story.append(sp(10))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 3: CASE 2
# ══════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(h1("SECTION 3 — CASE 2: THE ASYMPTOMATIC AT-RISK RELATIVE"))
story.append(colbox([
Paragraph("<b>CLINICAL VIGNETTE — Case 2</b>", sty("cv2", fontSize=11, fontName="Helvetica-Bold", textColor=TEAL, spaceAfter=4)),
Paragraph(
"Mr. A.K.'s son, <b>Rohan</b>, is a <b>24-year-old</b> medical student. After his father's HD diagnosis "
"(CAG repeat = 48), Rohan presents to the genetics clinic. He has <b>no symptoms</b>. He wants to "
"know if he has the gene so he can make informed decisions about his career and whether to start a family. "
"His partner accompanies him.", CASE),
Paragraph(
"He asks: <i>\"Doctor, should I get tested? What does the test mean for me? If I test positive, "
"what happens next? And what about my children?\"</i>", CASE),
], bg=LTEAL, border_col=TEAL))
story.append(sp(8))
story.append(h2("Case 2 — Questions"))
# Q4
story.append(colbox([
q("QUESTION 4 (2 marks): What is Rohan's prior risk of carrying the HD mutation? What test would you offer, and at what age can it be performed?"),
], bg=LAMBER, border_col=AMBER))
story.append(sp(4))
story.append(colbox([
ans("ANSWER 4:"),
b("<b>Prior (prior to testing) risk = 50%</b> — each child of an affected parent has a 50% chance of inheriting the expanded allele (autosomal dominant, single copy sufficient)."),
b("<b>Test: Presymptomatic (predictive) DNA testing</b> — PCR-based CAG repeat analysis of HTT gene."),
b("<b>Age:</b> Minimum age is <b>18 years</b> (Tietz Textbook, Box 68.2). Testing of minors is <b>not</b> recommended because HD is a late-onset disease with no preventive treatment; the child cannot give autonomous informed consent."),
p("<i>At CAG repeat 48 (his father's allele), the risk of repeat expansion during paternal meiosis is noted, but the inherited allele is already fixed at the child's conception.</i>"),
], bg=LGREEN, border_col=GREEN))
story.append(sp(6))
# Q5
story.append(colbox([
q("QUESTION 5 (5 marks): Outline the full presymptomatic testing protocol for HD. What ethical safeguards must be in place?"),
], bg=LAMBER, border_col=AMBER))
story.append(sp(4))
story.append(colbox([
ans("ANSWER 5 — Presymptomatic HD Testing Protocol (Tietz Lab Medicine 7e, Box 68.2):"),
], bg=LGREEN, border_col=GREEN))
protocol_data = [
["Step", "Requirement", "Rationale"],
["1. Confirm family diagnosis",
"DNA testing of affected relative must confirm HD before testing Rohan",
"Avoids false positive testing in family with misdiagnosed disease"],
["2. Genetic counselling (pre-test)",
"≥2 sessions with a certified genetic counsellor; implications for career, insurance, reproduction explained",
"Ensures truly informed consent; addresses psychosocial consequences"],
["3. Psychiatric assessment",
"Formal evaluation for depression, anxiety, suicidal ideation BEFORE testing",
"HD test results can precipitate severe depression/suicide; unstable patients postponed until stable"],
["4. Informed consent",
"Decision must be entirely voluntary; no coercion from family, clinicians, employers, insurers",
"Ethical autonomy; patient may choose NOT to know"],
["5. Support person",
"Patient should bring a trusted friend/partner to ALL sessions including result delivery",
"Provides immediate emotional support; helps process information"],
["6. DNA testing",
"Blood sample; PCR CAG repeat analysis",
"Definitive molecular result"],
["7. Result disclosure",
"Face-to-face, never by mail/phone alone; counsellor present",
"Result may be life-altering; immediate support required"],
["8. Post-test counselling",
"Mandatory follow-up after positive AND negative results",
"Negative result can also cause survivor guilt; positive result needs care planning"],
["9. Prenatal / preimplantation options",
"Discuss prenatal diagnosis by chorionic villus sampling (CVS) or PGT-M (preimplantation genetic testing)",
"Reproductive planning; allows selective embryo implantation"],
]
story.append(make_table(protocol_data, col_widths=[2.8*cm, 5.2*cm, 6.0*cm], hdr_bg=TEAL))
story.append(sp(4))
story.append(colbox([
warn("KEY ETHICAL PRINCIPLES (Tietz 7e):"),
b("Patient must be ≥18 years; decision is entirely voluntary and informed."),
b("Suicidality is elevated in both at-risk and affected individuals — psychiatric safety must be established."),
b("Insurance/employer discrimination is a real concern; patients must be counselled accordingly."),
b("A positive result does NOT mean the patient is symptomatic — it predicts future disease."),
b("Some patients opt out of testing — this is fully valid and must be respected."),
], bg=LRED, border_col=RED))
story.append(sp(6))
# Q6
story.append(colbox([
q("QUESTION 6 (2 marks): Rohan's test shows CAG repeats of 18 and 48. Interpret the result and explain 'anticipation' in the context of HD."),
], bg=LAMBER, border_col=AMBER))
story.append(sp(4))
story.append(colbox([
ans("ANSWER 6:"),
p("<b>Interpretation:</b> Two alleles detected — 18 repeats (normal; father's wild-type allele or mother's) and <b>48 repeats (HD allele, full penetrance)</b>. "
"Rohan has inherited the expanded HTT allele. He <b>will develop HD</b>. "
"This is a PRESYMPTOMATIC positive result."),
p("<b>Anticipation:</b> The CAG repeat tends to expand during <b>spermatogenesis</b> (paternal transmission). "
"The grandfather may have had a smaller repeat (e.g., 44); the father inherited 48; Rohan may have inherited 48 or a further expansion. "
"With each paternal generation, larger repeats → <b>earlier onset and more severe disease</b>. "
"This genotype-phenotype correlation (repeat length ↑ → age of onset ↓) is well established, "
"though once the disease starts, <b>repeat length does NOT determine rate of progression</b> (Robbins)."),
], bg=LGREEN, border_col=GREEN))
story.append(sp(10))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 4: CASE 3
# ══════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(h1("SECTION 4 — CASE 3: JUVENILE HD & DIFFERENTIAL DIAGNOSIS"))
story.append(colbox([
Paragraph("<b>CLINICAL VIGNETTE — Case 3</b>", sty("cv3", fontSize=11, fontName="Helvetica-Bold", textColor=RED, spaceAfter=4)),
Paragraph(
"A <b>16-year-old boy</b>, Sanjay, is brought by his mother because of <b>academic decline</b> "
"over 2 years, <b>behavioural changes</b> (aggression, school refusal), and <b>progressive "
"rigidity</b> with tremor in both hands over the past year. She mentions that "
"<b>his maternal grandfather died of a 'brain disease with shaking'</b> 3 years ago. "
"She herself is well at age 42.", CASE),
Paragraph(
"Examination: Marked bradyphrenia. Cogwheel rigidity in both arms. Bilateral resting tremor. "
"No chorea. Mild bradykinesia. Kayser-Fleischer rings <b>absent</b>. Serum copper normal. "
"Ceruloplasmin normal. MRI brain: <b>Bilateral caudate atrophy</b>. "
"EEG: Generalised slow waves.", CASE),
], bg=LRED, border_col=RED))
story.append(sp(8))
story.append(h2("Case 3 — Questions"))
# Q7
story.append(colbox([
q("QUESTION 7 (3 marks): What is the diagnosis? Why does this case present differently from Case 1? Name the clinical variant and explain the pathophysiology."),
], bg=LAMBER, border_col=AMBER))
story.append(sp(4))
story.append(colbox([
ans("ANSWER 7:"),
p("<b>Diagnosis: Juvenile Huntington Disease — Westphal (Rigid) Variant.</b>"),
p("<b>Why rigid, not choreic?</b> Juvenile HD typically has very high CAG repeat counts (often ≥55–60), "
"usually from <b>paternal</b> transmission. With massive repeat expansions, <b>both the direct and "
"indirect striatal pathways degenerate simultaneously and early</b> — rather than indirect pathway "
"first (as in adult HD). This means there is no transient chorea phase; instead, the loss of "
"direct pathway (D1 MSNs) reduces thalamic excitation → akinetic-rigid syndrome resembling "
"Parkinson disease."),
b("<b>Westphal variant features:</b> Rigidity > chorea; bradykinesia; tremor; seizures (EEG abnormalities common); rapid cognitive decline; onset <20 years."),
b("<b>Usually paternal inheritance</b> due to CAG expansion during spermatogenesis (anticipation)."),
p("<i>Note: His mother is 42 and well — the grandfather's disease is transmitted through the mother "
"as a carrier (presymptomatic), or the grandfather transmitted to the mother who is presymptomatic "
"(mean onset 45 years, she is currently 42 and may develop HD).</i>"),
], bg=LGREEN, border_col=GREEN))
story.append(sp(6))
# Q8
story.append(colbox([
q("QUESTION 8 (4 marks): List four important differential diagnoses for this presentation (rigid juvenile movement disorder + cognitive decline) and how you would exclude each."),
], bg=LAMBER, border_col=AMBER))
story.append(sp(4))
diff_dd = [
["Differential Diagnosis", "Distinguishing Features", "Investigations"],
["Wilson Disease",
"Autosomal recessive; Kayser-Fleischer rings; liver disease; psychiatric; age 5–35",
"Serum copper ↓, ceruloplasmin ↓, 24-h urine copper ↑; slit-lamp exam (K-F rings); MRI: 'face of giant panda'"],
["Neuroacanthocytosis (McLeod syndrome)",
"Chorea + dystonia + orolingual dystonia; peripheral neuropathy; elevated CK",
"Blood film: acanthocytes; CK elevated; molecular: XK gene (McLeod); VPS13A (NA)"],
["Dentatorubropallidoluysian atrophy (DRPLA)",
"Autosomal dominant; ataxia + chorea + myoclonus + dementia; ATN1 CAG expansion",
"Genetic testing: ATN1 CAG repeat analysis; more common in Japan"],
["Juvenile Parkinson Disease (Parkin/PINK1/DJ-1)",
"Levodopa-responsive rigidity; NO cognitive decline initially; NO dementia; usually after age 20",
"Parkin/PINK1 gene testing; DaTscan (↓ striatal DAT); good L-dopa response"],
["Autoimmune encephalitis (anti-NMDAR, etc.)",
"Subacute onset; CSF pleocytosis; prominent psychiatric + seizures; movement disorder",
"CSF antibody panel; EEG (delta-brush); MRI: FLAIR changes; good immunotherapy response"],
]
story.append(make_table(diff_dd, col_widths=[3.5*cm, 5.0*cm, 5.5*cm], hdr_bg=RED))
story.append(sp(6))
story.append(colbox([
ans("KEY TEACHING: In this case, HTT CAG repeat testing was performed and showed 62 repeats → Juvenile HD confirmed."),
p("The normal copper/ceruloplasmin and absent K-F rings exclude Wilson disease (the first and most important differential in any young person with a movement disorder)."),
], bg=LGREEN, border_col=GREEN))
story.append(sp(10))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 5: DIAGNOSTIC PATHWAY
# ══════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(h1("SECTION 5 — HD DIAGNOSTIC PATHWAY FLOWCHART"))
story.append(p(
"The pathway below integrates clinical assessment, genetic testing, and result interpretation "
"for both <b>symptomatic</b> and <b>presymptomatic (at-risk)</b> individuals."
))
story.append(sp(6))
def flowbox(text, bg, border, w=None):
w = w or W
style = ParagraphStyle("fb", fontSize=9.5, leading=13, alignment=TA_CENTER,
fontName="Helvetica-Bold", textColor=border, spaceAfter=0)
t = Table([[Paragraph(text, style)]], colWidths=[w])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(0,0), bg),
("BOX", (0,0),(0,0), 1.5, border),
("LEFTPADDING", (0,0),(0,0), 6),
("RIGHTPADDING", (0,0),(0,0), 6),
("TOPPADDING", (0,0),(0,0), 6),
("BOTTOMPADDING",(0,0),(0,0), 6),
]))
return t
def arrow(): return Paragraph("▼", sty("arr", fontSize=14, alignment=TA_CENTER,
textColor=GREY, spaceAfter=0, spaceBefore=0))
story.append(flowbox("PATIENT WITH SUSPECTED HD OR AT-RISK RELATIVE", LBLUE, NAVY))
story.append(arrow())
# Split: symptomatic vs at-risk
split_data = [[
flowbox("SYMPTOMATIC PATIENT\n(chorea, cognitive, psychiatric signs)", LTEAL, TEAL, w=W*0.46),
Paragraph("", BODY),
flowbox("ASYMPTOMATIC AT-RISK RELATIVE\n(family history of HD)", LAMBER, AMBER, w=W*0.46),
]]
split_t = Table(split_data, colWidths=[W*0.47, W*0.06, W*0.47])
split_t.setStyle(TableStyle([("VALIGN",(0,0),(-1,-1),"MIDDLE"),("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0)]))
story.append(split_t)
story.append(arrow())
# Steps
step_data = [[
Table([
[flowbox("Step 1: Clinical Assessment\n• Triad: Chorea + Dementia + Psychiatric\n• Trombone tongue, milkmaid grip\n• Oculomotor slowing, saccade delay", LTEAL, TEAL, w=W*0.46)],
[arrow()],
[flowbox("Step 2: Exclude Mimics\n• Wilson: copper, ceruloplasmin\n• Neuroacanthocytosis: blood film\n• DRPLA: if Asian + ataxia + chorea\n• Autoimmune: CSF, antibody panel", LAMBER, AMBER, w=W*0.46)],
[arrow()],
[flowbox("Step 3: MRI Brain\n• Caudate atrophy (butterfly ventricles)\n• Frontal cortical atrophy\n• Supports but NOT confirmatory", LBLUE, BLUE, w=W*0.46)],
[arrow()],
[flowbox("Step 4: HTT CAG Repeat Testing\nPCR + fragment analysis of blood DNA\nDEFINITIVE TEST", LGREEN, GREEN, w=W*0.46)],
], colWidths=[W*0.46]),
Paragraph("", BODY),
Table([
[flowbox("Step 1: Confirm family diagnosis\nAffected relative must have positive HTT test\nbefore proceeding", LTEAL, TEAL, w=W*0.46)],
[arrow()],
[flowbox("Step 2: Pre-test Genetic Counselling (≥2 sessions)\nRisk explanation · Career/insurance implications\nReproductive options · Right NOT to know", LAMBER, AMBER, w=W*0.46)],
[arrow()],
[flowbox("Step 3: Psychiatric Assessment\nScreen for depression, suicidality\nPostpone testing if unstable", LRED, RED, w=W*0.46)],
[arrow()],
[flowbox("Step 4: Informed Consent\nVoluntary · Minimum age 18\nNo coercion · Support person present", LBLUE, BLUE, w=W*0.46)],
[arrow()],
[flowbox("Step 5: HTT CAG Repeat Analysis\n(Same PCR/fragment analysis)", LGREEN, GREEN, w=W*0.46)],
], colWidths=[W*0.46]),
]]
step_t = Table(step_data, colWidths=[W*0.47, W*0.06, W*0.47])
step_t.setStyle(TableStyle([("VALIGN",(0,0),(-1,-1),"TOP"),("LEFTPADDING",(0,0),(-1,-1),0),("RIGHTPADDING",(0,0),(-1,-1),0)]))
story.append(step_t)
story.append(arrow())
# Interpretation
story.append(flowbox("INTERPRET CAG REPEAT RESULT", LBLUE, NAVY))
story.append(arrow())
interp_data = [[
flowbox("CAG ≤26\nNormal → HD EXCLUDED\nNo further testing needed", LGREEN, GREEN, w=W*0.23),
flowbox("CAG 27–35\nIntermediate allele\nPatient unaffected; offspring may expand\nGenetic counselling", LTEAL, TEAL, w=W*0.23),
flowbox("CAG 36–39\nReduced penetrance\nMay or may not develop HD\nCounselling + surveillance", LAMBER, AMBER, w=W*0.23),
flowbox("CAG ≥40\nFULL PENETRANCE\nHD CONFIRMED (or predicted)\nMultidisciplinary management", LRED, RED, w=W*0.23),
]]
interp_t = Table(interp_data, colWidths=[W*0.25, W*0.25, W*0.25, W*0.25])
interp_t.setStyle(TableStyle([("VALIGN",(0,0),(-1,-1),"TOP"),("LEFTPADDING",(0,0),(-1,-1),2),("RIGHTPADDING",(0,0),(-1,-1),2)]))
story.append(interp_t)
story.append(sp(4))
story.append(flowbox("POST-RESULT COUNSELLING (mandatory) → Multidisciplinary HD Team Referral", LBLUE, NAVY))
story.append(sp(10))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 6: MANAGEMENT
# ══════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(h1("SECTION 6 — MANAGEMENT OF HD"))
story.append(p(
"There is currently <b>no disease-modifying therapy</b> that alters HD progression. "
"Management is <b>symptomatic and multidisciplinary</b>, targeting the three domains: motor, cognitive, and psychiatric."
))
story.append(sp(4))
mgmt_data = [
["Domain / Symptom", "First-Line Therapy", "Second-Line / Notes"],
["Chorea (motor)",
"Tetrabenazine (VMAT2 inhibitor; FDA-approved for HD chorea); start low, titrate slowly",
"Deutetrabenazine / Valbenazine (better tolerability); haloperidol or olanzapine; clonazepam"],
["Rigidity / Bradykinesia (late)",
"Levodopa trial (especially juvenile variant)",
"Often poor response in adult HD unlike Parkinson"],
["Dystonia",
"Botulinum toxin for focal dystonia; baclofen",
"Clonazepam; trihexyphenidyl"],
["Depression",
"SSRIs (sertraline, citalopram) — first-line",
"SNRIs; mirtazapine; avoid TCAs (lower seizure threshold in juvenile HD)"],
["Irritability / Aggression",
"SSRIs; quetiapine (low-dose); citalopram",
"Carbamazepine; valproate"],
["Psychosis / Paranoia",
"Atypical antipsychotics: quetiapine, olanzapine",
"Avoid high-dose typical antipsychotics (worsen motor symptoms)"],
["Apathy",
"Psychosocial interventions; treat depression if co-existing",
"Methylphenidate (evidence limited)"],
["Cognitive decline",
"Cognitive rehabilitation; environmental modification; no approved pharmacotherapy",
"Rivastigmine (limited evidence); donepezil not proven beneficial"],
["Dysphagia",
"Speech-language therapy; dietary modification (thickened fluids)",
"PEG tube in late-stage disease"],
["Weight loss",
"High-calorie diet; dietary supplements; nutritional support team",
"Caloric needs can be 4000–5000 kcal/day due to constant movement"],
["Suicidality",
"Urgent psychiatric assessment; hospitalisation if needed; remove access to means",
"Highest risk: at time of diagnosis, mid-stage disease"],
["Gait/Falls",
"Physiotherapy; walking aids; fall prevention measures",
"Occupational therapy for home modification"],
]
story.append(make_table(mgmt_data, col_widths=[3.8*cm, 5.0*cm, 5.2*cm], hdr_bg=NAVY))
story.append(sp(6))
story.append(h2("Tetrabenazine — Mechanism and Key Points"))
story.append(colbox([
b("<b>Mechanism:</b> Inhibits vesicular monoamine transporter type 2 (VMAT2) → depletes presynaptic vesicular stores of dopamine, serotonin, noradrenaline."),
b("<b>Effect:</b> Reduces dopaminergic hyperactivity in the striatum → lessens choreiform movements."),
b("<b>FDA approval:</b> Only for <i>chorea</i> in Huntington disease (not preventive; does NOT alter course)."),
b("<b>Side effects:</b> Depression (BBW – black box warning for depression/suicidality); sedation; akathisia; parkinsonism."),
b("<b>Contraindication:</b> Active, untreated depression; suicidal ideation; hepatic impairment."),
b("<b>Newer agents:</b> Deutetrabenazine and valbenazine have longer half-lives, fewer peaks-and-troughs → better tolerability with similar efficacy."),
], bg=LRED, border_col=RED))
story.append(sp(6))
story.append(h2("Multidisciplinary Team (MDT) in HD"))
mdt_data = [
["Team Member", "Role"],
["Neurologist", "Diagnosis, motor symptom management, genetic testing coordination"],
["Clinical geneticist", "Genetic counselling, presymptomatic testing protocol, family cascade testing"],
["Psychiatrist", "Depression, psychosis, suicidality, behaviour management"],
["Neuropsychologist", "Cognitive assessment, monitoring disease progression, occupational advice"],
["Speech-language therapist","Dysarthria, dysphagia management, communication aids"],
["Physiotherapist", "Gait, balance, falls prevention, maintaining function"],
["Occupational therapist", "Home adaptations, aids/appliances, daily living activities"],
["Dietitian", "High-calorie nutrition, dysphagia diet, PEG tube planning"],
["Social worker", "Carer support, financial planning, residential care planning"],
["Palliative care team", "End-stage HD: comfort, PEG, advance care planning"],
]
story.append(make_table(mdt_data, col_widths=[4.5*cm, 9.5*cm], hdr_bg=TEAL))
story.append(sp(8))
# ══════════════════════════════════════════════════════════════════════════════
# SECTION 7: HIGH-YIELD SUMMARY
# ══════════════════════════════════════════════════════════════════════════════
story.append(h1("SECTION 7 — HIGH-YIELD EXAM SUMMARY"))
story.append(two_col(
[
colbox([
Paragraph("<b>GENETICS — Must Know</b>", sty("gk", fontSize=10, fontName="Helvetica-Bold", textColor=NAVY, spaceAfter=3)),
Paragraph("• Gene: <b>HTT</b>, chromosome <b>4p16.3</b>", BUL),
Paragraph("• Repeat: <b>CAG</b> (encodes glutamine → polyglutamine tract)", BUL),
Paragraph("• Normal: 11–26 repeats", BUL),
Paragraph("• Full penetrance: <b>≥40 repeats</b>", BUL),
Paragraph("• Reduced penetrance: 36–39 repeats", BUL),
Paragraph("• Juvenile HD: ≥55–60 repeats (usually)", BUL),
Paragraph("• Anticipation via paternal spermatogenesis", BUL),
Paragraph("• Autosomal dominant; new mutations rare", BUL),
], bg=LBLUE, border_col=NAVY),
sp(4),
colbox([
Paragraph("<b>CLINICAL — Must Know</b>", sty("ck", fontSize=10, fontName="Helvetica-Bold", textColor=TEAL, spaceAfter=3)),
Paragraph("• Triad: <b>Chorea + Dementia + Psychiatric</b>", BUL),
Paragraph("• Mean onset: 45 years; duration ~15–20 years", BUL),
Paragraph("• Psychiatric symptoms may precede motor by years", BUL),
Paragraph("• Trombone tongue = motor impersistence", BUL),
Paragraph("• Milkmaid grip = variable grip force", BUL),
Paragraph("• Slowed saccades = early, specific sign", BUL),
Paragraph("• Subcortical dementia (bradyphrenia)", BUL),
Paragraph("• Westphal variant = juvenile, rigid, CAG ≥55", BUL),
], bg=LTEAL, border_col=TEAL),
],
[
colbox([
Paragraph("<b>DIAGNOSIS — Must Know</b>", sty("dk", fontSize=10, fontName="Helvetica-Bold", textColor=RED, spaceAfter=3)),
Paragraph("• Definitive: <b>HTT CAG repeat analysis by PCR</b>", BUL),
Paragraph("• MRI: caudate atrophy, butterfly ventricles (supportive)", BUL),
Paragraph("• Always exclude Wilson (copper panel) in young patients", BUL),
Paragraph("• Presymptomatic testing: age ≥18, psychiatric assessment first", BUL),
Paragraph("• Informed consent: voluntary, no coercion", BUL),
Paragraph("• Post-test counselling: mandatory", BUL),
], bg=LRED, border_col=RED),
sp(4),
colbox([
Paragraph("<b>TREATMENT — Must Know</b>", sty("tk", fontSize=10, fontName="Helvetica-Bold", textColor=AMBER, spaceAfter=3)),
Paragraph("• NO disease-modifying therapy currently available", BUL),
Paragraph("• Chorea: <b>Tetrabenazine</b> (VMAT2 inhibitor, FDA-approved)", BUL),
Paragraph("• Tetrabenazine: BBW for depression/suicidality", BUL),
Paragraph("• Depression: SSRIs (sertraline, citalopram)", BUL),
Paragraph("• Psychosis: atypical antipsychotics (quetiapine)", BUL),
Paragraph("• Dysphagia: SLT, thickened feeds, PEG (late)", BUL),
Paragraph("• MDT essential: neurology, psychiatry, genetics, physio, dietitian", BUL),
], bg=LAMBER, border_col=AMBER),
]
))
story.append(sp(8))
# ── FOOTER ───────────────────────────────────────────────────────────────────
story.append(hr())
story.append(Paragraph(
"References: Bradley & Daroff's Neurology in Clinical Practice 8e (Chapter 44) | "
"Adams & Victor's Principles of Neurology 12e | "
"Tietz Textbook of Laboratory Medicine 7e (Chapter 68) | "
"Robbins & Kumar Basic Pathology | Goldman-Cecil Medicine | "
"Harrison's Principles of Internal Medicine 22e | Emery's Elements of Medical Genetics and Genomics | "
"DSM-5",
FOOT))
# ── BUILD ─────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"Generated: {OUTPUT}")
cd /home/daytona/workspace/hyperkinetic-movements && python hd_tutorial.py 2>&1
ls -lh /home/daytona/workspace/hyperkinetic-movements/HD_Diagnostic_Tutorial.pdf
HD Diagnostic Tutorial
PDF Document · PDF
| Question | Topic |
|---|---|
| Q1 | Most likely diagnosis + two family history features supporting it |
| Q2 | 5 cardinal exam findings + pathophysiology of trombone tongue |
| Q3 | Confirmatory investigation + how to interpret CAG repeat result |
| Question | Topic |
|---|---|
| Q4 | Prior risk calculation (50%) + minimum age for testing |
| Q5 | Full 9-step presymptomatic testing protocol + ethical safeguards |
| Q6 | Result interpretation (CAG 18 and 48) + explanation of anticipation |
| Question | Topic |
|---|---|
| Q7 | Diagnosis + why rigid not choreic + circuit pathophysiology |
| Q8 | 5 differential diagnoses with distinguishing features and investigations |