~/knrush-bpt-muscle/generate_pdf.py
#!/usr/bin/env python3
"""
KNRUHS BPT - Muscle Physiology Previous Year Questions with Answers
Generated using ReportLab
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.lib.colors import HexColor, white, black
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.lib import colors
OUTPUT = "/home/daytona/workspace/knrush-bpt-muscle/KNRUHS_BPT_Muscle_Physiology_PYQ.pdf"
# Color palette
DARK_BLUE = HexColor("#1a3a5c")
MID_BLUE = HexColor("#2563a8")
LIGHT_BLUE = HexColor("#dbeafe")
ACCENT = HexColor("#e63946")
GOLD = HexColor("#f4a261")
GREEN = HexColor("#2d6a4f")
LIGHT_GREEN = HexColor("#d8f3dc")
GREY_BG = HexColor("#f1f5f9")
DARK_GREY = HexColor("#334155")
LIGHT_GREY = HexColor("#e2e8f0")
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=1.8*cm,
leftMargin=1.8*cm,
topMargin=2*cm,
bottomMargin=2*cm,
title="KNRUHS BPT - Muscle Physiology PYQ",
author="KNRush University BPT Exam Prep"
)
styles = getSampleStyleSheet()
# Custom styles
title_style = ParagraphStyle(
"Title", parent=styles["Title"],
fontSize=22, textColor=white, alignment=TA_CENTER,
spaceAfter=4, fontName="Helvetica-Bold"
)
subtitle_style = ParagraphStyle(
"SubTitle", parent=styles["Normal"],
fontSize=12, textColor=LIGHT_BLUE, alignment=TA_CENTER,
spaceAfter=2, fontName="Helvetica"
)
section_style = ParagraphStyle(
"Section", parent=styles["Heading1"],
fontSize=14, textColor=white, fontName="Helvetica-Bold",
spaceAfter=6, spaceBefore=12, leftIndent=0
)
q_heading = ParagraphStyle(
"QHeading", parent=styles["Normal"],
fontSize=11, textColor=DARK_BLUE, fontName="Helvetica-Bold",
spaceBefore=10, spaceAfter=3
)
q_marks = ParagraphStyle(
"QMarks", parent=styles["Normal"],
fontSize=9, textColor=ACCENT, fontName="Helvetica-Bold",
spaceBefore=0, spaceAfter=2
)
ans_head = ParagraphStyle(
"AnsHead", parent=styles["Normal"],
fontSize=10, textColor=GREEN, fontName="Helvetica-Bold",
spaceBefore=4, spaceAfter=2
)
body_style = ParagraphStyle(
"Body", parent=styles["Normal"],
fontSize=10, textColor=DARK_GREY, fontName="Helvetica",
spaceBefore=2, spaceAfter=2, leading=15, alignment=TA_JUSTIFY
)
bullet_style = ParagraphStyle(
"Bullet", parent=styles["Normal"],
fontSize=10, textColor=DARK_GREY, fontName="Helvetica",
spaceBefore=1, spaceAfter=1, leftIndent=14, leading=14,
bulletIndent=4
)
note_style = ParagraphStyle(
"Note", parent=styles["Normal"],
fontSize=9, textColor=HexColor("#7c3aed"), fontName="Helvetica-Oblique",
spaceBefore=2, spaceAfter=2, leftIndent=6
)
table_head_style = ParagraphStyle(
"TH", parent=styles["Normal"],
fontSize=9, textColor=white, fontName="Helvetica-Bold", alignment=TA_CENTER
)
table_cell_style = ParagraphStyle(
"TC", parent=styles["Normal"],
fontSize=9, textColor=DARK_GREY, fontName="Helvetica", alignment=TA_LEFT, leading=12
)
story = []
# ─── COVER PAGE ─────────────────────────────────────────────────────────────
cover_data = [[
Paragraph("KNRUHS BPT", title_style),
]]
cover_table = Table([[
Paragraph("KNRUHS - BPT 1st Year", ParagraphStyle("C1", fontSize=20, textColor=white, alignment=TA_CENTER, fontName="Helvetica-Bold")),
]], colWidths=[doc.width])
cover_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 18),
("BOTTOMPADDING", (0,0), (-1,-1), 18),
("LEFTPADDING", (0,0), (-1,-1), 14),
("RIGHTPADDING", (0,0), (-1,-1), 14),
]))
story.append(cover_table)
story.append(Spacer(1, 0.3*cm))
subject_table = Table([[
Paragraph("PHYSIOLOGY (BP804)", ParagraphStyle("C2", fontSize=16, textColor=DARK_BLUE, alignment=TA_CENTER, fontName="Helvetica-Bold")),
]], colWidths=[doc.width])
subject_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_BLUE),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("BOX", (0,0), (-1,-1), 1.5, MID_BLUE),
]))
story.append(subject_table)
story.append(Spacer(1, 0.3*cm))
topic_table = Table([[
Paragraph("MUSCLE PHYSIOLOGY", ParagraphStyle("C3", fontSize=18, textColor=white, alignment=TA_CENTER, fontName="Helvetica-Bold")),
]], colWidths=[doc.width])
topic_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), MID_BLUE),
("TOPPADDING", (0,0), (-1,-1), 14),
("BOTTOMPADDING", (0,0), (-1,-1), 14),
]))
story.append(topic_table)
story.append(Spacer(1, 0.3*cm))
subtitle_table = Table([[
Paragraph("Previous Year Questions with Detailed Answers", ParagraphStyle("C4", fontSize=12, textColor=DARK_GREY, alignment=TA_CENTER, fontName="Helvetica-Oblique")),
]], colWidths=[doc.width])
subtitle_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), GREY_BG),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("BOX", (0,0), (-1,-1), 0.5, LIGHT_GREY),
]))
story.append(subtitle_table)
story.append(Spacer(1, 0.4*cm))
# Info box
info_data = [
[Paragraph("University", table_head_style), Paragraph("Kaloji Narayana Rao University of Health Sciences (KNRUHS), Warangal", table_cell_style)],
[Paragraph("Course", table_head_style), Paragraph("Bachelor of Physiotherapy (BPT) - 1st Year", table_cell_style)],
[Paragraph("Subject", table_head_style), Paragraph("Physiology - BP804", table_cell_style)],
[Paragraph("Topic", table_head_style), Paragraph("Muscle Physiology (as per Sembulingam)", table_cell_style)],
[Paragraph("Papers", table_head_style), Paragraph("Dec 2020 | Aug 2021 | Feb 2022 | Apr 2022 | Oct 2017-2019", table_cell_style)],
]
info_table = Table(info_data, colWidths=[3.5*cm, doc.width - 3.5*cm])
info_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,-1), DARK_BLUE),
("BACKGROUND", (1,0), (1,-1), white),
("ROWBACKGROUNDS", (1,0), (1,-1), [white, GREY_BG]),
("GRID", (0,0), (-1,-1), 0.5, LIGHT_GREY),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(info_table)
story.append(Spacer(1, 0.5*cm))
story.append(Paragraph(
"Compiled from: Sembulingam's Essentials of Medical Physiology | Guyton & Hall Medical Physiology 14e | Costanzo Physiology 7e",
ParagraphStyle("Src", fontSize=8, textColor=HexColor("#94a3b8"), alignment=TA_CENTER, fontName="Helvetica-Oblique")
))
story.append(PageBreak())
# ─── HELPER FUNCTIONS ────────────────────────────────────────────────────────
def section_header(text, color=DARK_BLUE):
tbl = Table([[Paragraph(text, section_style)]], colWidths=[doc.width])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 12),
("RIGHTPADDING", (0,0), (-1,-1), 12),
("ROUNDEDCORNERS", [4,4,4,4]),
]))
return tbl
def q_box(qnum, qtext, marks, year=""):
year_txt = f" [{year}]" if year else ""
header = Table([[
Paragraph(f"Q{qnum}.{year_txt}", ParagraphStyle("QN", fontSize=10, textColor=white, fontName="Helvetica-Bold")),
Paragraph(f"{marks} Marks", ParagraphStyle("QM", fontSize=10, textColor=GOLD, fontName="Helvetica-Bold", alignment=TA_CENTER)),
]], colWidths=[doc.width*0.8, doc.width*0.2])
header.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
body_tbl = Table([[Paragraph(qtext, q_heading)]], colWidths=[doc.width])
body_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_BLUE),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 12),
("RIGHTPADDING", (0,0), (-1,-1), 12),
("BOX", (0,0), (-1,-1), 1, MID_BLUE),
]))
return [header, body_tbl]
def ans_box_start():
ans_tbl = Table([[Paragraph("ANSWER", ans_head)]], colWidths=[doc.width])
ans_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_GREEN),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 10),
("BOX", (0,0), (-1,-1), 0.5, GREEN),
]))
return ans_tbl
def bp(text):
return Paragraph(f"<bullet>\u2022</bullet> {text}", bullet_style)
def mk_table(headers, rows, col_widths=None):
if col_widths is None:
n = len(headers)
col_widths = [doc.width/n]*n
data = [[Paragraph(h, table_head_style) for h in headers]]
for row in rows:
data.append([Paragraph(str(c), table_cell_style) for c in row])
tbl = Table(data, colWidths=col_widths)
style = [
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("ROWBACKGROUNDS", (0,1), (-1,-1), [white, GREY_BG]),
("GRID", (0,0), (-1,-1), 0.4, LIGHT_GREY),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]
tbl.setStyle(TableStyle(style))
return tbl
def divider():
return HRFlowable(width="100%", thickness=0.5, color=LIGHT_GREY, spaceAfter=4, spaceBefore=4)
# ─── INDEX PAGE ──────────────────────────────────────────────────────────────
story.append(section_header("INDEX OF TOPICS", DARK_BLUE))
story.append(Spacer(1, 0.3*cm))
index_data = [
["#", "Topic", "Type", "Page"],
["1", "Physiological Anatomy of Skeletal Muscle", "Long Essay (10M)", "3"],
["2", "Sliding Filament Theory of Muscle Contraction", "Long Essay (10M)", "4"],
["3", "Changes During Muscle Contraction (Band Changes)", "Long Essay (10M)", "5"],
["4", "Neuromuscular Junction (Motor End Plate)", "Long Essay (10M)", "7"],
["5", "Excitation-Contraction Coupling", "Short Essay (5M)", "9"],
["6", "Muscle Fiber Types (Type I vs Type II)", "Short Essay (5M)", "10"],
["7", "Motor Unit", "Short Essay (5M)", "11"],
["8", "Rigor Mortis", "Short Essay (5M)", "12"],
["9", "Muscle Fatigue", "Short Essay (5M)", "12"],
["10", "Types of Muscle Contraction (Isometric/Isotonic)", "Short Essay (5M)", "13"],
["11", "Length-Tension Relationship", "Short Note (2M)", "14"],
["12", "Summation & Tetanus", "Short Note (2M)", "14"],
["13", "Troponin-Tropomyosin Complex", "Short Note (2M)", "15"],
["14", "Sarcoplasmic Reticulum & T-Tubules", "Short Note (2M)", "15"],
["15", "Energy Sources for Muscle Contraction", "Short Note (2M)", "16"],
]
idx_tbl = Table(
[[Paragraph(r[0], table_head_style if i==0 else table_cell_style),
Paragraph(r[1], table_head_style if i==0 else table_cell_style),
Paragraph(r[2], table_head_style if i==0 else table_cell_style),
Paragraph(r[3], table_head_style if i==0 else table_cell_style)]
for i, r in enumerate(index_data)],
colWidths=[1*cm, 9*cm, 5*cm, 1.5*cm]
)
idx_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MID_BLUE),
("ROWBACKGROUNDS", (0,1), (-1,-1), [white, GREY_BG]),
("GRID", (0,0), (-1,-1), 0.4, LIGHT_GREY),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("ALIGN", (0,0), (0,-1), "CENTER"),
("ALIGN", (3,0), (3,-1), "CENTER"),
]))
story.append(idx_tbl)
story.append(PageBreak())
# ═══════════════════════════════════════════════════════════════════════════════
# LONG ESSAYS
# ═══════════════════════════════════════════════════════════════════════════════
story.append(section_header("LONG ESSAY QUESTIONS (10 Marks each)", DARK_BLUE))
story.append(Spacer(1, 0.2*cm))
# ─── Q1 ──────────────────────────────────────────────────────────────────────
for el in q_box(1, "Describe the physiological anatomy of skeletal muscle.", 10, "Dec 2020, Apr 2022"):
story.append(el)
story.append(ans_box_start())
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("INTRODUCTION", q_marks))
story.append(Paragraph(
"Skeletal muscle makes up ~40% of body weight. It is a voluntary, striated muscle under somatic motor control. "
"Understanding its microstructure is key to understanding contraction.", body_style))
story.append(Paragraph("1. GROSS STRUCTURE", q_marks))
story.append(bp("Muscle is surrounded by epimysium (outer connective tissue sheath)"))
story.append(bp("Bundles of fibers (fasciculi) are enclosed by perimysium"))
story.append(bp("Individual muscle fibers are enclosed by endomysium"))
story.append(bp("Muscle fibers: 10-80 micrometers diameter; extend entire muscle length"))
story.append(bp("Each fiber is innervated by ONE nerve ending (near center)"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("2. MUSCLE FIBER (Cell)", q_marks))
story.append(bp("Sarcolemma: cell membrane + outer polysaccharide coat with collagen fibrils; fuses with tendon at ends"))
story.append(bp("Sarcoplasm: intracellular fluid containing K+, Mg2+, phosphate, enzymes, and mitochondria"))
story.append(bp("Each fiber contains 100s-1000s of MYOFIBRILS"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("3. MYOFIBRIL", q_marks))
story.append(bp("~1500 myosin (thick) filaments + ~3000 actin (thin) filaments per myofibril"))
story.append(bp("Arranged in partially overlapping pattern → gives striated appearance"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("4. BANDS AND LINES (Sarcomere Structure)", q_marks))
band_rows = [
["A band", "Anisotropic - DARK", "Myosin + overlapping actin ends", "Does NOT change during contraction"],
["I band", "Isotropic - LIGHT", "Actin only (between Z discs)", "SHORTENS/disappears in contraction"],
["H zone", "Lighter centre of A band", "Myosin only (no actin overlap)", "DISAPPEARS in contraction"],
["M line", "Centre of H zone", "Cross-links between myosin", "Unchanged"],
["Z disc", "Dense line", "Anchor for actin filaments", "Move closer together"],
["Sarcomere", "Z disc to Z disc", "Fundamental unit of contraction", "~2.2 um at rest; shortens"],
]
story.append(mk_table(["Structure","Appearance","Contents","Change in Contraction"], band_rows,
[2.5*cm, 2.5*cm, 5.5*cm, 5.5*cm]))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("5. PROTEINS", q_marks))
prot_rows = [
["Myosin", "Thick filament", "Has globular heads (cross-bridges); ATPase activity"],
["Actin", "Thin filament", "Has active sites for myosin attachment; two strands twisted"],
["Tropomyosin", "Thin filament (regulatory)", "Blocks actin active sites at rest (inhibitory)"],
["Troponin (T, I, C)", "Thin filament (regulatory)", "Troponin C binds Ca2+; triggers conformational change"],
["Titin (connectin)", "Elastic filament", "Anchors myosin to Z disc; provides elasticity; prevents over-stretch"],
["Nebulin", "Thin filament associated", "Regulates actin filament length"],
]
story.append(mk_table(["Protein","Location","Function"], prot_rows, [2.5*cm, 4*cm, 10*cm]))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("6. T-TUBULE - SARCOPLASMIC RETICULUM SYSTEM", q_marks))
story.append(bp("T-tubules: extensions of sarcolemma that penetrate deep into fiber; surround each myofibril"))
story.append(bp("Conduct action potential rapidly to ALL myofibrils simultaneously"))
story.append(bp("Sarcoplasmic reticulum (SR): internal membrane network; terminal cisternae store Ca2+"))
story.append(bp("T-tubules contact SR at triads (1 T-tubule + 2 terminal cisternae)"))
story.append(bp("DHPR (dihydropyridine receptor) on T-tubule mechanically gates RyR (ryanodine receptor) on SR"))
story.append(Paragraph(
"Exam Tip: 'A band unchanged, I band and H zone disappear' is the most frequently asked single-line answer.",
note_style))
story.append(divider())
# ─── Q2 ──────────────────────────────────────────────────────────────────────
story.append(PageBreak())
for el in q_box(2, "Describe the sliding filament theory of muscle contraction with the molecular mechanism.", 10, "Aug 2021, Oct 2019"):
story.append(el)
story.append(ans_box_start())
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("SLIDING FILAMENT THEORY (Huxley & Hanson, 1954; Huxley & Niedergerke, 1954)", q_marks))
story.append(Paragraph(
"During muscle contraction, the ACTIN (thin) filaments SLIDE OVER the MYOSIN (thick) filaments toward "
"the center of the sarcomere (M line). Neither the actin nor myosin filaments change in LENGTH - only the "
"sarcomere shortens.", body_style))
story.append(Paragraph("EVIDENCE FOR SLIDING FILAMENT THEORY", q_marks))
story.append(bp("A band width remains CONSTANT during contraction and stretch"))
story.append(bp("I band shortens proportional to degree of contraction"))
story.append(bp("H zone narrows and disappears at full contraction"))
story.append(bp("Sarcomere length decreases"))
story.append(bp("Electron microscopy confirms filament lengths are constant"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("MOLECULAR MECHANISM (Walk-Along / Ratchet Theory)", q_marks))
steps = [
("Step 1 - RESTING STATE",
"Tropomyosin physically covers active sites on actin. Myosin heads are energized (cocked) with ADP+Pi attached. "
"No cross-bridge formation."),
("Step 2 - STIMULUS & Ca2+ RELEASE",
"Motor nerve AP → ACh release at NMJ → muscle AP → propagates along T-tubules → "
"DHPR conformational change → RyR opens → Ca2+ floods from SR into cytoplasm (10^-7 to 10^-6 M)."),
("Step 3 - TROPONIN C ACTIVATION",
"Ca2+ (up to 4 ions) binds Troponin C → conformational change in troponin-tropomyosin complex → "
"tropomyosin SHIFTS deeper into actin groove → ACTIVE SITES on actin UNCOVERED."),
("Step 4 - CROSS-BRIDGE ATTACHMENT",
"Myosin heads (cross-bridges) attach to exposed active sites on actin → acto-myosin complex formed."),
("Step 5 - POWER STROKE (Force Generation)",
"Release of Pi → myosin head TILTS ~45 degrees toward M line (arm) → POWER STROKE → "
"actin filament pulled ~10 nm toward center. ADP released. This is the FORCE-GENERATING step."),
("Step 6 - CROSS-BRIDGE DETACHMENT",
"NEW ATP binds to myosin head → acto-myosin bond BREAKS → cross-bridge detaches from actin. "
"(Without ATP: rigor mortis occurs - permanent cross-bridge attachment)"),
("Step 7 - RE-COCKING",
"ATP hydrolyzed → ADP + Pi + energy → myosin head returns to EXTENDED (cocked, high-energy) position, "
"pointing away from M line."),
("Step 8 - CYCLE REPEATS",
"Cocked head attaches to NEW active site further along actin → new power stroke. "
"Cycle continues as long as Ca2+ and ATP are available."),
]
for title_s, desc in steps:
step_tbl = Table([
[Paragraph(title_s, ParagraphStyle("ST", fontSize=9, textColor=white, fontName="Helvetica-Bold")),
Paragraph(desc, table_cell_style)]
], colWidths=[3.8*cm, doc.width - 3.8*cm])
step_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), MID_BLUE),
("BACKGROUND", (1,0), (1,0), GREY_BG),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LINEBELOW", (0,0), (-1,-1), 0.3, LIGHT_GREY),
]))
story.append(step_tbl)
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("RELAXATION", q_marks))
story.append(bp("SERCA pump (Ca2+-ATPase) actively pumps Ca2+ BACK into SR"))
story.append(bp("Cytoplasmic [Ca2+] falls below 10^-7 M"))
story.append(bp("Troponin C releases Ca2+"))
story.append(bp("Tropomyosin re-covers active sites on actin"))
story.append(bp("Cross-bridges detach → muscle relaxes (requires ATP)"))
story.append(divider())
# ─── Q3 ──────────────────────────────────────────────────────────────────────
story.append(PageBreak())
for el in q_box(3, "Describe the changes that occur during muscle contraction. Write about band changes in sarcomere.", 10, "Feb 2022, Apr 2019, Dec 2020"):
story.append(el)
story.append(ans_box_start())
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("CHANGES DURING MUSCLE CONTRACTION", q_marks))
story.append(Paragraph(
"Muscle contraction produces changes at multiple levels: microscopic band changes, molecular changes, "
"mechanical changes, and biochemical changes.", body_style))
story.append(Paragraph("A. BAND CHANGES IN SARCOMERE (Most Important)", q_marks))
band_change = [
["I band", "DECREASES (shortens)", "Actin slides in; less pure-actin zone remains"],
["H zone", "DISAPPEARS", "Actin tips reach/overlap centre of myosin; no myosin-only zone left"],
["A band", "UNCHANGED (constant)", "Myosin filament length constant; always = A band width"],
["M line", "Unchanged", "Cross-links between myosin remain"],
["Z disc distance", "DECREASES", "Z discs pulled toward M line; sarcomere shortens"],
["Sarcomere length", "2.2um -> ~1.6um", "Shortens as actin slides toward M line"],
]
story.append(mk_table(["Structure","Change","Reason"], band_change, [3*cm, 4.5*cm, 9*cm]))
story.append(Paragraph(
"Memory Aid: 'I band and H zone disappear; A band always stays the same'",
note_style))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("B. MOLECULAR CHANGES", q_marks))
story.append(bp("Ca2+ released from SR → binds Troponin C"))
story.append(bp("Tropomyosin shifts → active sites uncovered"))
story.append(bp("Myosin ATPase activated → ATP hydrolysis provides energy"))
story.append(bp("Cross-bridge cycling: attachment → power stroke → detachment → re-cocking"))
story.append(bp("Each power stroke moves actin ~10 nm; sarcomere shortens ~1% per cycle"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("C. MECHANICAL CHANGES", q_marks))
mech_rows = [
["Muscle length", "Shortens (isotonic) OR unchanged (isometric)"],
["Muscle tension", "Increases"],
["Sarcomere", "Shortens from ~2.2 um to ~1.6-2.0 um"],
["Force generated", "Proportional to cross-bridges engaged (filament overlap)"],
]
story.append(mk_table(["Parameter","Change"], mech_rows, [5*cm, 11.5*cm]))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("D. BIOCHEMICAL CHANGES", q_marks))
story.append(bp("ATP consumed by: (1) myosin ATPase power stroke, (2) SERCA pump for relaxation, (3) Na+/K+ pump"))
story.append(bp("O2 consumption increases"))
story.append(bp("CO2 and lactic acid produced (especially in intense exercise)"))
story.append(bp("Heat generated: ~75% of muscle energy released as heat"))
story.append(bp("Creatine phosphate rapidly replenishes ATP (Lohmann reaction)"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("E. ELECTRICAL CHANGES", q_marks))
story.append(bp("Action potential propagates along sarcolemma and T-tubules"))
story.append(bp("Muscle resting membrane potential: -90 mV"))
story.append(bp("Depolarization to +20 to +30 mV during AP"))
story.append(bp("AP precedes Ca2+ rise; Ca2+ rise precedes contraction (ECC sequence)"))
story.append(divider())
# ─── Q4 ──────────────────────────────────────────────────────────────────────
story.append(PageBreak())
for el in q_box(4, "Describe the structure and function of the neuromuscular junction (motor end plate). Explain neuromuscular transmission.", 10, "Oct 2017, Aug 2021, Apr 2022"):
story.append(el)
story.append(ans_box_start())
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("DEFINITION", q_marks))
story.append(Paragraph(
"The neuromuscular junction (NMJ) or motor end plate is the specialized synapse between the terminal "
"of a motor neuron and a skeletal muscle fiber. It is a chemical synapse using acetylcholine (ACh) as the "
"neurotransmitter.", body_style))
story.append(Paragraph("STRUCTURE", q_marks))
story.append(Paragraph("1. PRE-SYNAPTIC COMPONENT (Nerve Terminal):", body_style))
story.append(bp("Large myelinated alpha motor neuron; myelin sheath ends before terminal"))
story.append(bp("Axon terminal button contains: mitochondria (ATP for ACh synthesis), ~300,000 synaptic vesicles (each ~10,000 ACh molecules), voltage-gated Ca2+ channels, dense bars on inner membrane"))
story.append(Paragraph("2. SYNAPTIC CLEFT:", body_style))
story.append(bp("20-30 nm wide space between nerve terminal and muscle membrane"))
story.append(bp("Contains acetylcholinesterase (AChE) - enzyme that destroys ACh after action"))
story.append(bp("Contains basal lamina (extracellular matrix)"))
story.append(Paragraph("3. POST-SYNAPTIC COMPONENT (Motor End Plate):", body_style))
story.append(bp("Synaptic gutter/trough: invagination of muscle sarcolemma"))
story.append(bp("Subneural clefts: deep folds that greatly increase surface area"))
story.append(bp("Nicotinic ACh receptors (nAChR): ligand-gated ion channels; concentrated at mouths of subneural clefts"))
story.append(bp("Voltage-gated Na+ channels line the subneural clefts"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("NEUROMUSCULAR TRANSMISSION (Steps)", q_marks))
nmj_steps = [
("1", "AP arrives at motor nerve terminal"),
("2", "Depolarization opens voltage-gated Ca2+ channels on presynaptic membrane"),
("3", "Ca2+ influx into nerve terminal"),
("4", "Ca2+ activates Ca2+-calmodulin kinase → phosphorylates synapsin → vesicles mobilize to active zone"),
("5", "~125 vesicles undergo exocytosis → release ~1,000,000 ACh molecules into synaptic cleft"),
("6", "ACh diffuses across cleft (20-30 nm) → binds to nicotinic ACh receptors on motor end plate"),
("7", "nAChR opens (non-selective cation channel) → Na+ influx > K+ efflux → END PLATE POTENTIAL (EPP) generated"),
("8", "EPP (~60 mV depolarization) exceeds threshold → action potential generated in muscle fiber"),
("9", "AP propagates along sarcolemma and T-tubules → ECC → contraction"),
("10", "ACh rapidly destroyed by AChE (in 1-2 ms) → prevents sustained depolarization"),
]
nmj_tbl = Table(
[[Paragraph(s[0], ParagraphStyle("NS", fontSize=10, textColor=white, fontName="Helvetica-Bold", alignment=TA_CENTER)),
Paragraph(s[1], table_cell_style)] for s in nmj_steps],
colWidths=[0.8*cm, doc.width - 0.8*cm]
)
nmj_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,-1), MID_BLUE),
("ROWBACKGROUNDS", (1,0), (1,-1), [white, GREY_BG]),
("GRID", (0,0), (-1,-1), 0.4, LIGHT_GREY),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(nmj_tbl)
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("DRUGS AFFECTING NMJ (Important for Physio)", q_marks))
drug_rows = [
["Neostigmine / Pyridostigmine", "Inhibits AChE", "Prolongs ACh action; used in myasthenia gravis"],
["Succinylcholine", "Depolarizing blocker (agonist)", "Sustained depolarization; muscle relaxant in anesthesia"],
["Tubocurarine (curare)", "Competitive nAChR antagonist", "Blocks ACh; muscle paralysis"],
["Botulinum toxin (BoTox)", "Inhibits ACh vesicle exocytosis", "Prevents ACh release; flaccid paralysis"],
["Organophosphates", "Irreversible AChE inhibitor", "Nerve agents/pesticides; excessive ACh"],
]
story.append(mk_table(["Drug","Mechanism","Effect"], drug_rows, [4.5*cm, 5.5*cm, 6.5*cm]))
story.append(Paragraph(
"Clinical: Myasthenia Gravis = autoantibodies against nAChR → weakness; Lambert-Eaton = autoantibodies against VGCC → Ca2+ deficiency at terminal",
note_style))
story.append(divider())
# ═══════════════════════════════════════════════════════════════════════════════
# SHORT ESSAY QUESTIONS
# ═══════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("SHORT ESSAY QUESTIONS (5 Marks each)", MID_BLUE))
story.append(Spacer(1, 0.2*cm))
# ─── Q5 ──────────────────────────────────────────────────────────────────────
for el in q_box(5, "Write about excitation-contraction coupling in skeletal muscle.", 5, "Feb 2022, Nov 2019"):
story.append(el)
story.append(ans_box_start())
story.append(Spacer(1, 0.1*cm))
story.append(Paragraph(
"Excitation-contraction (EC) coupling = the mechanism that links the muscle ACTION POTENTIAL (excitation) "
"to SHORTENING (contraction). The temporal sequence is: AP → Ca2+ rise → contraction.", body_style))
ecc_seq = [
("AP on sarcolemma", "Motor nerve AP → ACh → muscle AP generated at motor end plate"),
("T-tubule conduction", "AP propagates along T-tubules into fiber interior - reaches ALL myofibrils simultaneously"),
("DHPR activation", "T-tubule depolarization → conformational change in DHPR (L-type Ca2+ channel, voltage sensor)"),
("RyR opening", "DHPR mechanically gates Ryanodine Receptor 1 (RyR1) on SR terminal cisternae"),
("Ca2+ release", "Ca2+ floods from SR into cytoplasm; [Ca2+] rises from <10^-7 M to ~10^-6 M"),
("Troponin C binding", "Ca2+ binds Troponin C (4 Ca2+ per molecule) → conformational change"),
("Tropomyosin shift", "Tropomyosin moves into actin groove → active sites uncovered"),
("Cross-bridge cycling", "Myosin heads bind actin → power stroke → contraction"),
("Relaxation", "SERCA pump returns Ca2+ to SR → Troponin C releases Ca2+ → tropomyosin covers sites → relaxation"),
]
ecc_tbl = Table(
[[Paragraph(s[0], ParagraphStyle("ES", fontSize=9, textColor=white, fontName="Helvetica-Bold")),
Paragraph(s[1], table_cell_style)] for s in ecc_seq],
colWidths=[3.5*cm, doc.width - 3.5*cm]
)
ecc_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,-1), MID_BLUE),
("ROWBACKGROUNDS", (1,0), (1,-1), [white, GREY_BG]),
("GRID", (0,0), (-1,-1), 0.4, LIGHT_GREY),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(ecc_tbl)
story.append(divider())
# ─── Q6 ──────────────────────────────────────────────────────────────────────
for el in q_box(6, "Classify and compare different types of muscle fibers.", 5, "Oct 2018, Aug 2021"):
story.append(el)
story.append(ans_box_start())
fiber_rows = [
["Feature", "Type I (Slow, Red)", "Type IIa (Fast Oxidative)", "Type IIb/IIx (Fast Glycolytic, White)"],
["Speed", "Slow", "Fast", "Fast"],
["Fatigue resistance", "HIGH (fatigue-resistant)", "Intermediate", "LOW (fatigues rapidly)"],
["Fiber size", "Small", "Intermediate", "Large"],
["Myoglobin", "High (red color)", "High", "Low (white color)"],
["Mitochondria", "Many", "Many", "Few"],
["SR", "Less extensive", "Intermediate", "Very extensive"],
["Metabolism", "Oxidative (aerobic)", "Oxidative + Glycolytic", "Glycolytic (anaerobic)"],
["Glycogen stores", "Low", "Intermediate", "High"],
["Capillary supply", "Rich", "Rich", "Sparse"],
["Myosin ATPase", "Low activity (slow)", "High", "High (fastest)"],
["Innervation", "Small alpha motor neuron", "Large alpha motor neuron", "Large alpha motor neuron"],
["Function", "Sustained posture (soleus)", "Sprinting + endurance", "Fast, powerful, brief (ocular)"],
["Recruited", "First (low threshold)", "Second", "Last (high threshold)"],
]
story.append(mk_table(
fiber_rows[0],
fiber_rows[1:],
[4*cm, 4.5*cm, 4*cm, 4*cm]
))
story.append(Paragraph("Henneman's Size Principle: Motor units recruited in order of increasing size (slow first, then fast).", note_style))
story.append(divider())
# ─── Q7 ──────────────────────────────────────────────────────────────────────
for el in q_box(7, "Define motor unit. Explain its significance.", 5, "Apr 2022, Oct 2019"):
story.append(el)
story.append(ans_box_start())
story.append(Paragraph(
"A motor unit consists of ONE alpha motor neuron and ALL the skeletal muscle fibers it innervates. "
"It is the SMALLEST FUNCTIONAL UNIT of muscle contraction.", body_style))
story.append(Paragraph("KEY FEATURES:", q_marks))
story.append(bp("All fibers in a motor unit are of the SAME fiber type"))
story.append(bp("All fibers in a unit contract TOGETHER (all-or-none at the unit level)"))
story.append(bp("Innervation ratio varies: ocular muscles ~3-6 fibers/neuron (precision); gastrocnemius ~1000-2000 fibers/neuron (power)"))
story.append(bp("Graded muscle force achieved by: (1) Recruitment of more motor units, (2) Increasing firing frequency (rate coding)"))
story.append(Paragraph("SIGNIFICANCE:", q_marks))
story.append(bp("Basis of graded voluntary muscle force"))
story.append(bp("Smaller motor units: precise control (hands, eyes)"))
story.append(bp("Larger motor units: powerful gross movements (thigh muscles)"))
story.append(bp("EMG records motor unit action potentials clinically"))
story.append(divider())
# ─── Q8 ──────────────────────────────────────────────────────────────────────
for el in q_box(8, "What is rigor mortis? Explain its mechanism and medicolegal importance.", 5, "Nov 2019, Apr 2022"):
story.append(el)
story.append(ans_box_start())
story.append(Paragraph(
"Rigor mortis is the stiffening of skeletal muscles that occurs after death, due to the depletion of ATP.", body_style))
story.append(Paragraph("MECHANISM:", q_marks))
story.append(bp("After death: cellular respiration ceases → ATP production stops → ATP depleted"))
story.append(bp("Without ATP: cross-bridges CANNOT DETACH from actin (ATP needed for detachment step)"))
story.append(bp("Ca2+ leaks from SR (membranes lose integrity) → cross-bridges form throughout muscle"))
story.append(bp("Muscle locked in CONTRACTED STATE → stiffness = rigor mortis"))
story.append(bp("As proteins begin to decompose (~48-72 h): cross-bridge proteins denature → stiffness resolves"))
story.append(Paragraph("TIME COURSE:", q_marks))
story.append(bp("Begins: 3-6 hours after death (starts in smaller muscles - face/jaw first)"))
story.append(bp("Maximum: 12-24 hours after death"))
story.append(bp("Resolves: 48-72 hours after death (muscle autolysis begins)"))
story.append(Paragraph("MEDICOLEGAL IMPORTANCE:", q_marks))
story.append(bp("Helps estimate TIME OF DEATH (post-mortem interval)"))
story.append(bp("Affects body position at discovery"))
story.append(bp("Faster in hot conditions / vigorous exercise preceding death (ATP depletes faster)"))
story.append(divider())
# ─── Q9 ──────────────────────────────────────────────────────────────────────
for el in q_box(9, "What is muscle fatigue? Describe its causes and types.", 5, "Dec 2020, Feb 2022"):
story.append(el)
story.append(ans_box_start())
story.append(Paragraph(
"Muscle fatigue is the inability to maintain the required or expected force/power output, resulting in a "
"decline in muscle performance despite continued effort.", body_style))
story.append(Paragraph("TYPES:", q_marks))
story.append(bp("Peripheral (muscle) fatigue: occurs at or beyond the NMJ"))
story.append(bp("Central fatigue: occurs in CNS - reduced neural drive to muscle"))
story.append(Paragraph("CAUSES OF PERIPHERAL FATIGUE:", q_marks))
fatigue_rows = [
["ATP depletion", "Insufficient energy for cross-bridge cycling and ion pumps"],
["Lactic acid / H+ accumulation", "Lowers pH → inhibits myosin ATPase; interferes with Ca2+ sensitivity of troponin"],
["Pi accumulation", "Released from ATP hydrolysis; inhibits cross-bridge power stroke"],
["Ca2+ release failure", "SR fails to release adequate Ca2+ with repeated stimulation"],
["K+ accumulation (extracellular)", "Depolarizes T-tubule membrane; impairs AP propagation"],
["Glycogen depletion", "Reduced substrate for glycolysis and oxidative phosphorylation"],
["NMJ fatigue (rare)", "Depletion of ACh vesicles with intense, sustained stimulation"],
]
story.append(mk_table(["Cause","Mechanism"], fatigue_rows, [5.5*cm, 11*cm]))
story.append(divider())
# ─── Q10 ──────────────────────────────────────────────────────────────────────
for el in q_box(10, "Distinguish between isotonic and isometric muscle contraction.", 5, "Apr 2019, Aug 2021"):
story.append(el)
story.append(ans_box_start())
contraction_rows = [
["Definition", "Muscle SHORTENS; tension constant", "Muscle does NOT shorten; tension changes"],
["Length", "Decreases", "Constant"],
["Tension", "Constant (= load)", "Increases without shortening"],
["Sarcomere", "Shortens", "No shortening"],
["Load", "Less than muscle force", "Greater than muscle force"],
["Movement", "Produces joint movement", "No joint movement"],
["Example", "Lifting a weight (bicep curl)", "Pushing wall; holding heavy bag still"],
["Work done", "Yes (force x distance)", "No external work (W=0)"],
["Types", "Concentric (shortening), Eccentric (lengthening)", "Static contraction"],
["O2 consumption", "Proportional to work", "Less than isotonic for same force"],
["EMG", "Motor units active", "Motor units active (more for same force)"],
]
story.append(mk_table(["Feature","Isotonic","Isometric"], contraction_rows, [4*cm, 7.5*cm, 5*cm]))
story.append(divider())
# ═══════════════════════════════════════════════════════════════════════════════
# SHORT NOTE QUESTIONS
# ═══════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("SHORT NOTE QUESTIONS (2-3 Marks each)", HexColor("#0f766e")))
story.append(Spacer(1, 0.2*cm))
short_notes = [
{
"qnum": 11,
"q": "Length-tension relationship in skeletal muscle",
"year": "Oct 2018, Apr 2022",
"marks": 2,
"points": [
"Resting sarcomere length ~2.0-2.2 um = OPTIMAL for maximum tension",
"At 2.2 um: all cross-bridges engaged → maximum tension",
"< 2.0 um: actin filaments overlap each other; Z disc contacts myosin → tension falls",
"< 1.65 um: myosin crumples → near-zero tension",
"> 2.2 um (overstretched): less filament overlap → fewer cross-bridges → tension falls toward zero",
"At 3.6 um: no overlap → zero active tension",
"Clinical: Frank-Starling Law of heart is based on this - starling's law of the heart",
"Basis of preload optimization in cardiac physiology",
]
},
{
"qnum": 12,
"q": "Summation and tetanus of muscle contraction",
"year": "Dec 2020, Nov 2019",
"marks": 2,
"points": [
"TWITCH: Single muscle contraction in response to single AP (lasts ~100 ms)",
"SUMMATION: If 2nd stimulus arrives before full relaxation from 1st twitch → contractions ADD UP → greater force (wave summation / temporal summation)",
"Basis: Ca2+ from SR not fully pumped back; elevated baseline [Ca2+] → more cross-bridges",
"INCOMPLETE TETANUS: Rapid stimuli at ~20-40 Hz → partial relaxation between twitches; jagged contraction",
"COMPLETE (FUSED) TETANUS: Stimuli at >50-100 Hz → NO relaxation between twitches; smooth, maximum force contraction",
"Tetanic tension ~4x greater than single twitch",
"Physiological significance: all voluntary contractions are partial tetanic contractions",
]
},
{
"qnum": 13,
"q": "Troponin-tropomyosin complex",
"year": "Feb 2022",
"marks": 2,
"points": [
"TROPOMYOSIN: Long rod-shaped protein running along the groove of actin double helix",
"Covers 7 actin monomers and their active sites in the resting state (INHIBITORY)",
"TROPONIN: Three-subunit complex attached to tropomyosin at intervals:",
" - Troponin T (TnT): binds tropomyosin; attaches complex to thin filament",
" - Troponin I (TnI): inhibitory unit; blocks actin-myosin interaction",
" - Troponin C (TnC): Ca2+-binding unit; binds up to 4 Ca2+ ions",
"When [Ca2+] rises: Ca2+ binds TnC → conformational change → tropomyosin shifts into groove → active sites on actin UNCOVERED",
"Clinical: Cardiac Troponin I and T are sensitive biomarkers for myocardial infarction",
]
},
{
"qnum": 14,
"q": "Sarcoplasmic reticulum and transverse tubules",
"year": "Oct 2019, Aug 2021",
"marks": 2,
"points": [
"T-TUBULES (Transverse tubules): Invaginations of sarcolemma; penetrate deep into muscle fiber",
"Surround each myofibril at A-I junction (2 per sarcomere in mammalian skeletal muscle)",
"Function: Rapidly conduct AP from surface to center of fiber (all myofibrils simultaneously)",
"Contain DHPR (dihydropyridine receptor / L-type Ca2+ channel) - voltage sensor",
"SARCOPLASMIC RETICULUM (SR): Smooth endoplasmic reticulum of muscle fiber",
"Terminal cisternae: enlarged ends adjacent to T-tubules; store Ca2+",
"TRIAD: One T-tubule flanked by 2 terminal cisternae",
"SR contains: (1) Ryanodine receptors (RyR1 = Ca2+ release channels), (2) SERCA pump (Ca2+ ATPase - returns Ca2+ to SR)",
"Free [Ca2+] in SR: ~1 mM; Cytoplasm at rest: <0.1 uM; During contraction: ~1-10 uM",
]
},
{
"qnum": 15,
"q": "Energy sources for muscle contraction",
"year": "Apr 2019, Feb 2022",
"marks": 2,
"points": [
"ATP is the IMMEDIATE energy source for: (1) cross-bridge power stroke, (2) SERCA pump, (3) Na+/K+ pump",
"1. IMMEDIATE: ATP directly available in muscle (~2-3 seconds supply at full activity)",
"2. CREATINE PHOSPHATE (PHOSPHOCREATINE): Rapidly regenerates ATP via creatine kinase (Lohmann reaction): CP + ADP → Creatine + ATP; lasts ~10-15 seconds",
"3. ANAEROBIC GLYCOLYSIS: Glucose → 2 pyruvate → 2 lactate + 2 ATP (net); lasts ~1-2 minutes; produces lactic acid/H+",
"4. AEROBIC OXIDATIVE PHOSPHORYLATION: Glucose/fatty acids + O2 → CO2 + H2O + 30-38 ATP; sustains prolonged activity",
"5. FATTY ACID OXIDATION: Dominant fuel at low-moderate exercise intensity (slow/Type I fibers)",
"In order of activation: Stored ATP → CP → Glycolysis → Oxidative phosphorylation",
]
},
]
for sn in short_notes:
for el in q_box(sn["qnum"], sn["q"], sn["marks"], sn["year"]):
story.append(el)
story.append(ans_box_start())
for pt in sn["points"]:
story.append(bp(pt))
story.append(divider())
# ═══════════════════════════════════════════════════════════════════════════════
# QUICK REVISION TABLES
# ═══════════════════════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("QUICK REVISION - HIGH YIELD FACTS", ACCENT))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("KEY NUMBERS TO REMEMBER", q_marks))
nums = [
["Resting sarcomere length", "~2.0-2.2 um"],
["Sarcomere at full contraction", "~1.6 um"],
["Resting muscle membrane potential", "-90 mV"],
["Synaptic cleft width (NMJ)", "20-30 nm"],
["ACh vesicles per end plate", "~300,000"],
["ACh vesicles released per AP", "~125 vesicles (~1 million molecules"],
["Resting intracellular [Ca2+]", "<10^-7 M (100 nM)"],
["[Ca2+] during contraction", "~10^-6 M (1000 nM)"],
["Ca2+ bound per Troponin C molecule", "Up to 4 ions"],
["Actin filament displacement per power stroke", "~10 nm"],
["Actin: Myosin filament ratio", "2:1 (3000 actin : 1500 myosin)"],
["Diameter of muscle fiber", "10-80 um"],
["Tetanic frequency (complete tetanus)", ">50-100 Hz"],
["Optimal sarcomere length (max tension)", "2.0-2.2 um"],
]
story.append(mk_table(["Parameter","Value/Fact"], nums, [8*cm, 8.5*cm]))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("MUST-KNOW COMPARISONS", q_marks))
comp = [
["Actin vs Myosin", "Thin vs Thick", "Moves vs Stationary during contraction", "~1 um vs ~1.6 um length"],
["I band vs A band", "Light vs Dark", "Actin only vs Myosin + actin", "Changes vs Constant"],
["Type I vs Type II", "Slow vs Fast", "Fatigue resistant vs Fatigable", "Oxidative vs Glycolytic"],
["Isometric vs Isotonic", "No length change vs Length change", "Tension builds vs Tension constant", "Wall push vs Weightlift"],
["RyR vs DHPR", "SR channel vs T-tubule sensor", "Ca2+ release vs Voltage sensor", "Skeletal: mechanical coupling"],
]
story.append(mk_table(["Comparison","Difference 1","Difference 2","Difference 3"], comp, [3.5*cm, 4.5*cm, 4.5*cm, 4*cm]))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("EXAM MNEMONICS", q_marks))
mnemo = [
["Band changes", "'I band and H zone: I Have (I-H) disappeared; A band: Always the same'"],
["Troponin subunits", "'TIC' = T (tropomyosin-binding), I (inhibitory), C (Ca2+-binding)"],
["EC coupling", "'AP - DHPR - RyR - Ca2+ - TnC - Tropomyosin - XB' (Action-D-R-C-T-T-X)"],
["Energy sources order", "'ATP-CP-Glucose-Fat' (All Creatures Get Fuel)"],
["Fiber type", "'SO-FOG-FG' = Slow Oxidative - Fast Oxidative Glycolytic - Fast Glycolytic"],
["Rigor mortis", "'No ATP = No Detachment = Stiff body' (muscles freeze in contracted state)"],
]
story.append(mk_table(["Topic","Mnemonic"], mnemo, [4*cm, 12.5*cm]))
# ─── FINAL PAGE: IMPORTANT DEFINITIONS ─────────────────────────────────────
story.append(PageBreak())
story.append(section_header("IMPORTANT ONE-LINE DEFINITIONS", MID_BLUE))
story.append(Spacer(1, 0.2*cm))
defs = [
("Sarcomere", "The functional unit of muscle contraction, defined as the segment between two successive Z discs (~2.2 um at rest)."),
("Motor unit", "A single alpha motor neuron and all the skeletal muscle fibers it innervates; smallest unit of voluntary contraction."),
("Twitch", "A single, brief contraction of a muscle fiber in response to a single action potential."),
("Tetanus", "A sustained, smooth muscle contraction produced by high-frequency stimulation (>50 Hz) with no relaxation between twitches."),
("Summation", "The addition of successive muscle twitches when stimulated before complete relaxation; results in greater force than a single twitch."),
("Recruitment", "The activation of additional motor units to increase the force of contraction."),
("Excitation-contraction coupling", "The sequence of events linking the muscle action potential (electrical) to myosin-actin cross-bridge formation (mechanical)."),
("Neuromuscular junction", "The specialized chemical synapse between the terminal of a motor neuron and a skeletal muscle fiber; uses ACh as transmitter."),
("End plate potential", "The graded depolarization of the motor end plate produced by ACh binding to nAChRs; normally suprathreshold → triggers muscle AP."),
("Rigor mortis", "Post-mortem stiffening of skeletal muscles due to ATP depletion preventing cross-bridge detachment."),
("Muscle fatigue", "The reversible decline in force/power output despite continued effort; due to metabolic changes (H+, Pi, K+) and Ca2+ failure."),
("Sliding filament theory", "The mechanism of muscle contraction whereby actin filaments slide over myosin filaments, shortening the sarcomere without changing filament length."),
("Power stroke", "The tilting of the myosin head after attaching to actin, pulling the actin filament ~10 nm toward the M line; the force-generating event."),
("Troponin C", "The Ca2+-binding subunit of troponin; binds 4 Ca2+ ions, triggering conformational change that uncovers actin active sites."),
("SERCA pump", "Sarcoplasmic/endoplasmic reticulum Ca2+-ATPase; actively transports Ca2+ from cytoplasm back into SR during relaxation."),
]
for term, definition in defs:
def_tbl = Table([
[Paragraph(term, ParagraphStyle("DT", fontSize=10, textColor=DARK_BLUE, fontName="Helvetica-Bold")),
Paragraph(definition, table_cell_style)]
], colWidths=[4.5*cm, doc.width - 4.5*cm])
def_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), LIGHT_BLUE),
("BACKGROUND", (1,0), (1,0), white),
("LINEBELOW", (0,0), (-1,0), 0.3, LIGHT_GREY),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(def_tbl)
story.append(Spacer(1, 0.5*cm))
story.append(HRFlowable(width="100%", thickness=1.5, color=MID_BLUE))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
"Best of Luck for Your KNRUHS BPT Exam!",
ParagraphStyle("GL", fontSize=14, textColor=MID_BLUE, alignment=TA_CENTER, fontName="Helvetica-Bold")
))
story.append(Paragraph(
"Study Sembulingam's Essentials of Medical Physiology thoroughly | Refer Guyton & Hall for additional depth",
ParagraphStyle("GL2", fontSize=9, textColor=DARK_GREY, alignment=TA_CENTER, fontName="Helvetica-Oblique")
))
# ─── BUILD ────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF generated: {OUTPUT}")