What is the diagnosis. Read mri report a orthopaedic diagnosis
| Structure | Finding |
|---|---|
| ACL / PCL | Normal |
| Medial & Lateral Collateral Ligaments | Normal |
| Menisci (medial & lateral) | Normal |
| Joint Effusion | Mild effusion present |
| Inferomedial Patella | Irregular with adjacent marrow edema |
| Lateral Femoral Condyle (anterior aspect) | Marrow edema + cortical flattening & irregularity |
| Articular Cartilage | Fairly preserved |
| Patellar / Quadriceps Tendon | Normal signal intensity |
| Medial Patellar Retinaculum | Focal high signal - partial tear |
| TT-TG Distance | 1.3 cm (normal, <2 cm) |
| Osteophytic Lipping | Present at articular margins |
| Diagnosis | Confidence |
|---|---|
| Transient lateral patellar dislocation (self-reduced) | High - classic MRI triad |
| Medial patellar retinaculum partial tear | Confirmed on MRI |
| Osteochondral injury - inferomedial patella + lateral femoral condyle | Confirmed on MRI + CT |
| Loose bodies (free osteochondral fragments) | Confirmed on CT |
| Mild traumatic joint effusion (haemarthrosis likely) | Confirmed on MRI |
Do it
"patellar dislocation" AND "rehabilitation" AND "physiotherapy"
PMID: 37254200
"osteochondral injury" AND "knee" AND "rehabilitation"
mkdir -p /tmp/workspace/ronald-physio && ls /tmp/workspace/
~/ronald-physio/generate_plan.py
from docx import Document
from docx.shared import Pt, Inches, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
import datetime
doc = Document()
# ── Page margins ──────────────────────────────────────────────────────────────
for section in doc.sections:
section.top_margin = Inches(0.9)
section.bottom_margin = Inches(0.9)
section.left_margin = Inches(1.0)
section.right_margin = Inches(1.0)
# ── Default font ──────────────────────────────────────────────────────────────
normal = doc.styles["Normal"]
normal.font.name = "Calibri"
normal.font.size = Pt(11)
# ─────────────────────────────────────────────────────────────────────────────
# Helper functions
# ─────────────────────────────────────────────────────────────────────────────
def add_heading(doc, text, level=1, color=None):
h = doc.add_heading(text, level=level)
h.alignment = WD_ALIGN_PARAGRAPH.LEFT
for run in h.runs:
if color:
run.font.color.rgb = RGBColor(*color)
run.font.bold = True
return h
def add_para(doc, text, bold=False, italic=False, indent=False):
p = doc.add_paragraph()
if indent:
p.paragraph_format.left_indent = Inches(0.25)
run = p.add_run(text)
run.bold = bold
run.italic = italic
return p
def add_bullet(doc, text, level=0):
p = doc.add_paragraph(style="List Bullet")
p.paragraph_format.left_indent = Inches(0.25 + 0.2 * level)
p.add_run(text)
def add_table_row(table, cells, bold_first=False):
row = table.add_row()
for i, (cell, text) in enumerate(zip(row.cells, cells)):
cell.text = text
for para in cell.paragraphs:
for run in para.runs:
if bold_first and i == 0:
run.bold = True
run.font.size = Pt(10)
return row
def shade_row(row, fill_hex):
"""Apply background shading to all cells of a row."""
for cell in row.cells:
tc = cell._tc
tcPr = tc.get_or_add_tcPr()
shd = OxmlElement("w:shd")
shd.set(qn("w:val"), "clear")
shd.set(qn("w:color"), "auto")
shd.set(qn("w:fill"), fill_hex)
tcPr.append(shd)
def set_col_widths(table, widths):
for row in table.rows:
for i, cell in enumerate(row.cells):
if i < len(widths):
cell.width = Inches(widths[i])
# ─────────────────────────────────────────────────────────────────────────────
# HEADER BANNER
# ─────────────────────────────────────────────────────────────────────────────
title_para = doc.add_paragraph()
title_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = title_para.add_run("PHYSIOTHERAPY TREATMENT PLAN")
run.bold = True
run.font.size = Pt(18)
run.font.color.rgb = RGBColor(0x1A, 0x53, 0x76) # dark blue
sub = doc.add_paragraph()
sub.alignment = WD_ALIGN_PARAGRAPH.CENTER
sub_run = sub.add_run("Right Knee - Osteochondral Injury & Medial Patellar Retinaculum Partial Tear")
sub_run.italic = True
sub_run.font.size = Pt(13)
sub_run.font.color.rgb = RGBColor(0x44, 0x44, 0x44)
doc.add_paragraph()
# ─────────────────────────────────────────────────────────────────────────────
# PATIENT DETAILS TABLE
# ─────────────────────────────────────────────────────────────────────────────
add_heading(doc, "1. Patient Information", level=2, color=(0x1A, 0x53, 0x76))
info_table = doc.add_table(rows=1, cols=4)
info_table.style = "Table Grid"
shade_row(info_table.rows[0], "1A5376")
hdr = info_table.rows[0].cells
for cell, text in zip(hdr, ["Field", "Details", "Field", "Details"]):
cell.text = text
for para in cell.paragraphs:
for run in para.runs:
run.bold = True
run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
run.font.size = Pt(10)
rows = [
("Name", "Ronald Lancy D Costa", "Age / Gender", "33 Years / Male"),
("Diagnosis", "Osteochondral Injury R knee + Medial Patellar Retinaculum Partial Tear + Mild Joint Effusion + Free Osteochondral Fragments",
"Imaging", "MRI + CT Right Knee (28/04/2025)"),
("Mechanism", "Skidded & twisted right leg while walking (3 weeks prior)", "Referring Physician", "Dr. Surendra U Kamath"),
("Plan Date", "30/04/2025", "Physiotherapist","Dr. Nikitha (PT)"),
("Occupation", "Office Worker", "Facility", "Alva's Physiotherapy Center, Moodbidri"),
]
for r in rows:
row = info_table.add_row()
for i, (cell, text) in enumerate(zip(row.cells, r)):
cell.text = text
for para in cell.paragraphs:
for run in para.runs:
run.bold = (i % 2 == 0)
run.font.size = Pt(10)
doc.add_paragraph()
# ─────────────────────────────────────────────────────────────────────────────
# MRI FINDINGS SUMMARY
# ─────────────────────────────────────────────────────────────────────────────
add_heading(doc, "2. MRI / CT Findings Summary", level=2, color=(0x1A, 0x53, 0x76))
mri_table = doc.add_table(rows=1, cols=3)
mri_table.style = "Table Grid"
shade_row(mri_table.rows[0], "2E86AB")
for cell, text in zip(mri_table.rows[0].cells, ["Structure", "Finding", "Clinical Relevance"]):
cell.text = text
for para in cell.paragraphs:
for run in para.runs:
run.bold = True
run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
run.font.size = Pt(10)
mri_data = [
("ACL / PCL", "Normal", "No instability"),
("Collateral Ligaments", "Normal", "No valgus/varus laxity"),
("Menisci", "Normal", "No meniscal pathology"),
("Inferomedial Patella", "Irregular + Marrow Edema", "Osteochondral injury site"),
("Lateral Femoral Condyle", "Cortical flattening + Marrow Edema","Impact site - patellar dislocation"),
("Medial Patellar Retinaculum", "Focal high signal - Partial Tear", "Source of medial knee pain & instability"),
("Joint Effusion", "Mild", "Haemarthrosis - limits ROM"),
("Free Osteochondral Fragments", "0.2x0.2cm & 0.1x0.1cm (CT)", "Loose bodies - risk of locking"),
("Patellar/Quad Tendon", "Normal", "No tendon rupture"),
("TT-TG Distance", "1.3 cm (Normal)", "No bony malalignment"),
]
for i, (s, f, c) in enumerate(mri_data):
row = mri_table.add_row()
row.cells[0].text = s
row.cells[1].text = f
row.cells[2].text = c
if i % 2 == 0:
shade_row(row, "EAF4FB")
for cell in row.cells:
for para in cell.paragraphs:
for run in para.runs:
run.font.size = Pt(10)
doc.add_paragraph()
# ─────────────────────────────────────────────────────────────────────────────
# GOALS OF TREATMENT
# ─────────────────────────────────────────────────────────────────────────────
add_heading(doc, "3. Goals of Physiotherapy", level=2, color=(0x1A, 0x53, 0x76))
goals = [
("Short-Term (0-4 weeks)",
["Reduce pain and joint effusion",
"Restore normal gait pattern",
"Achieve 0-90 degrees knee flexion",
"Prevent quadriceps wasting",
"Protect healing retinaculum"]),
("Medium-Term (4-8 weeks)",
["Full pain-free range of motion (0-135 degrees)",
"Regain quadriceps (VMO) strength to 70% of uninvolved side",
"Normal stair climbing and sit-to-stand",
"Improve patellar tracking"]),
("Long-Term (8-16 weeks)",
["Full functional return to work and daily activities",
"Prevent patellar re-dislocation",
"Quadriceps strength equal to uninvolved side",
"Return to recreational activities if desired"]),
]
for phase, items in goals:
p = doc.add_paragraph()
run = p.add_run(f" {phase}:")
run.bold = True
run.font.color.rgb = RGBColor(0x1A, 0x53, 0x76)
for item in items:
add_bullet(doc, item)
doc.add_paragraph()
# ─────────────────────────────────────────────────────────────────────────────
# TREATMENT PROTOCOL - PHASE TABLE
# ─────────────────────────────────────────────────────────────────────────────
add_heading(doc, "4. Phased Treatment Protocol", level=2, color=(0x1A, 0x53, 0x76))
phases = [
{
"phase": "PHASE 1 - Acute / Protective Phase (Weeks 1-2)",
"color": "C0392B", # red
"precautions": "Protect retinaculum. Avoid deep flexion >70°. Non-weight bearing or partial weight bearing as tolerated. Patellar brace/taping at all times.",
"modalities": [
"Cryotherapy (ice pack) 15-20 min, 4-5x/day over knee joint",
"Transcutaneous Electrical Nerve Stimulation (TENS) for pain relief - 80-100 Hz, 30 min",
"Interferential Therapy (IFT) for swelling reduction - 4000 Hz carrier, 80-100 Hz AMF, 20 min",
"Ultrasound therapy (pulsed 1:4) over medial retinaculum - 1 MHz, 0.5-0.8 W/cm², 5 min",
"Elevation of limb at rest",
"Gentle patellar mobilisation (Grade I-II medial glides only)",
],
"exercises": [
"Ankle pumps and foot circles - 3x20 reps hourly",
"Isometric quadriceps sets (quad sets) in extension - 10 sec hold, 3x15",
"Straight leg raises (SLR) - 3x10 reps (pain-free only)",
"Isometric hip abduction - 3x10",
"Terminal knee extensions (last 15°) - 3x15",
"Seated knee extension 0-45° arc only",
],
"outcome": "Pain VAS ≤3/10 at rest, effusion reduced, SLR without lag",
},
{
"phase": "PHASE 2 - Sub-Acute / Strengthening Phase (Weeks 3-6)",
"color": "E67E22", # orange
"precautions": "Continue patellar brace. Avoid impact activities. Flexion progressed to 90° then 120°. Begin partial weight bearing progressing to full.",
"modalities": [
"IFT for residual swelling - reduce frequency as swelling resolves",
"Ultrasound (pulsed → continuous) over retinaculum as healing progresses",
"Moist heat before exercise if stiffness present",
"Therapeutic taping: McConnell medial glide taping for patellar alignment",
"Manual therapy: patellar mobilisation Grade III, tibiofemoral joint mobilisation",
],
"exercises": [
"Supine heel slides - ROM progression 0-120°",
"Short arc quads (0-60°) - 3x15",
"Mini squats 0-45° with wall support - 3x15",
"Straight leg raises in all planes (hip flex, ext, abd, add) - 3x15",
"Step-ups (low 4-inch step) - 3x10 each leg",
"Hamstring curls prone - 3x15",
"VMO biofeedback training with surface EMG (if available)",
"Stationary cycling (low resistance, seat height adjusted) - 15 min",
"Proprioception: single leg balance on firm surface - 3x30 sec",
"Closed kinetic chain exercises: leg press (0-60° only)",
],
"outcome": "Knee flexion 120°, normal gait without limp, able to perform SLR without pain",
},
{
"phase": "PHASE 3 - Functional / Neuromuscular Phase (Weeks 7-12)",
"color": "1E8449", # green
"precautions": "Discontinue brace (or wean). No running until full quad strength. Monitor for any loose body symptoms (locking, catching - refer back to orthopaedic if these develop).",
"modalities": [
"Continue taping as needed for activity",
"Deep tissue massage to lateral retinaculum if tightness present",
"Ultrasound if residual soft tissue tightness",
],
"exercises": [
"Full squat progression (0-90°, then 0-120°) - 3x15",
"Lunges forward and lateral - 3x12",
"Step-ups and step-downs (8-inch step) - 3x15",
"Leg press full range - 3x15",
"Hamstring strengthening: Nordic curls, hamstring curls - 3x12",
"Hip strengthening: clamshells, resistance band abduction - 3x15",
"Balance and proprioception: wobble board, single leg squats",
"Stationary cycling progression to 30 min",
"Swimming (flutter kick, avoid breaststroke frog kick)",
"VMO isolation exercises: terminal knee extensions with band",
"Core strengthening: plank, dead bug, bridges - 3x12",
],
"outcome": "Quadriceps strength >80% of contralateral side, full ROM, no pain during ADLs",
},
{
"phase": "PHASE 4 - Return to Activity (Weeks 12-16)",
"color": "1A5376", # dark blue
"precautions": "Avoid contact sports or heavy manual labor until cleared by orthopaedic surgeon. Monitor for loose body symptoms throughout.",
"modalities": [
"Sports taping or prophylactic patellar brace for high-demand activities",
"Maintenance program 2-3x/week",
],
"exercises": [
"Jogging progression (walk-jog intervals) if cleared",
"Agility drills: side steps, figure-of-eight",
"Plyometrics: low-level jumping, box jumps",
"Sport/work-specific functional training",
"Home exercise program for maintenance",
"Full strengthening gym program",
],
"outcome": "Quadriceps strength equal to contralateral side. Full return to work and recreational activities. Patient education on re-dislocation prevention.",
},
]
for ph in phases:
p = doc.add_paragraph()
run = p.add_run(f" {ph['phase']}")
run.bold = True
r, g, b = int(ph['color'][0:2], 16), int(ph['color'][2:4], 16), int(ph['color'][4:6], 16)
run.font.color.rgb = RGBColor(r, g, b)
run.font.size = Pt(12)
tbl = doc.add_table(rows=4, cols=2)
tbl.style = "Table Grid"
headers = ["Precautions", "Electrotherapy / Manual Therapy", "Therapeutic Exercises", "Phase Outcome Criteria"]
contents = [ph["precautions"], "\n".join(f"• {m}" for m in ph["modalities"]),
"\n".join(f"• {e}" for e in ph["exercises"]), ph["outcome"]]
col_colors = ["F9EBEA", "EAF4FB", "EAFAF1", "FEF9E7"]
for i, row in enumerate(tbl.rows):
shade_row(row, col_colors[i])
row.cells[0].text = headers[i]
for para in row.cells[0].paragraphs:
for run in para.runs:
run.bold = True
run.font.size = Pt(10)
row.cells[1].text = contents[i]
for para in row.cells[1].paragraphs:
for run in para.runs:
run.font.size = Pt(10)
set_col_widths(tbl, [1.6, 5.4])
doc.add_paragraph()
# ─────────────────────────────────────────────────────────────────────────────
# KEY EXERCISES - DETAILED
# ─────────────────────────────────────────────────────────────────────────────
add_heading(doc, "5. Priority Exercises - Description & Rationale", level=2, color=(0x1A, 0x53, 0x76))
priority_ex = [
("Quad Sets (Isometric Quadriceps)",
"Lie supine, place rolled towel under knee. Contract quad, press knee down. Hold 10 sec.",
"Prevents quadriceps atrophy; safe in acute phase as it avoids joint movement. Activates VMO."),
("Straight Leg Raise (SLR)",
"Lie supine, lock knee straight, raise leg to 45°, hold 2 sec, lower slowly. 3x10.",
"Strengthens quad without compressing patellofemoral joint. First closed-chain preparation."),
("VMO Biofeedback Training",
"Seated, place fingers on VMO (medial quads, just above patella). Focus contraction here during terminal extension.",
"Vastus Medialis Oblique is the primary medial stabiliser of the patella. Strengthening prevents re-dislocation."),
("McConnell Patellar Taping",
"Apply rigid tape from lateral patella to medial side, gliding patella medially. Reassess pain before and after.",
"Improves patellar tracking, reduces lateral tilt, reduces patellofemoral pain during exercise by 50%."),
("Mini Squat 0-45°",
"Stand shoulder-width apart, feet slightly turned out. Squat to 45° only (not beyond). Keep knee over 2nd toe.",
"Closed kinetic chain exercise - builds quad, glute, and VMO strength. Restricted range protects the osteochondral injury."),
("Terminal Knee Extension (TKE)",
"Band behind knee, start at 30° flexion, extend to full extension against resistance. 3x15.",
"Specifically targets VMO in final degrees of extension - the most critical range for patellar stability."),
("Single Leg Balance",
"Stand on injured leg, maintain balance 30 sec. Progress to eyes closed, then unstable surface.",
"Restores neuromuscular control and proprioception lost after dislocation. Critical for preventing re-injury."),
]
ex_table = doc.add_table(rows=1, cols=3)
ex_table.style = "Table Grid"
shade_row(ex_table.rows[0], "1A5376")
for cell, text in zip(ex_table.rows[0].cells, ["Exercise", "Technique", "Rationale"]):
cell.text = text
for para in cell.paragraphs:
for run in para.runs:
run.bold = True
run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
run.font.size = Pt(10)
for i, (ex, tech, rat) in enumerate(priority_ex):
row = ex_table.add_row()
row.cells[0].text = ex
row.cells[1].text = tech
row.cells[2].text = rat
if i % 2 == 0:
shade_row(row, "EAF4FB")
for j, cell in enumerate(row.cells):
for para in cell.paragraphs:
for run in para.runs:
if j == 0:
run.bold = True
run.font.size = Pt(10)
set_col_widths(ex_table, [1.7, 2.8, 2.5])
doc.add_paragraph()
# ─────────────────────────────────────────────────────────────────────────────
# PRECAUTIONS & RED FLAGS
# ─────────────────────────────────────────────────────────────────────────────
add_heading(doc, "6. Precautions & Red Flags", level=2, color=(0x1A, 0x53, 0x76))
add_para(doc, "PRECAUTIONS (throughout treatment):", bold=True)
precautions = [
"Avoid deep knee flexion beyond 90° in Phase 1-2",
"Do NOT perform open kinetic chain knee extensions beyond 90° (increases patellofemoral stress)",
"Avoid high-impact activities (running, jumping) until Phase 4",
"Avoid breaststroke swimming (frog kick increases lateral patella stress)",
"Do not force ROM - progress pain-free",
"Maintain patellar brace during all weight-bearing activities in Phase 1-2",
]
for p in precautions:
add_bullet(doc, p)
doc.add_paragraph()
add_para(doc, "RED FLAGS - Refer back to Orthopaedic Surgeon if:", bold=True)
red_flags = [
"Sudden onset of knee LOCKING or CATCHING (suggests loose body migration into joint)",
"Marked increase in effusion after exercise",
"Visible patellar subluxation/dislocation event",
"Worsening pain despite 4-6 weeks of physiotherapy",
"Neurological symptoms (numbness, tingling)",
"Any suspicion of re-dislocation",
]
for r in red_flags:
p = doc.add_paragraph(style="List Bullet")
run = p.add_run(r)
run.font.color.rgb = RGBColor(0xC0, 0x39, 0x2B)
run.font.size = Pt(11)
doc.add_paragraph()
# ─────────────────────────────────────────────────────────────────────────────
# HOME EXERCISE PROGRAM
# ─────────────────────────────────────────────────────────────────────────────
add_heading(doc, "7. Home Exercise Program (Daily)", level=2, color=(0x1A, 0x53, 0x76))
hep = [
("Ankle pumps", "3x20", "Hourly", "Prevent DVT, reduce swelling"),
("Quad sets", "3x15", "3x/day", "Maintain quad activation"),
("SLR", "3x10", "2x/day", "Quad strengthening"),
("Ice application", "15-20 min","After exercises", "Reduce swelling and pain"),
("Knee ROM (heel slides)", "3x15", "2x/day", "Maintain and gain flexion"),
("VMO isometrics", "3x15", "2x/day", "Patellar stabilisation"),
("Single leg balance (Phase 3)","3x30 sec","Daily", "Proprioception"),
]
hep_table = doc.add_table(rows=1, cols=4)
hep_table.style = "Table Grid"
shade_row(hep_table.rows[0], "2E86AB")
for cell, text in zip(hep_table.rows[0].cells, ["Exercise", "Sets/Reps", "Frequency", "Purpose"]):
cell.text = text
for para in cell.paragraphs:
for run in para.runs:
run.bold = True
run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
run.font.size = Pt(10)
for i, (ex, reps, freq, pur) in enumerate(hep):
row = hep_table.add_row()
for j, (cell, text) in enumerate(zip(row.cells, [ex, reps, freq, pur])):
cell.text = text
for para in cell.paragraphs:
for run in para.runs:
run.bold = (j == 0)
run.font.size = Pt(10)
if i % 2 == 0:
shade_row(row, "EAF4FB")
set_col_widths(hep_table, [2.2, 1.2, 1.3, 2.3])
doc.add_paragraph()
# ─────────────────────────────────────────────────────────────────────────────
# OUTCOME MEASURES
# ─────────────────────────────────────────────────────────────────────────────
add_heading(doc, "8. Outcome Measures & Assessment Schedule", level=2, color=(0x1A, 0x53, 0x76))
outcome_data = [
("VAS Pain Scale", "0-10 numeric", "Every session", "Target: ≤2/10 by Week 8"),
("Knee ROM (Goniometry)", "Degrees", "Weekly", "Target: Full ROM (0-135°) by Week 8"),
("Quadriceps Circumference", "Centimetres", "Fortnightly", "Monitor atrophy (<1.5 cm difference)"),
("Timed Up and Go (TUG)", "Seconds", "Weeks 2, 6, 12", "Target: <12 sec by discharge"),
("Tegner Activity Level Scale", "0-10", "Start & discharge","Baseline and end comparison"),
("Kujala Patellofemoral Score", "0-100", "Weeks 4, 8, 16", "Target: >75 by discharge"),
("Single Leg Hop Test", "cm / % symmetry","Weeks 8 & 16", "Target: >85% limb symmetry index"),
("Effusion Assessment", "Ballottement", "Every session", "Target: No effusion by Week 6"),
]
om_table = doc.add_table(rows=1, cols=4)
om_table.style = "Table Grid"
shade_row(om_table.rows[0], "1E8449")
for cell, text in zip(om_table.rows[0].cells, ["Measure", "Tool", "Frequency", "Target"]):
cell.text = text
for para in cell.paragraphs:
for run in para.runs:
run.bold = True
run.font.color.rgb = RGBColor(0xFF, 0xFF, 0xFF)
run.font.size = Pt(10)
for i, row_data in enumerate(outcome_data):
row = om_table.add_row()
for j, (cell, text) in enumerate(zip(row.cells, row_data)):
cell.text = text
for para in cell.paragraphs:
for run in para.runs:
run.bold = (j == 0)
run.font.size = Pt(10)
if i % 2 == 0:
shade_row(row, "EAFAF1")
set_col_widths(om_table, [2.0, 1.2, 1.5, 2.3])
doc.add_paragraph()
# ─────────────────────────────────────────────────────────────────────────────
# PATIENT EDUCATION
# ─────────────────────────────────────────────────────────────────────────────
add_heading(doc, "9. Patient Education", level=2, color=(0x1A, 0x53, 0x76))
education = [
"Explain the injury mechanism: transient patellar dislocation causes damage to the medial retinaculum and cartilage",
"Explain the role of VMO strengthening in preventing recurrence",
"Demonstrate correct patellar taping technique for self-application",
"Educate on activity modification: avoid sudden twisting, pivoting, and running until Phase 4",
"Explain warning signs of loose body migration (locking, catching, giving way) - when to seek urgent review",
"Advise on correct footwear: supportive shoes, avoid walking barefoot on slippery surfaces",
"Ergonomic advice for office work: avoid prolonged knee flexion, take breaks every 45 min",
"Ice application technique post-exercise to manage inflammatory response",
"Importance of compliance with home exercise program for successful outcome",
]
for ed in education:
add_bullet(doc, ed)
doc.add_paragraph()
# ─────────────────────────────────────────────────────────────────────────────
# EVIDENCE BASE
# ─────────────────────────────────────────────────────────────────────────────
add_heading(doc, "10. Evidence Base", level=2, color=(0x1A, 0x53, 0x76))
evidence_para = doc.add_paragraph()
evidence_para.add_run(
"This treatment plan is developed in accordance with current evidence:\n\n"
"1. Flores GW et al. (2023). \"Conservative management following patellar dislocation: a level I systematic review.\" "
"Journal of Orthopaedic Surgery and Research. PMID: 37254200\n"
" - A knee brace with limited ROM, stretching, and neuromuscular exercises are the most recommended physiotherapy "
"modalities. An unstructured lower limb programme produces outcomes similar to specific exercises.\n\n"
"2. Bolisetti A et al. (2025). \"Simultaneous Osteochondral Fractures of the Medial Patella and Lateral Femoral "
"Condyle Following Lateral Patellar Dislocation.\" Cureus. PMID: 41018411\n"
" - Confirms the classic MRI triad of osteochondral injury pattern in this patient. Conservative management "
"appropriate for small fragments (<0.5 cm) with physiotherapy.\n\n"
"3. Indiana Hospital MRI Report (Dr. Ranjan Shetty, Consultant Radiologist, 28/04/2025) - Radiological diagnosis "
"of osteochondral injury, medial patellar retinaculum partial tear, and free osteochondral fragments as primary "
"basis for this plan."
)
evidence_para.runs[0].font.size = Pt(10)
evidence_para.runs[0].italic = True
doc.add_paragraph()
# ─────────────────────────────────────────────────────────────────────────────
# FOOTER
# ─────────────────────────────────────────────────────────────────────────────
footer_para = doc.add_paragraph()
footer_para.alignment = WD_ALIGN_PARAGRAPH.CENTER
run = footer_para.add_run(
f"Document prepared: {datetime.date.today().strftime('%d %B %Y')} | "
"Alva's Physiotherapy Center, Moodbidri - 574 227, D.K. | "
"For clinical use only. Review at each phase milestone."
)
run.italic = True
run.font.size = Pt(9)
run.font.color.rgb = RGBColor(0x88, 0x88, 0x88)
# ─────────────────────────────────────────────────────────────────────────────
# SAVE
# ─────────────────────────────────────────────────────────────────────────────
out = "/tmp/workspace/ronald-physio/Ronald_Physio_Treatment_Plan.docx"
doc.save(out)
print(f"Saved: {out}")
python3 /tmp/workspace/ronald-physio/generate_plan.py
Ronald Physio Treatment Plan
Word Document · DOCX
| Phase | Duration | Focus |
|---|---|---|
| Phase 1 - Acute / Protective | Weeks 1-2 | Pain/swelling control, quad activation, brace protection |
| Phase 2 - Sub-Acute / Strengthening | Weeks 3-6 | ROM restoration 0-120°, VMO strengthening, taping |
| Phase 3 - Functional / Neuromuscular | Weeks 7-12 | Full strength, proprioception, functional exercises |
| Phase 4 - Return to Activity | Weeks 12-16 | Return to work/sport, maintenance program |
• FOCAL PARTIAL TEAR IN MEDIAL PATELLAR RETINACULUM •OSTEOCHONDRAL INJURY INVOLVING INFEROMEDIAL PATELLA AND LATERAL FEMORAL CONDYLE WITH MARROW EDEMA • MILD JOINT EFFUSION WITH FREE OSTEOCHONDRAL FRAGMENTS. Physiotherapy management
"patellar dislocation" AND "medial retinaculum" AND "rehabilitation"
"osteochondral defect" AND "knee" AND "conservative treatment"
"patellar dislocation" AND "conservative management"
PMID: 37254200
PMID: 39336921
| Diagnosis | Physiotherapy Priority |
|---|---|
| Focal partial tear - Medial Patellar Retinaculum | Protect, heal, and restore medial patellar stability |
| Osteochondral injury - inferomedial patella + lateral femoral condyle with marrow edema | Reduce load, protect cartilage, control marrow edema |
| Mild joint effusion + free osteochondral fragments | Reduce effusion, monitor for loose body symptoms |
| Modality | Parameters | Purpose |
|---|---|---|
| Cryotherapy (ice) | 15-20 min, 4-5x/day | Reduce effusion and pain; vasoconstriction limits haemarthrosis |
| IFT (Interferential Therapy) | 4000 Hz carrier, 80-100 Hz AMF, 20 min | Analgesia + lymphatic drainage of effusion |
| TENS | 80-100 Hz, 30-40 min | Gate-control pain relief; allows early exercise |
| Pulsed Ultrasound | 1 MHz, 1:4 duty cycle, 0.5 W/cm², 5 min over medial retinaculum | Promotes retinacular healing - non-thermal effect; reduces local oedema |
| Elevation + compression | Limb elevated above heart level; tubigrip compression bandage | Reduces effusion and swelling |
| Patellar taping | McConnell medial glide tape - medially directed taping | Unloads torn medial retinaculum; improves patellar alignment; reduces patellofemoral contact stress on osteochondral injury |
| Exercise | Dose | Rationale |
|---|---|---|
| Ankle pumps | 3x20, hourly | DVT prevention; calf muscle pump reduces effusion |
| Isometric quad sets | 10 sec hold, 3x15, 3x/day | Prevents quadriceps inhibition from effusion (arthrogenic muscle inhibition); no joint movement |
| Straight leg raises (SLR) | 3x10, 2x/day | Quadriceps strengthening without patellofemoral compression |
| Terminal knee extensions (TKE) | Last 15° only, 3x15 | Specifically activates VMO - critical medial patellar stabiliser |
| Isometric hip abduction/adduction | 3x10 | Hip musculature contributes to patellar tracking |
| Seated knee extension 0-45° only | 3x12 | Controlled OKC - avoids high PF contact zone (beyond 45°) |
Key Precaution: Avoid knee flexion >70° in this phase. High patellofemoral joint reaction forces beyond 70° will stress the osteochondral injury and retinal tear simultaneously.
| Exercise | Dose | Rationale |
|---|---|---|
| Supine heel slides | 3x15, ROM to 120° | Restore knee flexion ROM; gentle articular cartilage gliding promotes healing |
| Mini squats 0-45° | 3x15 | CKC exercise; VMO activation; limits PF stress |
| Short arc quads (SAQ) | 0-60° arc, 3x15 | Progressive quad strengthening within safe PF range |
| Step-ups (4-inch step) | 3x12 each | Functional CKC; VMO + glute activation |
| Hamstring curls prone | 3x15 | Hamstring co-contraction stabilises knee |
| Hip strengthening: clamshells, resistance band abduction | 3x15 | Reduces dynamic valgus; improves patellar tracking |
| Stationary cycling | 15-20 min, low resistance, seat high | Low PF joint load; maintains cardiovascular fitness; promotes cartilage nutrition |
| Single leg balance (firm surface) | 3x30 sec | Proprioception recovery - essential after retinacular disruption |
| VMO biofeedback | Surface EMG or palpation feedback, 3x15 | Isolates and re-trains medial patellar stabiliser |
| Exercise | Dose |
|---|---|
| Full squats (progress to 0-90°, then 0-120°) | 3x15 |
| Lunges - forward and lateral | 3x12 each |
| Step-ups and step-downs (8-inch step) | 3x15 |
| Leg press (full ROM progression) | 3x15 |
| TKE with resistance band | 3x15 - most important VMO exercise |
| Nordic hamstring curls | 3x10 |
| Wobble board / BOSU balance | 3x45 sec |
| Swimming (freestyle/backstroke only - avoid breaststroke frog kick) | 30 min |
| Core strengthening: plank, dead bug, glute bridges | 3x12 |
| Walk-jog intervals (if cleared) | Start Week 10 |
| Measure | Frequency | Target by Discharge |
|---|---|---|
| VAS Pain Scale (0-10) | Every session | ≤2/10 |
| Knee goniometry (ROM) | Weekly | Full 0-135° |
| Effusion assessment (ballottement/brush test) | Every session | No effusion by Week 6 |
| Kujala Patellofemoral Score | Weeks 4, 8, 16 | >75/100 |
| Single Leg Hop Test | Weeks 8 & 16 | >85% LSI |
| Timed Up and Go (TUG) | Weeks 2, 6, 12 | <12 seconds |