Describe all the small muscle of hand and it’s action and it’s function in daily life and test to detect it weakness and how to describe power of small muscle of hand

Reading File
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Finding Sources
Reading File
Reading File
Finding Sources
Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Searching Images

intrinsic muscles of hand thenar hypothenar lumbricals interossei anatomy diagram

Loading Image
Loading Image
Loading Image
I now have all the information needed. Here is a comprehensive, structured answer:

Small Muscles of the Hand (Intrinsic Muscles)

The intrinsic muscles of the hand are those with both origin and insertion within the hand itself. They are grouped into four compartments: Thenar, Hypothenar, Lumbricals, and Interossei.

Anatomical Overview

Thenar and hypothenar muscles — schematic palmar view
① Abductor pollicis brevis ② Adductor pollicis ③ Flexor pollicis brevis ④ Opponens pollicis ⑤ Abductor digiti minimi ⑥ Flexor digiti minimi brevis ⑦ Opponens digiti minimi
Lumbricals and palmar/dorsal interossei — palmar schematic
① Lumbricals ② Palmar interossei ③ Dorsal interossei

GROUP 1 — THENAR MUSCLES (Thumb eminence)

All except adductor pollicis are innervated by the median nerve (C8, T1). The thumb has its own special intrinsic group because of the enormous range and complexity of thumb motion.

1. Abductor Pollicis Brevis (APB)

FeatureDetail
OriginScaphoid, trapezium, flexor retinaculum
InsertionBase of proximal phalanx of thumb (radial sesamoid)
ActionAbduction of thumb (lifts thumb perpendicular to palm)
NerveMedian nerve (C8, T1)
Daily functionOpening a jar, pinching a key, holding a phone, picking up small objects

2. Opponens Pollicis

FeatureDetail
OriginTrapezium, flexor retinaculum
InsertionRadial border of 1st metacarpal
ActionOpposition of thumb at CMC joint (rotates thumb to face fingers)
NerveMedian nerve (C8, T1)
Daily functionThe most critical muscle for grip — buttoning a shirt, writing, pinch grip for holding a pen

3. Flexor Pollicis Brevis (FPB)

FeatureDetail
OriginSuperficial head: flexor retinaculum; Deep head: capitate, trapezium
InsertionBase of proximal phalanx of thumb (radial sesamoid)
ActionFlexion + opposition at CMC joint; Flexion at MCP joint
NerveSuperficial head: Median nerve (C8, T1); Deep head: Ulnar nerve (C8, T1)
Daily functionGripping a steering wheel, holding scissors, power pinch

4. Adductor Pollicis

FeatureDetail
OriginTransverse head: palmar surface of 3rd metacarpal; Oblique head: capitate, base of 2nd & 3rd metacarpals
InsertionBase of proximal phalanx of thumb (ulnar sesamoid)
ActionOpposition at CMC joint; Flexion at MCP joint; Adducts thumb toward palm
NerveUlnar nerve (C8, T1)
Daily functionHolding a key, pinching coins, squeezing a bottle cap

GROUP 2 — HYPOTHENAR MUSCLES (Little finger eminence)

All innervated by the ulnar nerve (C8, T1). They originate from the flexor retinaculum and carpal bones and insert on the ulnar side of the little finger and 5th metacarpal.

5. Abductor Digiti Minimi (ADM)

FeatureDetail
OriginPisiform
InsertionUlnar base of proximal phalanx of 5th digit + dorsal digital expansion
ActionAbduction + flexion at MCP joint of little finger; Extension at PIP/DIP
NerveUlnar nerve (C8, T1)
Daily functionSpreading fingers wide (keyboard use), stabilizing the little finger during grip

6. Flexor Digiti Minimi Brevis (FDMB)

FeatureDetail
OriginHook of hamate, flexor retinaculum
InsertionBase of proximal phalanx of 5th digit
ActionFlexion at MCP joint of little finger
NerveUlnar nerve (C8, T1)
Daily functionStarting a flexion grip on the little finger side, as in wringing a cloth

7. Opponens Digiti Minimi (ODM)

FeatureDetail
OriginHook of hamate, flexor retinaculum
InsertionUlnar border of 5th metacarpal
ActionDraws 5th metacarpal in the palmar direction (cups the palm)
NerveUlnar nerve (C8, T1)
Daily functionCupping the palm to hold water or small objects; holding a can

GROUP 3 — LUMBRICALS (4 muscles)

Unique muscles — they arise from tendons (FDP), not bone, and insert into the extensor expansion. They do not attach to any bone.
1st & 2nd Lumbrical3rd & 4th Lumbrical
OriginRadial sides of FDP tendons to index & middle fingersRadial sides of FDP tendons to ring & little fingers
InsertionDorsal digital expansion (radial side) of digits 2–5Same
ActionsMCP flexion + PIP/DIP extension of digits 2–5Same
NerveMedian nerve (C8, T1)Ulnar nerve (C8, T1)
The lumbrical position (MCP flexed + IP joints extended) is the most precise, functional position of the hand.
Daily life: Typing on a keyboard, turning pages of a book, playing the piano, writing — any task requiring the "intrinsic plus" position. Damage causes an "intrinsic minus" or claw hand deformity.

GROUP 4 — INTEROSSEI

Dorsal Interossei (4 muscles — DAB: Dorsal ABduct)

FeatureDetail
OriginBy two heads from adjacent sides of metacarpals 1–5
InsertionDorsal digital expansion + base of proximal phalanx (radial side of index & middle; ulnar side of middle & ring)
ActionMCP flexion; PIP/DIP extension; Abduction of fingers from middle finger axis
NerveUlnar nerve (C8, T1)

Palmar Interossei (3 muscles — PAD: Palmar ADduct)

FeatureDetail
Origin1st: ulnar side of 2nd metacarpal; 2nd: radial side of 4th metacarpal; 3rd: radial side of 5th metacarpal
InsertionDorsal digital expansion + base of proximal phalanx
ActionMCP flexion; PIP/DIP extension; Adduction of fingers toward middle finger axis
NerveUlnar nerve (C8, T1)
Daily life: Spreading fingers to span an octave on piano (dorsal); holding a newspaper between fingers; pinching a pen (palmar); making a "scissors" gesture.

DAILY LIFE FUNCTIONS — Summary

TaskPrimary Intrinsic Muscles Involved
Writing with a penOpponens pollicis, APB, FPB, lumbricals, palmar interossei
Pinching coinsAdductor pollicis, APB, FPB
Power grip (hammer)All intrinsics + extrinsics; interossei + hypothenar stabilize
TypingLumbricals (MCP flex + IP extend position), dorsal interossei (abduction)
Playing pianoLumbricals, dorsal interossei (finger spread), opponens pollicis
Buttoning a shirtOpponens pollicis, APB, 1st & 2nd lumbricals
Cupping palmOpponens digiti minimi, hypothenar group
Turning a pageLumbricals, palmar interossei (adduction)

SIGNS & TESTS TO DETECT INTRINSIC WEAKNESS

Inspection

  • Thenar wasting: Flattening of the thenar eminence → median nerve palsy (carpal tunnel syndrome, C8/T1 lesion)
  • Hypothenar wasting: Flattening ulnar side → ulnar nerve palsy
  • Dorsal guttering: Hollowing between metacarpals on the dorsum → interossei atrophy (ulnar nerve palsy)
  • Claw hand (main en griffe): MCP hyperextension + IP flexion at ring/little fingers → ulnar nerve palsy (loss of lumbricals 3 & 4 and interossei)
Claw hand deformity — ulnar nerve palsy showing MCP hyperextension and IP flexion with hypothenar and interosseous wasting

Specific Clinical Tests

TestTechniquePositive FindingMuscle/Nerve Tested
Froment's signPatient grips a sheet of paper between thumb and index finger; examiner pulls paper awayThumb IP joint flexes (FPL compensates for absent adductor pollicis)Adductor pollicis / Ulnar nerve
Wartenberg's signPatient holds fingers together; little finger abducts involuntarilyLittle finger drifts into abductionInterossei (ulnar nerve); unopposed ADM
Card test (paper grip)Card placed between extended adjacent fingers; examiner pulls card outCannot hold card against resistancePalmar interossei / Ulnar nerve
Finger abduction testPatient spreads fingers wide against resistanceInability/weaknessDorsal interossei / Ulnar nerve
Opposition testPatient touches thumb tip to little finger tip against resistanceWeakness or inability to opposeOpponens pollicis / Median nerve
Thumb abduction test (APB)Patient holds palm flat, lifts thumb perpendicular to palm against examiner resistanceWeakness → thenar wastingAPB / Median nerve
Pen-touch test (Ochsner's clasping test)Patient clasps hands together; if FPL substitutes for absent index FDP, index stays straightIndex finger does not flexTests AIN/median nerve integrity, reveals intrinsic-extrinsic balance
Intrinsic tightness test (Bunnell test)PIP is passively flexed with MCP extended, then with MCP flexedIf PIP only flexes freely when MCP flexed → intrinsic tightnessIntrinsic muscle contracture

GRADING POWER OF SMALL MUSCLES — MRC Scale

Muscle power is graded using the Medical Research Council (MRC) Scale:
GradeDescription
0No contraction at all
1Flicker or trace of contraction visible/palpable, but no movement
2Active movement possible with gravity eliminated (movement in horizontal plane)
3Active movement against gravity only (cannot overcome any added resistance)
4Active movement against gravity plus some resistance — subdivided: 4− (slight), 4 (moderate), 4+ (strong)
5Normal power against full resistance

How to Apply MRC Grading to Specific Intrinsic Muscles

APB (Median nerve — most tested in clinic):
  • Position: Hand flat on table, thumb pointing upward
  • Ask: "Lift your thumb toward the ceiling" — apply downward resistance
  • Palpate the thenar eminence for contraction
First Dorsal Interosseous (FDI — most visible interosseous, Ulnar nerve):
  • Position: Hand flat, fingers extended
  • Ask: "Push your index finger away from your middle finger (abduct)" against resistance
  • The FDI muscle belly is visible and palpable on the dorsal radial aspect of the hand
Adductor pollicis (Ulnar nerve):
  • Ask: "Hold this card between your thumb and index finger"
  • Look for Froment's sign (IP flexion of thumb) as compensation
Hypothenar (ADM, Ulnar nerve):
  • Ask: "Move your little finger away from the others" against resistance

Describing Power in Clinic

A complete description should include:
  1. Which muscle (e.g., first dorsal interosseous, APB)
  2. MRC grade (0–5)
  3. Side (right/left)
  4. Comparison to contralateral side
  5. Associated signs (wasting, claw, Froment's positive)
Example: "Right APB — MRC grade 3/5 with thenar wasting and no Froment's sign. Left APB — 5/5. Consistent with right median nerve motor dysfunction."

NERVE SUPPLY SUMMARY

NerveMuscles Supplied
Median nerve (C8, T1)APB, Opponens pollicis, FPB (superficial head), Lumbricals 1 & 2
Ulnar nerve (C8, T1)Adductor pollicis, FPB (deep head), ALL hypothenar muscles, ALL interossei, Lumbricals 3 & 4
Key rule: "Ulnar nerve does most of the intrinsic work" — it innervates 15 of the 20 intrinsic muscles. The median nerve is critical for thenar function and fine precision pinch.

Sources: General Anatomy and Musculoskeletal System — THIEME Atlas of Anatomy; Tintinalli's Emergency Medicine; Neuroanatomy through Clinical Cases 3rd Edition; Imaging Anatomy Vol. 3 — THIEME

Create a clinical examination checklist PDF for testing all intrinsic hand muscles

Reading File
Running Command

ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace not found"

Running Command

mkdir -p /home/daytona/workspace/hand-exam-checklist && python3 -c "import reportlab; print('reportlab OK')"

Writing File

~/hand-exam-checklist/generate_checklist.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm, cm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.pdfgen import canvas
from reportlab.platypus import BaseDocTemplate, PageTemplate, Frame

OUTPUT = "/home/daytona/workspace/hand-exam-checklist/Intrinsic_Hand_Muscles_Examination_Checklist.pdf"

# ── Colour palette ──────────────────────────────────────────────────────────
NAVY      = colors.HexColor("#1B3A5C")
TEAL      = colors.HexColor("#1E7A8F")
TEAL_LITE = colors.HexColor("#D6EEF3")
AMBER     = colors.HexColor("#E8A020")
AMBER_LITE= colors.HexColor("#FFF4DC")
GREEN     = colors.HexColor("#2E7D32")
RED_LITE  = colors.HexColor("#FDECEA")
GREY_LITE = colors.HexColor("#F4F6F8")
GREY_MID  = colors.HexColor("#D0D7E0")
WHITE     = colors.white
BLACK     = colors.HexColor("#1A1A1A")

PAGE_W, PAGE_H = A4
MARGIN = 1.5 * cm

# ── Styles ──────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

def sty(name, **kw):
    return ParagraphStyle(name, **kw)

TITLE = sty("TITLE", fontName="Helvetica-Bold", fontSize=18,
            textColor=WHITE, alignment=TA_CENTER, leading=22, spaceAfter=2)
SUBTITLE = sty("SUBTITLE", fontName="Helvetica", fontSize=10,
               textColor=colors.HexColor("#CCE8F0"), alignment=TA_CENTER, leading=13)
DATE_STYLE = sty("DATE_STYLE", fontName="Helvetica", fontSize=8,
                 textColor=GREY_MID, alignment=TA_CENTER)

H1 = sty("H1", fontName="Helvetica-Bold", fontSize=11,
         textColor=WHITE, leading=14, alignment=TA_LEFT)
H2 = sty("H2", fontName="Helvetica-Bold", fontSize=9,
         textColor=NAVY, leading=12, spaceBefore=3, spaceAfter=1)
BODY = sty("BODY", fontName="Helvetica", fontSize=8,
           textColor=BLACK, leading=11)
BODY_BOLD = sty("BODY_BOLD", fontName="Helvetica-Bold", fontSize=8,
                textColor=BLACK, leading=11)
SMALL = sty("SMALL", fontName="Helvetica", fontSize=7,
            textColor=colors.HexColor("#555555"), leading=10)
NERVE_MED = sty("NERVE_MED", fontName="Helvetica-Bold", fontSize=7,
                textColor=colors.HexColor("#1565C0"), leading=10)
NERVE_ULN = sty("NERVE_ULN", fontName="Helvetica-Bold", fontSize=7,
                textColor=colors.HexColor("#6A1B9A"), leading=10)
WARN = sty("WARN", fontName="Helvetica-BoldOblique", fontSize=7.5,
           textColor=colors.HexColor("#B71C1C"), leading=11)

def checkbox():
    return "□"

def checked():
    return "☑"

# ── Helper: section header row ───────────────────────────────────────────────
def section_header(title, subtitle=""):
    cell_text = Paragraph(title, H1)
    sub_para  = Paragraph(subtitle, sty("SH_SUB", fontName="Helvetica",
                           fontSize=7.5, textColor=colors.HexColor("#A8D8E8"),
                           leading=11)) if subtitle else Paragraph("", SMALL)
    tbl = Table([[cell_text], [sub_para]],
                colWidths=[PAGE_W - 2*MARGIN])
    tbl.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), NAVY),
        ("BACKGROUND", (0,1), (-1,1), TEAL),
        ("LEFTPADDING",  (0,0), (-1,-1), 8),
        ("RIGHTPADDING", (0,0), (-1,-1), 8),
        ("TOPPADDING",   (0,0), (-1,-1), 5),
        ("BOTTOMPADDING",(0,0), (-1,-1), 4),
    ]))
    return tbl

# ── MRC Grade row ─────────────────────────────────────────────────────────────
def mrc_table():
    headers = ["Grade", "Description", "Functional Meaning"]
    rows = [
        ["0", "No contraction", "Complete paralysis"],
        ["1", "Flicker / trace only — no movement", "Visible or palpable twitch"],
        ["2", "Movement with gravity eliminated", "Horizontal plane movement only"],
        ["3", "Movement against gravity", "Cannot overcome any resistance"],
        ["4−/4/4+", "Movement vs. slight / moderate / strong resistance", "Reduced but present"],
        ["5", "Normal power", "Full resistance without break"],
    ]
    data = [headers] + rows
    col_w = [(PAGE_W - 2*MARGIN) * f for f in [0.10, 0.52, 0.38]]
    tbl = Table(data, colWidths=col_w)
    style = TableStyle([
        ("BACKGROUND",  (0,0), (-1,0), TEAL),
        ("TEXTCOLOR",   (0,0), (-1,0), WHITE),
        ("FONTNAME",    (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE",    (0,0), (-1,-1), 7.5),
        ("FONTNAME",    (0,1), (-1,-1), "Helvetica"),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_LITE]),
        ("GRID",        (0,0), (-1,-1), 0.4, GREY_MID),
        ("LEFTPADDING", (0,0), (-1,-1), 5),
        ("RIGHTPADDING",(0,0), (-1,-1), 5),
        ("TOPPADDING",  (0,0), (-1,-1), 3),
        ("BOTTOMPADDING",(0,0), (-1,-1), 3),
        ("ALIGN",       (0,0), (0,-1), "CENTER"),
        ("VALIGN",      (0,0), (-1,-1), "MIDDLE"),
        ("FONTNAME",    (0,4), (0,4), "Helvetica-Bold"),
        ("BACKGROUND",  (0,5), (-1,5), colors.HexColor("#E8F5E9")),
        ("FONTNAME",    (0,5), (-1,5), "Helvetica-Bold"),
    ])
    tbl.setStyle(style)
    return tbl

# ── Muscle examination table ──────────────────────────────────────────────────
def muscle_table(muscles):
    """
    muscles: list of dicts with keys:
      name, nerve, root, position, instruction, palpation, normal, r_grade, l_grade, notes
    """
    headers = ["Muscle", "Nerve\n(Root)", "Patient Position\n& Instruction",
               "Palpation / Trick", "R\nGrade", "L\nGrade", "Notes / Signs"]
    col_w = [(PAGE_W - 2*MARGIN) * f for f in [0.17, 0.10, 0.28, 0.19, 0.06, 0.06, 0.14]]
    data = [headers]
    for m in muscles:
        nerve_style = NERVE_MED if "Median" in m["nerve"] else NERVE_ULN
        data.append([
            Paragraph(f"<b>{m['name']}</b>", BODY_BOLD),
            Paragraph(f"<font color='#{('1565C0' if 'Median' in m['nerve'] else '6A1B9A')}'>"
                      f"<b>{m['nerve']}</b></font><br/>"
                      f"<font size='6.5'>{m['root']}</font>", SMALL),
            Paragraph(m["instruction"], BODY),
            Paragraph(m["palpation"], SMALL),
            Paragraph(checkbox(), sty("CB", fontName="Helvetica", fontSize=14,
                                      alignment=TA_CENTER, leading=16)),
            Paragraph(checkbox(), sty("CB2", fontName="Helvetica", fontSize=14,
                                      alignment=TA_CENTER, leading=16)),
            Paragraph(m.get("notes",""), SMALL),
        ])
    tbl = Table(data, colWidths=col_w, repeatRows=1)
    style = TableStyle([
        # Header
        ("BACKGROUND",   (0,0), (-1,0), TEAL),
        ("TEXTCOLOR",    (0,0), (-1,0), WHITE),
        ("FONTNAME",     (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE",     (0,0), (-1,0), 7.5),
        ("ALIGN",        (0,0), (-1,0), "CENTER"),
        # Body
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_LITE]),
        ("FONTSIZE",     (0,1), (-1,-1), 7.5),
        ("GRID",         (0,0), (-1,-1), 0.4, GREY_MID),
        ("LEFTPADDING",  (0,0), (-1,-1), 4),
        ("RIGHTPADDING", (0,0), (-1,-1), 4),
        ("TOPPADDING",   (0,0), (-1,-1), 3),
        ("BOTTOMPADDING",(0,0), (-1,-1), 3),
        ("VALIGN",       (0,0), (-1,-1), "TOP"),
        ("ALIGN",        (4,0), (5,-1), "CENTER"),
        ("ALIGN",        (4,1), (5,-1), "CENTER"),
        # Grade columns highlight
        ("BACKGROUND",   (4,0), (5,0), AMBER),
        ("TEXTCOLOR",    (4,0), (5,0), WHITE),
    ])
    tbl.setStyle(style)
    return tbl

# ── Special tests table ────────────────────────────────────────────────────────
def special_tests_table():
    headers = ["Test", "Technique", "Positive Finding", "Nerve / Muscle", "R □", "L □"]
    rows = [
        ["Froment's Sign",
         "Patient grips paper between thumb & index finger; examiner pulls paper",
         "Thumb IP flexes (FPL substitutes for weak adductor pollicis)",
         "Adductor pollicis\nUlnar nerve", checkbox(), checkbox()],
        ["Wartenberg's Sign",
         "Patient holds all fingers extended together; observe for 30 s",
         "Little finger drifts into abduction (ADM not opposed by 3rd palmar interosseous)",
         "Interossei / ADM\nUlnar nerve", checkbox(), checkbox()],
        ["Card Test\n(Palmar interossei)",
         "Slip paper card between two adjacent extended fingers; attempt to pull card out",
         "Cannot grip card — card slips out easily",
         "Palmar interossei\nUlnar nerve", checkbox(), checkbox()],
        ["Finger Abduction\n(Dorsal interossei)",
         "Patient spreads all fingers wide; examiner resists each abduction",
         "Weakness or inability to abduct fingers",
         "Dorsal interossei\nUlnar nerve", checkbox(), checkbox()],
        ["Opposition Test",
         "Patient touches thumb tip to little finger tip; examiner resists pinch",
         "Inability to complete full opposition; thenar flattening",
         "Opponens pollicis\nMedian nerve", checkbox(), checkbox()],
        ["APB Isolation Test",
         "Palm flat on table; patient lifts thumb perpendicular to palm against resistance",
         "MRC < 4; thenar wasting visible/palpable",
         "Abductor pollicis brevis\nMedian nerve", checkbox(), checkbox()],
        ["Bunnell Intrinsic\nTightness Test",
         "Passively flex PIP (1) with MCP extended, then (2) with MCP flexed",
         "PIP only flexes freely when MCP flexed → intrinsic tightness/contracture",
         "Intrinsic muscles\n(general)", checkbox(), checkbox()],
        ["OK / Circle Sign",
         "Ask patient to make 'OK' circle with thumb & index",
         "Cannot make circle — pinches side of index DIP instead → AIN palsy",
         "FPL + FDP index\nAnterior Interosseous N.", checkbox(), checkbox()],
        ["Grip Dynamometry",
         "Standardised hand-grip dynamometer, 3 attempts per side",
         "Record in kg; compare to normative values & contralateral side",
         "Overall intrinsic\n+ extrinsic", "___kg", "___kg"],
        ["Pinch Dynamometry",
         "Key/lateral pinch dynamometer; 3 attempts per side",
         "Record in kg; compare sides",
         "Adductor pollicis\nFPB / APB", "___kg", "___kg"],
    ]
    data = [headers] + rows
    col_w = [(PAGE_W - 2*MARGIN) * f for f in [0.16, 0.28, 0.24, 0.18, 0.07, 0.07]]
    tbl = Table(data, colWidths=col_w, repeatRows=1)
    style = TableStyle([
        ("BACKGROUND",   (0,0), (-1,0), NAVY),
        ("TEXTCOLOR",    (0,0), (-1,0), WHITE),
        ("FONTNAME",     (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE",     (0,0), (-1,-1), 7.5),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_LITE]),
        ("GRID",         (0,0), (-1,-1), 0.4, GREY_MID),
        ("FONTNAME",     (0,1), (-1,-1), "Helvetica"),
        ("LEFTPADDING",  (0,0), (-1,-1), 4),
        ("RIGHTPADDING", (0,0), (-1,-1), 4),
        ("TOPPADDING",   (0,0), (-1,-1), 3),
        ("BOTTOMPADDING",(0,0), (-1,-1), 3),
        ("VALIGN",       (0,0), (-1,-1), "TOP"),
        ("ALIGN",        (4,0), (5,-1), "CENTER"),
        ("FONTNAME",     (0,1), (0,-1), "Helvetica-Bold"),
        ("BACKGROUND",   (4,0), (5,0), AMBER),
    ])
    tbl.setStyle(style)
    return tbl

# ── Inspection checklist ────────────────────────────────────────────────────────
def inspection_table():
    items = [
        [checkbox(), "Thenar wasting (flattening of thenar eminence)",
         "Median nerve palsy / CTS / C8-T1 lesion", ""],
        [checkbox(), "Hypothenar wasting (ulnar eminence flattening)",
         "Ulnar nerve palsy at wrist or elbow", ""],
        [checkbox(), "Dorsal guttering (hollowing between metacarpals)",
         "Interossei atrophy — ulnar nerve palsy", ""],
        [checkbox(), "Claw hand (ring & little — MCP hyperext + IP flex)",
         "Low ulnar nerve palsy (ulnar paradox)", ""],
        [checkbox(), "Claw all fingers (index to little)",
         "High ulnar + median palsy OR C8/T1 lesion", ""],
        [checkbox(), "Ape thumb / flat hand (loss of thenar bulk + opposition)",
         "Median nerve palsy (recurrent branch)", ""],
        [checkbox(), "Simian hand (thumb in plane of palm, no abduction/opposition)",
         "Combined median + ulnar palsy", ""],
        [checkbox(), "Skin trophic changes / sweating abnormality",
         "Autonomic involvement — check nerve territory", ""],
    ]
    headers = ["□", "Finding", "Significance", "Side / Notes"]
    col_w = [(PAGE_W - 2*MARGIN) * f for f in [0.04, 0.42, 0.36, 0.18]]
    data = [headers] + items
    tbl = Table(data, colWidths=col_w, repeatRows=1)
    style = TableStyle([
        ("BACKGROUND",   (0,0), (-1,0), TEAL),
        ("TEXTCOLOR",    (0,0), (-1,0), WHITE),
        ("FONTNAME",     (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE",     (0,0), (-1,-1), 7.5),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_LITE]),
        ("GRID",         (0,0), (-1,-1), 0.4, GREY_MID),
        ("FONTNAME",     (0,1), (-1,-1), "Helvetica"),
        ("LEFTPADDING",  (0,0), (-1,-1), 4),
        ("RIGHTPADDING", (0,0), (-1,-1), 4),
        ("TOPPADDING",   (0,0), (-1,-1), 3),
        ("BOTTOMPADDING",(0,0), (-1,-1), 3),
        ("VALIGN",       (0,0), (-1,-1), "TOP"),
        ("ALIGN",        (0,1), (0,-1), "CENTER"),
        ("FONTSIZE",     (0,1), (0,-1), 12),
    ])
    tbl.setStyle(style)
    return tbl

# ── Nerve injury quick-ref ────────────────────────────────────────────────────
def nerve_ref_table():
    headers = ["Nerve Injured", "Level", "Intrinsic Muscles Lost", "Classic Sign"]
    rows = [
        ["Median nerve\n(recurrent motor branch)",
         "Wrist / carpal tunnel",
         "APB, Opponens pollicis, FPB (superficial), Lumb 1&2",
         "Ape hand; cannot oppose thumb"],
        ["Ulnar nerve",
         "Wrist (Guyon's canal)",
         "ALL hypothenar, ALL interossei, Adductor pollicis, FPB (deep), Lumb 3&4",
         "Claw hand (ring & little); Froment's +ve; dorsal guttering"],
        ["Ulnar nerve",
         "Elbow (cubital tunnel)",
         "Same as above + FCU + medial FDP",
         "Claw LESS pronounced (ulnar paradox — FDP also weak)"],
        ["Combined Median\n+ Ulnar",
         "Wrist",
         "All 20 intrinsic muscles",
         "Simian hand; no grip or pinch; complete intrinsic loss"],
        ["C8 / T1 roots\nor lower trunk",
         "Brachial plexus",
         "All intrinsics (both median + ulnar supply)",
         "Bilateral small hand wasting (Hirayama, Pancoast, etc.)"],
    ]
    data = [headers] + rows
    col_w = [(PAGE_W - 2*MARGIN) * f for f in [0.18, 0.14, 0.40, 0.28]]
    tbl = Table(data, colWidths=col_w, repeatRows=1)
    style = TableStyle([
        ("BACKGROUND",   (0,0), (-1,0), NAVY),
        ("TEXTCOLOR",    (0,0), (-1,0), WHITE),
        ("FONTNAME",     (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE",     (0,0), (-1,-1), 7.5),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_LITE]),
        ("GRID",         (0,0), (-1,-1), 0.4, GREY_MID),
        ("FONTNAME",     (0,1), (-1,-1), "Helvetica"),
        ("LEFTPADDING",  (0,0), (-1,-1), 4),
        ("RIGHTPADDING", (0,0), (-1,-1), 4),
        ("TOPPADDING",   (0,0), (-1,-1), 3),
        ("BOTTOMPADDING",(0,0), (-1,-1), 3),
        ("VALIGN",       (0,0), (-1,-1), "TOP"),
    ])
    tbl.setStyle(style)
    return tbl

# ── Patient info header ────────────────────────────────────────────────────────
def patient_info_table():
    row1 = [
        Paragraph("Patient Name: _______________________________", BODY),
        Paragraph("Date: _______________________", BODY),
        Paragraph("Examiner: _______________________", BODY),
    ]
    row2 = [
        Paragraph("Age: _____ / Sex: M □  F □  / Hand dominance: R □  L □", BODY),
        Paragraph("Diagnosis / Provisional: ________________________________", BODY),
        Paragraph("MRN / ID: _______________________", BODY),
    ]
    data = [row1, row2]
    col_w = [(PAGE_W - 2*MARGIN) * f for f in [0.40, 0.36, 0.24]]
    tbl = Table(data, colWidths=col_w)
    style = TableStyle([
        ("BOX",          (0,0), (-1,-1), 1, TEAL),
        ("INNERGRID",    (0,0), (-1,-1), 0.4, GREY_MID),
        ("BACKGROUND",   (0,0), (-1,-1), TEAL_LITE),
        ("LEFTPADDING",  (0,0), (-1,-1), 6),
        ("RIGHTPADDING", (0,0), (-1,-1), 6),
        ("TOPPADDING",   (0,0), (-1,-1), 5),
        ("BOTTOMPADDING",(0,0), (-1,-1), 5),
        ("FONTNAME",     (0,0), (-1,-1), "Helvetica"),
        ("FONTSIZE",     (0,0), (-1,-1), 8),
    ])
    tbl.setStyle(style)
    return tbl

# ── Summary score box ─────────────────────────────────────────────────────────
def summary_box():
    data = [
        [Paragraph("<b>EXAMINATION SUMMARY</b>", sty("SH", fontName="Helvetica-Bold",
                   fontSize=9, textColor=WHITE, alignment=TA_CENTER)), "", "", ""],
        [Paragraph("Thenar group (R/L): ___/___", BODY),
         Paragraph("Hypothenar group (R/L): ___/___", BODY),
         Paragraph("Lumbricals (R/L): ___/___", BODY),
         Paragraph("Interossei (R/L): ___/___", BODY)],
        [Paragraph("Grip dynamometry (R/L): ___ / ___ kg", BODY),
         Paragraph("Pinch dynamometry (R/L): ___ / ___ kg", BODY),
         Paragraph("Froment's □  Wartenberg's □  Card □", BODY),
         Paragraph("Nerve suspected: ___________________", BODY)],
        [Paragraph("Overall functional assessment: □ Normal  □ Mild loss  □ Moderate loss  □ Severe loss  □ Complete", BODY),
         "", "", ""],
        [Paragraph("Clinical impression / Plan:", BODY_BOLD),
         "", "", ""],
        [Paragraph("_" * 100, SMALL), "", "", ""],
    ]
    spans = [(0,0,3,0), (0,3,3,3), (0,4,3,4), (0,5,3,5)]
    col_w = [(PAGE_W - 2*MARGIN) * 0.25] * 4
    tbl = Table(data, colWidths=col_w)
    style = TableStyle([
        ("BACKGROUND",  (0,0), (-1,0), NAVY),
        ("TEXTCOLOR",   (0,0), (-1,0), WHITE),
        ("BACKGROUND",  (0,1), (-1,-1), AMBER_LITE),
        ("BOX",         (0,0), (-1,-1), 1, NAVY),
        ("INNERGRID",   (0,0), (-1,-1), 0.3, GREY_MID),
        ("LEFTPADDING", (0,0), (-1,-1), 6),
        ("RIGHTPADDING",(0,0), (-1,-1), 6),
        ("TOPPADDING",  (0,0), (-1,-1), 4),
        ("BOTTOMPADDING",(0,0), (-1,-1), 4),
        ("SPAN",        (0,0), (3,0)),
        ("SPAN",        (0,3), (3,3)),
        ("SPAN",        (0,4), (3,4)),
        ("SPAN",        (0,5), (3,5)),
    ])
    tbl.setStyle(style)
    return tbl

# ── Page number canvas ────────────────────────────────────────────────────────
def add_page_number(canvas, doc):
    canvas.saveState()
    canvas.setFont("Helvetica", 7)
    canvas.setFillColor(colors.HexColor("#888888"))
    canvas.drawRightString(PAGE_W - MARGIN, 0.7*cm,
        f"Page {doc.page}  |  Intrinsic Hand Muscles — Clinical Examination Checklist")
    canvas.drawString(MARGIN, 0.7*cm, "© Clinical Examination Tool — For Educational Use")
    canvas.restoreState()

# ── MAIN BUILD ────────────────────────────────────────────────────────────────
def build():
    doc = SimpleDocTemplate(
        OUTPUT,
        pagesize=A4,
        leftMargin=MARGIN, rightMargin=MARGIN,
        topMargin=MARGIN, bottomMargin=1.5*cm,
        title="Intrinsic Hand Muscles — Clinical Examination Checklist",
        author="Orris Clinical Tools",
    )

    story = []

    # ── TITLE BLOCK ─────────────────────────────────────────────────────────
    title_data = [[
        Paragraph("INTRINSIC HAND MUSCLES", TITLE),
        Paragraph("Clinical Examination Checklist", SUBTITLE),
        Paragraph("Thenar · Hypothenar · Lumbricals · Interossei", SUBTITLE),
        Paragraph("Nerve roots: C8, T1  |  Nerves: Median & Ulnar", DATE_STYLE),
    ]]
    title_tbl = Table([[
        Paragraph("INTRINSIC HAND MUSCLES", TITLE)],
        [Paragraph("Clinical Examination Checklist", SUBTITLE)],
        [Paragraph("Thenar · Hypothenar · Lumbricals · Interossei  |  Nerve roots: C8, T1", SUBTITLE)],
    ], colWidths=[PAGE_W - 2*MARGIN])
    title_tbl.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), NAVY),
        ("TOPPADDING",  (0,0), (-1,-1), 4),
        ("BOTTOMPADDING",(0,0), (-1,-1), 4),
        ("LEFTPADDING", (0,0), (-1,-1), 10),
        ("RIGHTPADDING",(0,0), (-1,-1), 10),
    ]))
    story.append(title_tbl)
    story.append(Spacer(1, 4*mm))

    # ── PATIENT INFO ─────────────────────────────────────────────────────────
    story.append(patient_info_table())
    story.append(Spacer(1, 4*mm))

    # ── STEP 1: INSPECTION ───────────────────────────────────────────────────
    story.append(section_header("STEP 1 — INSPECTION", "Observe both hands at rest, dorsum and palm"))
    story.append(Spacer(1, 2*mm))
    story.append(inspection_table())
    story.append(Spacer(1, 5*mm))

    # ── STEP 2: MRC GRADING REFERENCE ────────────────────────────────────────
    story.append(section_header("MRC POWER GRADING SCALE — Reference",
                                "Grade each muscle Right (R) and Left (L) using 0–5 scale"))
    story.append(Spacer(1, 2*mm))
    story.append(mrc_table())
    story.append(Spacer(1, 5*mm))

    # ── STEP 3: THENAR MUSCLES ───────────────────────────────────────────────
    story.append(section_header("STEP 2 — THENAR MUSCLES",
                                "Median nerve (C8, T1) — except adductor pollicis (ulnar)"))
    story.append(Spacer(1, 2*mm))

    thenar = [
        {
            "name": "Abductor Pollicis\nBrevis (APB)",
            "nerve": "Median", "root": "C8, T1",
            "instruction": (
                "Hand palm-up flat on table. Ask: 'Lift your thumb straight up toward "
                "the ceiling.' Examiner applies downward resistance at thumb proximal phalanx."
            ),
            "palpation": "Palpate lateral thenar eminence for muscle belly contraction.",
            "notes": "Most sensitive test for CTS motor loss.\nWasting = thenar flattening."
        },
        {
            "name": "Opponens\nPollicis (OP)",
            "nerve": "Median", "root": "C8, T1",
            "instruction": (
                "Ask patient to touch thumb tip to little finger tip. Examiner tries to "
                "pull thumb away from little finger. Assess rotational component of opposition."
            ),
            "palpation": "Palpate deep to APB along 1st metacarpal shaft.",
            "notes": "Loss = inability to rotate thumb pad-to-pad.\nKey for buttoning, writing."
        },
        {
            "name": "Flexor Pollicis\nBrevis (FPB)",
            "nerve": "Median\n(sup. head)\nUlnar\n(deep head)", "root": "C8, T1",
            "instruction": (
                "Ask patient to flex thumb at MCP joint (keeping IP extended). "
                "Examiner resists MCP flexion."
            ),
            "palpation": "Palpate medial thenar eminence proximal to MCP joint.",
            "notes": "Dual innervation; rarely completely lost in single nerve injury."
        },
        {
            "name": "Adductor\nPollicis (AP)",
            "nerve": "Ulnar", "root": "C8, T1",
            "instruction": (
                "Ask patient to grip paper between extended thumb and radial side of index "
                "finger. Examiner pulls paper out (Froment's test)."
            ),
            "palpation": "Palpate 1st web space on palmar aspect (deep to APB).",
            "notes": "Froment's +ve = IP flexion (FPL compensates).\nWasting = 1st web space hollowing."
        },
    ]
    story.append(muscle_table(thenar))
    story.append(Spacer(1, 5*mm))

    # ── STEP 3: HYPOTHENAR MUSCLES ───────────────────────────────────────────
    story.append(section_header("STEP 3 — HYPOTHENAR MUSCLES",
                                "All: Ulnar nerve (C8, T1) — originate from flexor retinaculum & hamate"))
    story.append(Spacer(1, 2*mm))

    hypothenar = [
        {
            "name": "Abductor Digiti\nMinimi (ADM)",
            "nerve": "Ulnar", "root": "C8, T1",
            "instruction": (
                "Hand flat on table. Ask patient to move little finger away from ring finger. "
                "Examiner resists at ulnar side of little finger proximal phalanx."
            ),
            "palpation": "Palpate ulnar border of the hand — ADM is the most superficial hypothenar muscle.",
            "notes": "Most accessible hypothenar muscle to test.\nFirst sign of ulnar motor loss at wrist."
        },
        {
            "name": "Flexor Digiti\nMinimi Brevis\n(FDMB)",
            "nerve": "Ulnar", "root": "C8, T1",
            "instruction": (
                "Ask patient to flex little finger at MCP joint against resistance "
                "while keeping PIP and DIP extended."
            ),
            "palpation": "Palpate volar-ulnar aspect of little finger base.",
            "notes": "Often tested with ADM together.\nWasting = hypothenar eminence flattening."
        },
        {
            "name": "Opponens Digiti\nMinimi (ODM)",
            "nerve": "Ulnar", "root": "C8, T1",
            "instruction": (
                "Ask patient to cup the palm (as if holding water). Examiner attempts to flatten "
                "the palm. Alternatively, ask patient to bring little finger toward thumb."
            ),
            "palpation": "Deep to ADM and FDMB along ulnar border of 5th metacarpal.",
            "notes": "Loss limits ability to cup palm.\nRelevant for holding bowls, jars, cans."
        },
    ]
    story.append(muscle_table(hypothenar))
    story.append(Spacer(1, 5*mm))

    # ── STEP 4: LUMBRICALS ───────────────────────────────────────────────────
    story.append(section_header("STEP 4 — LUMBRICAL MUSCLES (4)",
                                "1st & 2nd: Median nerve  |  3rd & 4th: Ulnar nerve  (C8, T1)"))
    story.append(Spacer(1, 2*mm))

    lumbricals = [
        {
            "name": "1st Lumbrical\n(Index finger)",
            "nerve": "Median", "root": "C8, T1",
            "instruction": (
                "Ask patient to flex index finger MCP joint to 90° while keeping "
                "PIP and DIP joints fully extended ('tabletop position'). "
                "Examiner resists MCP flexion."
            ),
            "palpation": "Arise from FDP tendons — palpate in palm radial to index metacarpal.",
            "notes": "Tests 'intrinsic plus' position.\nLoss → index claw tendency."
        },
        {
            "name": "2nd Lumbrical\n(Middle finger)",
            "nerve": "Median", "root": "C8, T1",
            "instruction": (
                "Same as above for middle finger — MCP flexion with PIP/DIP extended. "
                "Resist at proximal phalanx."
            ),
            "palpation": "Palpate in palm just ulnar to 2nd metacarpal.",
            "notes": "Fine motor tasks (typing, writing) depend heavily on 2nd lumbrical."
        },
        {
            "name": "3rd Lumbrical\n(Ring finger)",
            "nerve": "Ulnar", "root": "C8, T1",
            "instruction": (
                "'Tabletop position' for ring finger. MCP to 90°, PIP/DIP straight. "
                "Resist at proximal phalanx."
            ),
            "palpation": "Palpate radial to 4th metacarpal in palm.",
            "notes": "Loss contributes to ring finger clawing in ulnar nerve palsy."
        },
        {
            "name": "4th Lumbrical\n(Little finger)",
            "nerve": "Ulnar", "root": "C8, T1",
            "instruction": (
                "'Tabletop position' for little finger. Resist MCP flexion while "
                "checking PIP/DIP remain extended."
            ),
            "palpation": "Palpate radial to 5th metacarpal.",
            "notes": "Loss → greatest claw in little finger.\nMost pronounced in low ulnar palsy."
        },
    ]
    story.append(muscle_table(lumbricals))

    # Lumbrical note
    story.append(Spacer(1, 2*mm))
    note_data = [[Paragraph(
        "⚠  CLINICAL NOTE — INTRINSIC PLUS POSITION: MCP flexed + PIP/DIP extended. "
        "Loss of lumbrical function produces the opposite: MCP hyperextended + IP flexed = "
        "<b>CLAW HAND (intrinsic minus)</b>. In ulnar palsy this affects ring & little fingers "
        "(3rd & 4th lumbricals lost). In combined palsy all 4 fingers claw.", WARN)]]
    note_tbl = Table(note_data, colWidths=[PAGE_W - 2*MARGIN])
    note_tbl.setStyle(TableStyle([
        ("BACKGROUND",   (0,0), (-1,-1), RED_LITE),
        ("BOX",          (0,0), (-1,-1), 1, colors.HexColor("#EF9A9A")),
        ("LEFTPADDING",  (0,0), (-1,-1), 8),
        ("RIGHTPADDING", (0,0), (-1,-1), 8),
        ("TOPPADDING",   (0,0), (-1,-1), 5),
        ("BOTTOMPADDING",(0,0), (-1,-1), 5),
    ]))
    story.append(note_tbl)
    story.append(Spacer(1, 5*mm))

    # ── STEP 5: INTEROSSEI ───────────────────────────────────────────────────
    story.append(section_header("STEP 5 — INTEROSSEI MUSCLES (7)",
                                "All: Ulnar nerve (C8, T1)  |  DAB = Dorsal ABduct  |  PAD = Palmar ADduct"))
    story.append(Spacer(1, 2*mm))

    interossei = [
        {
            "name": "1st Dorsal\nInterosseous\n(FDI)",
            "nerve": "Ulnar", "root": "C8, T1",
            "instruction": (
                "Hand flat palm-down. Ask patient to move index finger away from middle "
                "finger (radially). Examiner resists at radial side of index proximal phalanx."
            ),
            "palpation": "Most accessible interosseous — palpate belly in dorsal 1st web space.",
            "notes": "Most testable interosseous.\nWasting → 1st web space hollowing."
        },
        {
            "name": "2nd–4th Dorsal\nInterossei",
            "nerve": "Ulnar", "root": "C8, T1",
            "instruction": (
                "2nd: middle finger abducts radially. 3rd: middle finger abducts ulnarly. "
                "4th: ring finger abducts ulnarly. Test each against resistance. "
                "Alternatively: patient spreads all fingers against examiner's resistance."
            ),
            "palpation": "Palpate respective intermetacarpal spaces on dorsum.",
            "notes": "Dorsal guttering on dorsum = wasting.\nTest all with 'spread fingers' command."
        },
        {
            "name": "1st–3rd Palmar\nInterossei",
            "nerve": "Ulnar", "root": "C8, T1",
            "instruction": (
                "Card test: slip paper between adjacent extended fingers; "
                "examiner pulls card while patient grips. "
                "Or: ask patient to adduct each finger toward middle finger against resistance."
            ),
            "palpation": "Lie in intermetacarpal spaces on palmar side — difficult to palpate directly.",
            "notes": "Card test: cannot grip = palmar interosseous weakness.\nAdduction tested against dorsal interossei abduction."
        },
    ]
    story.append(muscle_table(interossei))
    story.append(Spacer(1, 5*mm))

    # ── STEP 6: SPECIAL TESTS ─────────────────────────────────────────────────
    story.append(section_header("STEP 6 — SPECIAL CLINICAL TESTS",
                                "Functional & provocation tests for intrinsic muscle integrity"))
    story.append(Spacer(1, 2*mm))
    story.append(special_tests_table())
    story.append(Spacer(1, 5*mm))

    # ── NERVE QUICK REFERENCE ────────────────────────────────────────────────
    story.append(section_header("NERVE INJURY QUICK REFERENCE",
                                "Expected intrinsic muscle loss by nerve level"))
    story.append(Spacer(1, 2*mm))
    story.append(nerve_ref_table())
    story.append(Spacer(1, 5*mm))

    # ── SUMMARY BOX ──────────────────────────────────────────────────────────
    story.append(summary_box())
    story.append(Spacer(1, 3*mm))

    # ── FINAL NOTE ────────────────────────────────────────────────────────────
    footer_note = Paragraph(
        "For educational and clinical reference use only. Always correlate with full history, "
        "sensory examination, nerve conduction studies, and imaging as appropriate. "
        "MRC grading should be performed with the patient seated comfortably, with gravity "
        "appropriately eliminated for grades 0–2.",
        sty("FN", fontName="Helvetica-Oblique", fontSize=7,
            textColor=colors.HexColor("#666666"), alignment=TA_CENTER, leading=10)
    )
    story.append(footer_note)

    doc.build(story, onFirstPage=add_page_number, onLaterPages=add_page_number)
    print(f"PDF created: {OUTPUT}")

build()
Running Command

cd /home/daytona/workspace/hand-exam-checklist && python3 generate_checklist.py 2>&1

Your credits are exhausted. Your daily credits reset tomorrow, or you can purchase a top-up for more.

How to describe power of small muscle of hand ,all muscle power or specific ? in clinical examination

Your credits are exhausted. Your daily credits reset tomorrow, or you can purchase a top-up for more.
This is a shared conversation. Sign in to Orris to start your own chat.