teach me physiology of homeostasis,respiratory system,gastrointestinal system,nervous system,endocrine glands,haemopioetic system,immunity,physiology of cardiovascular system,muscle physiology,adipose tissue,physiology of male and female reproductive system,physiology of excretion system,special sense,sleep and dream
human physiology overview homeostasis respiratory cardiovascular nervous endocrine reproductive systems
| Volume/Capacity | Value (approx.) | Definition |
|---|---|---|
| Tidal Volume (TV) | 500 mL | Air per normal breath |
| Inspiratory Reserve Volume (IRV) | 3000 mL | Extra air inhaled forcibly |
| Expiratory Reserve Volume (ERV) | 1100 mL | Extra air exhaled forcibly |
| Residual Volume (RV) | 1200 mL | Air remaining after max expiration |
| Total Lung Capacity (TLC) | 5800 mL | TV + IRV + ERV + RV |
| Vital Capacity (VC) | 4600 mL | TLC - RV |
| Functional Residual Capacity (FRC) | 2300 mL | ERV + RV |
| Organ | Secretion | Key Components |
|---|---|---|
| Salivary glands | Saliva (~1.5 L/day) | Amylase, mucus, lingual lipase |
| Stomach | Gastric juice (~2 L/day) | HCl (parietal cells), pepsinogen (chief cells), intrinsic factor, mucus |
| Pancreas | Pancreatic juice (~1.5 L/day) | Bicarbonate, lipase, amylase, proteases (trypsin, chymotrypsin) |
| Liver/Bile ducts | Bile (~0.5 L/day) | Bile salts, cholesterol, bilirubin |
| Feature | Sympathetic | Parasympathetic |
|---|---|---|
| Origin | Thoracolumbar (T1-L2) | Craniosacral (III, VII, IX, X; S2-4) |
| Preganglionic NT | Acetylcholine (nAChR) | Acetylcholine (nAChR) |
| Postganglionic NT | Norepinephrine (adrenergic) | Acetylcholine (mAChR) |
| Effect | "Fight or flight" | "Rest and digest" |
| Gland | Key Hormones | Main Actions |
|---|---|---|
| Hypothalamus | TRH, CRH, GnRH, GHRH, Somatostatin, Dopamine | Regulate anterior pituitary; control of ANS |
| Anterior Pituitary | TSH, ACTH, FSH, LH, GH, Prolactin, MSH | Stimulate target glands (thyroid, adrenal, gonads) |
| Posterior Pituitary | ADH (vasopressin), Oxytocin | Water reabsorption (ADH); uterine contraction/milk ejection (oxytocin) |
| Thyroid | T3, T4 (thyroxine), Calcitonin | Metabolic rate, growth, development; lower blood calcium |
| Parathyroid | PTH | Raises blood calcium (bone resorption, renal Ca reabsorption, activates Vit D) |
| Adrenal Cortex | Cortisol (glucocorticoid), Aldosterone (mineralocorticoid), Androgens | Stress response, Na⁺/K⁺ balance, sex hormone precursors |
| Adrenal Medulla | Epinephrine, Norepinephrine | Sympathoadrenal "fight or flight" response |
| Pancreas | Insulin (β cells), Glucagon (α cells), Somatostatin (δ cells) | Lower/raise blood glucose; suppress both insulin and glucagon |
| Pineal Gland | Melatonin | Circadian rhythm regulation |
| Thymus | Thymosin | T-lymphocyte maturation |
| Cell Type | Normal Count | Function |
|---|---|---|
| Neutrophils | 60-70% | First-line phagocytosis (bacteria) |
| Eosinophils | 2-4% | Parasites, allergic responses |
| Basophils | <1% | Histamine release, allergy |
| Monocytes | 3-8% | Differentiate into macrophages |
| Lymphocytes | 20-30% | Adaptive immunity (B and T cells) |
| Feature | Skeletal | Cardiac | Smooth |
|---|---|---|---|
| Control | Voluntary | Involuntary | Involuntary |
| Appearance | Striated | Striated | Non-striated |
| Nuclei | Multiple peripheral | Single central | Single central |
| T-tubules | Yes (large) | Yes (smaller) | No |
| Ca²⁺ source | SR only | SR + extracellular | Extracellular + SR |
| Mechanism | Troponin-tropomyosin | Troponin-tropomyosin | Calmodulin-MLCK |
| Stage | EEG Pattern | Features |
|---|---|---|
| NREM Stage 1 (N1) | Theta waves (4-8 Hz) | Light sleep, hypnic jerks |
| NREM Stage 2 (N2) | Sleep spindles, K-complexes | True sleep, memory consolidation |
| NREM Stage 3 (N3) | Delta waves (<4 Hz) | Deep/slow-wave sleep; physically restorative; growth hormone released |
| REM | Low-amplitude, mixed frequency (similar to wakefulness) | Dreams, eye movements, atonia; memory consolidation (procedural/emotional) |
| System | Key Function | Master Controller |
|---|---|---|
| Homeostasis | Maintain stable internal environment | Negative feedback loops |
| Respiratory | Gas exchange (O₂/CO₂) | Medullary respiratory centers |
| GI | Digestion, absorption, motility | Enteric NS + hormones |
| Nervous | Signal processing, integration | Brain + spinal cord |
| Endocrine | Chemical signaling, long-term regulation | Hypothalamus-pituitary axis |
| Haematopoietic | Blood cell production, hemostasis | Bone marrow + EPO/TPO |
| Immunity | Defense against pathogens | Innate + adaptive arms |
| Cardiovascular | Oxygen/nutrient delivery | SA node + autonomic NS |
| Muscle | Movement, force generation | Motor neurons + Ca²⁺ |
| Adipose | Energy storage + endocrine signaling | Leptin/insulin axis |
| Male Reproductive | Spermatogenesis + testosterone | HPG axis (LH/FSH) |
| Female Reproductive | Oogenesis, menstrual cycle, pregnancy | HPG axis (cyclical) |
| Excretory (Renal) | Filtration, acid-base, fluid balance | RAAS + ADH + aldosterone |
| Special Senses | Detect environmental stimuli | Thalamus → cortex |
| Sleep | Restoration, memory consolidation | SCN circadian clock + adenosine |
Generate a detailed study guide PDF with diagrams and mechanisms
mkdir -p /home/daytona/workspace/physiology-guide && ls /home/daytona/workspace/…
~/physiology-guide/generate_physiology_pdf.py
#!/usr/bin/env python3
"""
Comprehensive Physiology Study Guide PDF Generator
Covers all 15 major physiology topics with diagrams, tables, and mechanisms
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.lib import colors
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
PageBreak, HRFlowable, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.graphics.shapes import (
Drawing, Rect, Circle, Ellipse, Line, Polygon, PolyLine,
String, Arrow, Group
)
from reportlab.graphics import renderPDF
from reportlab.graphics.charts.lineplots import LinePlot
from reportlab.lib.colors import (
HexColor, blue, red, green, white, black, orange,
lightblue, lightgreen, lightyellow, pink, purple
)
import math
# ─── Color Palette ───────────────────────────────────────────────────────────
DARK_BLUE = HexColor('#1B3A6B')
MED_BLUE = HexColor('#2E6DA4')
LIGHT_BLUE = HexColor('#D6E8F8')
ACCENT_TEAL = HexColor('#17A2B8')
ACCENT_GREEN= HexColor('#28A745')
ACCENT_RED = HexColor('#DC3545')
ACCENT_ORG = HexColor('#FD7E14')
ACCENT_PURP = HexColor('#6F42C1')
LIGHT_GRAY = HexColor('#F8F9FA')
MED_GRAY = HexColor('#6C757D')
DARK_GRAY = HexColor('#343A40')
YELLOW_BG = HexColor('#FFF9C4')
GREEN_BG = HexColor('#E8F5E9')
BLUE_BG = HexColor('#E3F2FD')
RED_BG = HexColor('#FFEBEE')
PURPLE_BG = HexColor('#F3E5F5')
PAGE_W, PAGE_H = A4
# ─── Styles ──────────────────────────────────────────────────────────────────
def make_styles():
base = getSampleStyleSheet()
styles = {}
styles['title'] = ParagraphStyle('title',
fontName='Helvetica-Bold', fontSize=28, textColor=white,
alignment=1, spaceAfter=6, leading=34)
styles['subtitle'] = ParagraphStyle('subtitle',
fontName='Helvetica', fontSize=13, textColor=HexColor('#E8F4FD'),
alignment=1, spaceAfter=4, leading=18)
styles['h1'] = ParagraphStyle('h1',
fontName='Helvetica-Bold', fontSize=17, textColor=white,
spaceAfter=6, spaceBefore=4, leading=22)
styles['h2'] = ParagraphStyle('h2',
fontName='Helvetica-Bold', fontSize=13, textColor=DARK_BLUE,
spaceAfter=4, spaceBefore=8, leading=17)
styles['h3'] = ParagraphStyle('h3',
fontName='Helvetica-Bold', fontSize=11, textColor=MED_BLUE,
spaceAfter=3, spaceBefore=6, leading=15)
styles['body'] = ParagraphStyle('body',
fontName='Helvetica', fontSize=9.5, textColor=DARK_GRAY,
spaceAfter=4, spaceBefore=2, leading=14)
styles['bullet'] = ParagraphStyle('bullet',
fontName='Helvetica', fontSize=9.5, textColor=DARK_GRAY,
spaceAfter=2, spaceBefore=1, leading=13,
leftIndent=14, bulletIndent=4)
styles['small'] = ParagraphStyle('small',
fontName='Helvetica', fontSize=8.5, textColor=MED_GRAY,
spaceAfter=2, leading=12)
styles['key'] = ParagraphStyle('key',
fontName='Helvetica-Bold', fontSize=9.5, textColor=DARK_BLUE,
spaceAfter=2, spaceBefore=2, leading=13,
leftIndent=10)
styles['caption'] = ParagraphStyle('caption',
fontName='Helvetica-Oblique', fontSize=8, textColor=MED_GRAY,
alignment=1, spaceAfter=4, leading=11)
return styles
# ─── Helper Flowables ────────────────────────────────────────────────────────
class SectionHeader(Flowable):
"""Full-width colored section header bar."""
def __init__(self, number, title, color=DARK_BLUE, width=None):
super().__init__()
self.number = number
self.title = title
self.color = color
self.width = width or (PAGE_W - 4*cm)
self.height = 38
def draw(self):
c = self.canv
# Background bar
c.setFillColor(self.color)
c.roundRect(0, 0, self.width, self.height, 6, fill=1, stroke=0)
# Number badge
c.setFillColor(white)
c.setFont('Helvetica-Bold', 11)
badge_x = 12
c.drawString(badge_x, 12, f"{self.number:02d}")
# Title
c.setFont('Helvetica-Bold', 14)
c.drawString(badge_x + 36, 13, self.title)
# Decorative right bar
c.setFillColor(HexColor('#FFFFFF44') if True else white)
c.rect(self.width - 8, 4, 5, self.height - 8, fill=1, stroke=0)
def wrap(self, avW, avH):
self.width = avW
return avW, self.height
class InfoBox(Flowable):
"""Colored info box with left accent bar."""
def __init__(self, text, bg=BLUE_BG, accent=MED_BLUE, width=None, height=None):
super().__init__()
self.text = text
self.bg = bg
self.accent = accent
self._width = width
self._height = height or 40
def wrap(self, avW, avH):
self._width = avW
return avW, self._height
def draw(self):
c = self.canv
c.setFillColor(self.bg)
c.roundRect(0, 0, self._width, self._height, 4, fill=1, stroke=0)
c.setFillColor(self.accent)
c.rect(0, 0, 5, self._height, fill=1, stroke=0)
c.setFillColor(DARK_GRAY)
c.setFont('Helvetica', 8.5)
# wrap text manually
lines = self.text.split('\n')
y = self._height - 13
for line in lines:
c.drawString(12, y, line)
y -= 12
# ─── DIAGRAMS ────────────────────────────────────────────────────────────────
def make_homeostasis_diagram(w=430, h=200):
d = Drawing(w, h)
# Arrow cycle
cx, cy, r = w/2, h/2, 70
boxes = [
(cx, cy+r, "STIMULUS\n(Disturbance)", ACCENT_RED),
(cx+r, cy, "SENSOR\n(Detector)", MED_BLUE),
(cx, cy-r, "EFFECTOR\n(Response)", ACCENT_GREEN),
(cx-r, cy, "CONTROL\nCENTER", ACCENT_PURP),
]
# Draw arcs (simplified as lines with arrows)
pts = [(cx, cy+r), (cx+r, cy), (cx, cy-r), (cx-r, cy)]
for i in range(4):
x1,y1 = pts[i]
x2,y2 = pts[(i+1)%4]
d.add(Line(x1, y1, x2, y2, strokeColor=MED_GRAY, strokeWidth=1.5))
# Draw boxes
bw, bh = 90, 36
for (bx, by, lbl, col) in boxes:
d.add(Rect(bx-bw/2, by-bh/2, bw, bh, rx=6, ry=6,
fillColor=col, strokeColor=white, strokeWidth=1.5))
lines = lbl.split('\n')
for j, line in enumerate(lines):
yoff = 4 if len(lines)==2 else 10
d.add(String(bx, by + yoff - j*11, line,
textAnchor='middle', fontSize=8,
fillColor=white, fontName='Helvetica-Bold'))
# Negative Feedback label
d.add(String(cx, cy+6, "NEGATIVE", textAnchor='middle', fontSize=9,
fillColor=ACCENT_RED, fontName='Helvetica-Bold'))
d.add(String(cx, cy-6, "FEEDBACK", textAnchor='middle', fontSize=9,
fillColor=ACCENT_RED, fontName='Helvetica-Bold'))
return d
def make_action_potential_diagram(w=430, h=180):
d = Drawing(w, h)
# Axes
ox, oy = 50, 20
aw, ah = 360, 140
d.add(Line(ox, oy, ox, oy+ah, strokeColor=DARK_GRAY, strokeWidth=1.5))
d.add(Line(ox, oy+30, ox+aw, oy+30, strokeColor=DARK_GRAY, strokeWidth=1.5))
# Y-axis labels
d.add(String(ox-5, oy+ah-2, "+40 mV", textAnchor='end', fontSize=7, fillColor=DARK_GRAY))
d.add(String(ox-5, oy+28, " 0 mV", textAnchor='end', fontSize=7, fillColor=MED_GRAY))
d.add(String(ox-5, oy+5, "-70 mV", textAnchor='end', fontSize=7, fillColor=DARK_BLUE))
d.add(String(ox-5, oy+15, "-55 mV", textAnchor='end', fontSize=7, fillColor=ACCENT_RED))
# Threshold line
d.add(Line(ox, oy+15, ox+aw, oy+15, strokeColor=ACCENT_RED,
strokeWidth=0.8, strokeDashArray=[4,3]))
# AP curve points (x offset from ox, y offset from baseline oy+30)
# Resting: -70mV, threshold: -55mV, peak: +40mV, repol, undershoot, rest
def mV_to_y(mv): return oy+30 + (mv/110)*ah
pts = [
(0, -70), (30, -70), (55, -55), (70, +40),
(90, +40), (110, -70), (130, -80), (160, -70), (aw, -70)
]
# Draw the curve
poly_pts = [(ox+x, mV_to_y(mv)) for x,mv in pts]
d.add(PolyLine(poly_pts, strokeColor=MED_BLUE, strokeWidth=2.5, strokeLineJoin=1))
# Phase labels
phases = [
(65, +50, "0: Depolarization\n(Na⁺ in)", ACCENT_RED),
(100, +20, "2: Plateau\n(Ca²⁺ in)", ACCENT_ORG),
(120, -60, "3: Repolarization\n(K⁺ out)", ACCENT_GREEN),
(142, -82, "Hyperpolarization", MED_GRAY),
]
for (px, pmv, lbl, col) in phases:
py = mV_to_y(pmv)
lns = lbl.split('\n')
for j, l in enumerate(lns):
d.add(String(ox+px, py + 6 - j*9, l, fontSize=7,
fillColor=col, fontName='Helvetica-Bold'))
d.add(String(ox+aw/2, oy+ah+8, "Time →", textAnchor='middle',
fontSize=8, fillColor=DARK_GRAY))
d.add(String(ox-40, oy+ah/2, "mV", textAnchor='middle',
fontSize=8, fillColor=DARK_GRAY))
return d
def make_cardiac_conduction_diagram(w=350, h=200):
d = Drawing(w, h)
# Heart outline (simplified)
heart_pts = [175, 190, 90, 140, 50, 90, 55, 50, 100, 30,
140, 50, 175, 30, 210, 50, 250, 30, 295, 50,
300, 90, 260, 140, 175, 190]
# Draw heart shape with two arcs (simplified rect-ish)
d.add(Ellipse(110, 60, 130, 110, fillColor=HexColor('#FFE0E0'), strokeColor=ACCENT_RED, strokeWidth=1))
d.add(Ellipse(210, 60, 130, 110, fillColor=HexColor('#FFE0E0'), strokeColor=ACCENT_RED, strokeWidth=1))
d.add(Ellipse(175, 100, 180, 130, fillColor=HexColor('#FFCCCC'), strokeColor=ACCENT_RED, strokeWidth=1))
# Conduction pathway
nodes = [
(140, 130, "SA Node\n(Pacemaker)", ACCENT_RED),
(155, 95, "AV Node\n(Delay)", ACCENT_ORG),
(175, 75, "Bundle\nof His", MED_BLUE),
(155, 50, "L. Bundle\nBranch", ACCENT_GREEN),
(195, 50, "R. Bundle\nBranch", ACCENT_GREEN),
]
# Path arrows
path = [(140,130),(155,95),(175,75),(165,60),(155,50)]
for i in range(len(path)-1):
x1,y1=path[i]; x2,y2=path[i+1]
d.add(Line(x1,y1,x2,y2, strokeColor=DARK_BLUE, strokeWidth=1.5))
for (nx, ny, lbl, col) in nodes:
d.add(Circle(nx, ny, 8, fillColor=col, strokeColor=white, strokeWidth=1))
lines = lbl.split('\n')
for j,l in enumerate(lines):
d.add(String(nx+12, ny+3-j*9, l, fontSize=7,
fillColor=DARK_GRAY, fontName='Helvetica-Bold'))
d.add(String(175, 190, "Cardiac Conduction System",
textAnchor='middle', fontSize=9,
fillColor=DARK_BLUE, fontName='Helvetica-Bold'))
return d
def make_nephron_diagram(w=430, h=220):
d = Drawing(w, h)
# Glomerulus
d.add(Circle(80, 170, 22, fillColor=HexColor('#FFD0D0'), strokeColor=ACCENT_RED, strokeWidth=1.5))
d.add(String(80, 195, "Glomerulus", textAnchor='middle', fontSize=7.5,
fillColor=ACCENT_RED, fontName='Helvetica-Bold'))
d.add(String(80, 160, "GFR\n125 mL/min", textAnchor='middle', fontSize=6.5,
fillColor=DARK_GRAY))
# Proximal tubule
d.add(Rect(120, 155, 70, 28, rx=5, ry=5, fillColor=LIGHT_BLUE,
strokeColor=MED_BLUE, strokeWidth=1.2))
d.add(String(155, 172, "Proximal Tubule", textAnchor='middle', fontSize=7,
fillColor=DARK_BLUE, fontName='Helvetica-Bold'))
d.add(String(155, 162, "67% Na⁺, H₂O, all glucose", textAnchor='middle',
fontSize=6.5, fillColor=DARK_GRAY))
# Loop of Henle
pts = [195,169, 230,169, 250,130, 265,80, 270,40, 265,20,
235,20, 230,40, 235,80, 248,130, 260,155, 280,169]
d.add(PolyLine([(pts[i],pts[i+1]) for i in range(0,len(pts),2)],
strokeColor=ACCENT_TEAL, strokeWidth=2))
d.add(String(258, 10, "Loop of Henle", textAnchor='middle', fontSize=7,
fillColor=ACCENT_TEAL, fontName='Helvetica-Bold'))
d.add(String(258, 1, "Countercurrent mechanism", textAnchor='middle',
fontSize=6, fillColor=MED_GRAY))
# DCT
d.add(Rect(290, 155, 60, 28, rx=5, ry=5, fillColor=GREEN_BG,
strokeColor=ACCENT_GREEN, strokeWidth=1.2))
d.add(String(320, 172, "Distal Tubule", textAnchor='middle', fontSize=7,
fillColor=ACCENT_GREEN, fontName='Helvetica-Bold'))
d.add(String(320, 162, "Ca²⁺, PTH/Vit D", textAnchor='middle',
fontSize=6.5, fillColor=DARK_GRAY))
# Collecting duct
d.add(Rect(360, 80, 55, 100, rx=5, ry=5, fillColor=PURPLE_BG,
strokeColor=ACCENT_PURP, strokeWidth=1.2))
d.add(String(387, 155, "Collecting", textAnchor='middle', fontSize=7,
fillColor=ACCENT_PURP, fontName='Helvetica-Bold'))
d.add(String(387, 145, "Duct", textAnchor='middle', fontSize=7,
fillColor=ACCENT_PURP, fontName='Helvetica-Bold'))
d.add(String(387, 132, "ADH → AQP2", textAnchor='middle', fontSize=6.5,
fillColor=DARK_GRAY))
d.add(String(387, 121, "Aldosterone", textAnchor='middle', fontSize=6.5,
fillColor=DARK_GRAY))
d.add(String(387, 110, "→ Na⁺ in, K⁺ out", textAnchor='middle', fontSize=6.5,
fillColor=DARK_GRAY))
# Arrows
d.add(Line(102,169,120,169, strokeColor=DARK_GRAY, strokeWidth=1.2))
d.add(Line(190,169,195,169, strokeColor=DARK_GRAY, strokeWidth=1.2))
d.add(Line(285,169,290,169, strokeColor=DARK_GRAY, strokeWidth=1.2))
d.add(Line(350,169,360,169, strokeColor=DARK_GRAY, strokeWidth=1.2))
d.add(String(215, 210, "Nephron — Site-by-site Reabsorption",
textAnchor='middle', fontSize=9,
fillColor=DARK_BLUE, fontName='Helvetica-Bold'))
return d
def make_menstrual_cycle_diagram(w=430, h=180):
d = Drawing(w, h)
days = 28
scale = (w - 60) / days
ox, oy = 40, 30
# Day axis
d.add(Line(ox, oy, ox + days*scale, oy, strokeColor=DARK_GRAY, strokeWidth=1))
for day in [1, 7, 14, 21, 28]:
x = ox + (day-1)*scale
d.add(Line(x, oy-3, x, oy+3, strokeColor=DARK_GRAY, strokeWidth=0.8))
d.add(String(x, oy-12, f"{day}", textAnchor='middle', fontSize=7,
fillColor=DARK_GRAY))
d.add(String(ox + days*scale/2, oy-22, "Days of Menstrual Cycle",
textAnchor='middle', fontSize=8, fillColor=DARK_GRAY))
# Phase bands
phases = [
(1, 5, "Menstruation", HexColor('#FFCDD2')),
(1, 14, "Follicular Phase", HexColor('#E3F2FD')),
(14, 15, "Ovulation", HexColor('#FFF9C4')),
(15, 28, "Luteal Phase", HexColor('#E8F5E9')),
]
for (s, e, lbl, col) in phases:
x1 = ox + (s-1)*scale
x2 = ox + (e-1)*scale
bh = 30
d.add(Rect(x1, oy+5, x2-x1, bh, fillColor=col,
strokeColor=MED_GRAY, strokeWidth=0.5))
mid = (x1+x2)/2
d.add(String(mid, oy+14, lbl, textAnchor='middle', fontSize=6.5,
fillColor=DARK_GRAY, fontName='Helvetica-Bold'))
# Hormone curves (simplified)
def day_x(d_val): return ox + (d_val-1)*scale
# Estrogen curve (E2)
e2_pts = [(1,60),(5,63),(8,70),(12,90),(14,95),(16,75),(18,72),(21,80),(25,75),(28,60)]
e2_poly = [(day_x(d), oy+35+v/3) for d,v in e2_pts]
d.add(PolyLine(e2_poly, strokeColor=ACCENT_RED, strokeWidth=1.8))
# Progesterone curve
pg_pts = [(1,60),(14,60),(16,70),(21,90),(25,80),(28,60)]
pg_poly = [(day_x(d), oy+35+v/3) for d,v in pg_pts]
d.add(PolyLine(pg_poly, strokeColor=ACCENT_GREEN, strokeWidth=1.8))
# LH surge
lh_pts = [(12,60),(13,60),(14,100),(15,65),(16,62)]
lh_poly = [(day_x(d), oy+35+v/3) for d,v in lh_pts]
d.add(PolyLine(lh_poly, strokeColor=MED_BLUE, strokeWidth=2.0))
# Legend
legend = [(ACCENT_RED,"Estrogen"), (ACCENT_GREEN,"Progesterone"), (MED_BLUE,"LH Surge")]
for i,(col,lbl) in enumerate(legend):
lx = ox + i*130
d.add(Line(lx, oy+150, lx+18, oy+150, strokeColor=col, strokeWidth=2))
d.add(String(lx+22, oy+146, lbl, fontSize=7.5, fillColor=DARK_GRAY))
return d
def make_sliding_filament_diagram(w=430, h=140):
d = Drawing(w, h)
cy = 70
# Sarcomere box
d.add(Rect(30, cy-50, 370, 100, rx=4, ry=4,
fillColor=HexColor('#F5F5F5'), strokeColor=MED_GRAY, strokeWidth=1))
# Z-lines
for zx in [30, 400]:
d.add(Rect(zx-4, cy-50, 8, 100, fillColor=DARK_BLUE, strokeColor=DARK_BLUE))
d.add(String(zx, cy-58, "Z-line", textAnchor='middle', fontSize=7,
fillColor=DARK_BLUE, fontName='Helvetica-Bold'))
# M-line
d.add(Rect(211, cy-25, 8, 50, fillColor=MED_GRAY, strokeColor=MED_GRAY))
d.add(String(215, cy+35, "M-line", textAnchor='middle', fontSize=7,
fillColor=MED_GRAY))
# Thick filaments (myosin) - center
for y_off in [-18, 18]:
d.add(Rect(80, cy+y_off-5, 260, 10, rx=3, ry=3,
fillColor=ACCENT_RED, strokeColor=HexColor('#B71C1C'), strokeWidth=0.5))
# Myosin heads
for hx in range(95, 340, 25):
d.add(Circle(hx, cy+y_off+(-8 if y_off<0 else 8), 4,
fillColor=ACCENT_ORG, strokeColor=ACCENT_RED, strokeWidth=0.5))
# Thin filaments (actin) - peripheral
for (ax, alen) in [(34, 180), (216, 180)]:
for y_off in [-10, 10]:
d.add(Rect(ax, cy+y_off-3, alen, 6, rx=2,
fillColor=MED_BLUE, strokeColor=DARK_BLUE, strokeWidth=0.5))
# Labels
d.add(String(215, cy-2, "← A Band →", textAnchor='middle', fontSize=7,
fillColor=DARK_GRAY))
d.add(String(60, cy+58, "Actin (Thin)", textAnchor='middle', fontSize=7.5,
fillColor=MED_BLUE, fontName='Helvetica-Bold'))
d.add(String(215, cy+58, "Myosin (Thick)", textAnchor='middle', fontSize=7.5,
fillColor=ACCENT_RED, fontName='Helvetica-Bold'))
d.add(String(215, cy-65, "Sarcomere Structure (Sliding Filament Theory)",
textAnchor='middle', fontSize=9,
fillColor=DARK_BLUE, fontName='Helvetica-Bold'))
return d
def make_immune_diagram(w=430, h=190):
d = Drawing(w, h)
# Two columns: innate (left) and adaptive (right)
# Divider
d.add(Line(215, 10, 215, 185, strokeColor=MED_GRAY,
strokeWidth=1, strokeDashArray=[4,3]))
# Headers
d.add(Rect(10, 165, 195, 25, rx=4, fillColor=ACCENT_ORG, strokeColor=white))
d.add(String(107, 175, "INNATE IMMUNITY", textAnchor='middle', fontSize=9,
fillColor=white, fontName='Helvetica-Bold'))
d.add(Rect(220, 165, 200, 25, rx=4, fillColor=MED_BLUE, strokeColor=white))
d.add(String(320, 175, "ADAPTIVE IMMUNITY", textAnchor='middle', fontSize=9,
fillColor=white, fontName='Helvetica-Bold'))
# Innate cells
innate = [
(60, 130, "Neutrophils\n(Phagocytosis)", HexColor('#FFE0B2')),
(150, 130, "Macrophages\n(APC + Phagocytosis)", HexColor('#FFCCBC')),
(60, 75, "NK Cells\n(Kill virus/tumor)", HexColor('#FCE4EC')),
(150, 75, "Dendritic Cells\n(Best APC)", HexColor('#F3E5F5')),
(105, 25, "Mast Cells\n(Histamine/IgE)", HexColor('#E8EAF6')),
]
for (cx_, cy_, lbl, col) in innate:
d.add(Ellipse(cx_, cy_, 78, 35, fillColor=col,
strokeColor=ACCENT_ORG, strokeWidth=1))
for j,l in enumerate(lbl.split('\n')):
d.add(String(cx_, cy_+5-j*10, l, textAnchor='middle',
fontSize=7, fillColor=DARK_GRAY, fontName='Helvetica-Bold'))
# Adaptive cells
adaptive = [
(280, 130, "CD4+ T Helper\n(MHC II)", HexColor('#E3F2FD')),
(370, 130, "CD8+ Cytotoxic T\n(MHC I → Kill)", HexColor('#E8F5E9')),
(280, 75, "B Cells → Plasma\n(Antibodies IgG/M/A)", HexColor('#FFF9C4')),
(370, 75, "Memory Cells\n(Long-term immunity)", HexColor('#E0F7FA')),
(325, 25, "Tregs\n(Suppress autoimmunity)", HexColor('#FCE4EC')),
]
for (cx_, cy_, lbl, col) in adaptive:
d.add(Ellipse(cx_, cy_, 78, 35, fillColor=col,
strokeColor=MED_BLUE, strokeWidth=1))
for j,l in enumerate(lbl.split('\n')):
d.add(String(cx_, cy_+5-j*10, l, textAnchor='middle',
fontSize=7, fillColor=DARK_GRAY, fontName='Helvetica-Bold'))
return d
def make_respiratory_diagram(w=430, h=180):
d = Drawing(w, h)
# Trachea
d.add(Rect(195, 130, 40, 40, fillColor=LIGHT_BLUE, strokeColor=MED_BLUE, strokeWidth=1.5))
d.add(String(215, 155, "Trachea", textAnchor='middle', fontSize=7,
fillColor=DARK_BLUE, fontName='Helvetica-Bold'))
# Left bronchus
d.add(Line(195, 130, 140, 100, strokeColor=MED_BLUE, strokeWidth=2))
# Right bronchus
d.add(Line(235, 130, 290, 100, strokeColor=MED_BLUE, strokeWidth=2))
# Left lung (ellipse)
d.add(Ellipse(110, 65, 100, 100, fillColor=HexColor('#FFE4E4'),
strokeColor=ACCENT_RED, strokeWidth=1.5))
d.add(String(110, 70, "Left Lung", textAnchor='middle', fontSize=8,
fillColor=DARK_GRAY, fontName='Helvetica-Bold'))
d.add(String(110, 58, "2 lobes", textAnchor='middle', fontSize=7,
fillColor=MED_GRAY))
# Right lung (ellipse)
d.add(Ellipse(320, 65, 100, 100, fillColor=HexColor('#FFE4E4'),
strokeColor=ACCENT_RED, strokeWidth=1.5))
d.add(String(320, 70, "Right Lung", textAnchor='middle', fontSize=8,
fillColor=DARK_GRAY, fontName='Helvetica-Bold'))
d.add(String(320, 58, "3 lobes", textAnchor='middle', fontSize=7,
fillColor=MED_GRAY))
# Alveolus zoom (bottom right)
d.add(Circle(370, 145, 22, fillColor=HexColor('#E3F2FD'),
strokeColor=MED_BLUE, strokeWidth=1.2))
d.add(String(370, 148, "Alveolus", textAnchor='middle', fontSize=7,
fillColor=DARK_BLUE, fontName='Helvetica-Bold'))
d.add(String(370, 138, "O₂ ↔ CO₂", textAnchor='middle', fontSize=7,
fillColor=MED_GRAY))
# Gas exchange arrows
d.add(String(100, 10, "O₂: Alveoli (100) → Blood (40 mmHg) → Tissues",
fontSize=7.5, fillColor=ACCENT_GREEN, fontName='Helvetica-Bold'))
d.add(String(100, 1, "CO₂: Tissues → Blood (45) → Alveoli (40 mmHg) → Expired",
fontSize=7.5, fillColor=ACCENT_RED, fontName='Helvetica-Bold'))
d.add(String(215, 175, "Respiratory System & Gas Exchange",
textAnchor='middle', fontSize=9,
fillColor=DARK_BLUE, fontName='Helvetica-Bold'))
return d
def make_hpa_axis_diagram(w=300, h=220):
d = Drawing(w, h)
boxes = [
(150, 195, "HYPOTHALAMUS\nCRH / TRH / GnRH", DARK_BLUE),
(150, 130, "ANTERIOR PITUITARY\nACTH / TSH / FSH / LH", MED_BLUE),
(150, 65, "TARGET GLAND\n(Adrenal / Thyroid / Gonad)", ACCENT_GREEN),
(150, 10, "HORMONE PRODUCT\n(Cortisol / T3/T4 / Steroids)", ACCENT_TEAL),
]
bw, bh = 190, 34
for i, (bx, by, lbl, col) in enumerate(boxes):
d.add(Rect(bx-bw/2, by, bw, bh, rx=5, ry=5,
fillColor=col, strokeColor=white, strokeWidth=1.5))
lines = lbl.split('\n')
for j,l in enumerate(lines):
d.add(String(bx, by+bh-13-j*12, l, textAnchor='middle',
fontSize=8 if j==0 else 7,
fontName='Helvetica-Bold' if j==0 else 'Helvetica',
fillColor=white))
if i < 3:
d.add(Line(bx, by, bx, by-30, strokeColor=MED_GRAY,
strokeWidth=1.5))
# Arrow head
d.add(Polygon([bx-5, by-26, bx+5, by-26, bx, by-32],
fillColor=MED_GRAY, strokeColor=MED_GRAY))
# Negative feedback arrow
d.add(Line(55, 50, 55, 195, strokeColor=ACCENT_RED, strokeWidth=1.5,
strokeDashArray=[5,3]))
d.add(Polygon([50, 190, 60, 190, 55, 197],
fillColor=ACCENT_RED, strokeColor=ACCENT_RED))
d.add(String(15, 120, "Negative\nFeedback", textAnchor='middle',
fontSize=7.5, fillColor=ACCENT_RED, fontName='Helvetica-Bold'))
d.add(String(150, -8, "Hypothalamic-Pituitary Axis",
textAnchor='middle', fontSize=9,
fillColor=DARK_BLUE, fontName='Helvetica-Bold'))
return d
def make_sleep_diagram(w=430, h=160):
d = Drawing(w, h)
stages = ["Wake", "N1", "N2", "N3", "REM", "N2", "N3", "REM", "N2", "REM"]
y_map = {"Wake": 130, "N1": 110, "N2": 90, "N3": 60, "REM": 80}
colors_map = {
"Wake": ACCENT_ORG, "N1": LIGHT_BLUE, "N2": MED_BLUE,
"N3": DARK_BLUE, "REM": ACCENT_PURP
}
bw = 38
ox = 30
# Draw hypnogram bars
for i, stage in enumerate(stages):
x = ox + i*(bw+4)
y = y_map[stage]
col = colors_map[stage]
d.add(Rect(x, y, bw, 20, rx=3, fillColor=col, strokeColor=white, strokeWidth=0.8))
d.add(String(x+bw/2, y+6, stage, textAnchor='middle', fontSize=7.5,
fillColor=white, fontName='Helvetica-Bold'))
# Connect with lines
for i in range(len(stages)-1):
x1 = ox + i*(bw+4) + bw
x2 = ox + (i+1)*(bw+4)
y1 = y_map[stages[i]] + 10
y2 = y_map[stages[i+1]] + 10
d.add(Line(x1, y1, x2, y2, strokeColor=MED_GRAY, strokeWidth=1))
# Time axis
d.add(Line(ox, 50, ox+len(stages)*(bw+4), 50,
strokeColor=DARK_GRAY, strokeWidth=1))
for i, hr in enumerate(["10pm","11pm","12am","1am","2am","3am","4am","5am","6am"]):
d.add(String(ox + i*(bw+4), 40, hr, fontSize=6.5, fillColor=MED_GRAY))
# Legend
legend_items = [("Wake",ACCENT_ORG),("N1",LIGHT_BLUE),("N2",MED_BLUE),
("N3 (Deep)",DARK_BLUE),("REM",ACCENT_PURP)]
for i,(lbl,col) in enumerate(legend_items):
lx = 30 + i*84
d.add(Rect(lx, 10, 14, 12, fillColor=col, strokeColor=white))
d.add(String(lx+17, 14, lbl, fontSize=7, fillColor=DARK_GRAY))
d.add(String(215, 152, "Sleep Architecture (Hypnogram) — Typical Night",
textAnchor='middle', fontSize=9,
fillColor=DARK_BLUE, fontName='Helvetica-Bold'))
return d
# ─── TABLE BUILDERS ──────────────────────────────────────────────────────────
def make_table(data, col_widths, header_color=DARK_BLUE, stripe_color=LIGHT_BLUE):
style = TableStyle([
('BACKGROUND', (0,0), (-1,0), header_color),
('TEXTCOLOR', (0,0), (-1,0), white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 8.5),
('BOTTOMPADDING',(0,0), (-1,0), 7),
('TOPPADDING', (0,0), (-1,0), 7),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,1), (-1,-1), 8),
('BOTTOMPADDING',(0,1), (-1,-1), 5),
('TOPPADDING', (0,1), (-1,-1), 5),
('ROWBACKGROUNDS',(0,1),(-1,-1),[white, stripe_color]),
('GRID', (0,0), (-1,-1), 0.4, MED_GRAY),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
])
t = Table(data, colWidths=col_widths)
t.setStyle(style)
return t
# ─── PAGE TEMPLATE ───────────────────────────────────────────────────────────
def on_page(canvas, doc):
canvas.saveState()
# Footer
canvas.setFillColor(DARK_BLUE)
canvas.rect(0, 0, PAGE_W, 22, fill=1, stroke=0)
canvas.setFillColor(white)
canvas.setFont('Helvetica', 8)
canvas.drawString(2*cm, 8, "Comprehensive Physiology Study Guide | Sources: Ganong, Costanzo, Guyton & Hall")
canvas.drawRightString(PAGE_W - 2*cm, 8, f"Page {doc.page}")
# Header accent
canvas.setFillColor(MED_BLUE)
canvas.rect(0, PAGE_H - 14, PAGE_W, 14, fill=1, stroke=0)
canvas.setFillColor(white)
canvas.setFont('Helvetica-Bold', 8)
canvas.drawCentredString(PAGE_W/2, PAGE_H - 10, "PHYSIOLOGY STUDY GUIDE")
canvas.restoreState()
# ─── DOCUMENT BUILDER ────────────────────────────────────────────────────────
def build_pdf(path):
doc = SimpleDocTemplate(
path, pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=1.8*cm, bottomMargin=1.5*cm,
title="Comprehensive Physiology Study Guide",
author="Orris AI",
subject="Medical Physiology"
)
S = make_styles()
story = []
# ── COVER PAGE ──────────────────────────────────────────────────────────
story.append(Spacer(1, 2*cm))
# Cover drawing
cover = Drawing(PAGE_W - 4*cm, 220)
cover.add(Rect(0, 0, PAGE_W-4*cm, 220, rx=12, ry=12,
fillColor=DARK_BLUE, strokeColor=MED_BLUE, strokeWidth=3))
# Decorative circles
for (cx2,cy2,r2,alpha) in [(340,180,90,0.15),(60,40,60,0.12),(380,30,50,0.10)]:
cover.add(Circle(cx2, cy2, r2, fillColor=HexColor('#FFFFFF'),
strokeColor=None, strokeWidth=0))
cover.add(String(PAGE_W/2 - 2*cm, 160, "COMPREHENSIVE",
textAnchor='middle', fontSize=22,
fillColor=HexColor('#E8F4FD'), fontName='Helvetica-Bold'))
cover.add(String(PAGE_W/2 - 2*cm, 130, "PHYSIOLOGY",
textAnchor='middle', fontSize=36,
fillColor=white, fontName='Helvetica-Bold'))
cover.add(String(PAGE_W/2 - 2*cm, 100, "STUDY GUIDE",
textAnchor='middle', fontSize=28,
fillColor=ACCENT_TEAL, fontName='Helvetica-Bold'))
cover.add(String(PAGE_W/2 - 2*cm, 68, "15 Major Systems • Mechanisms • Diagrams • Tables",
textAnchor='middle', fontSize=11,
fillColor=HexColor('#B0BEC5'), fontName='Helvetica'))
cover.add(String(PAGE_W/2 - 2*cm, 45, "Based on Ganong • Costanzo • Guyton & Hall • Medical Physiology",
textAnchor='middle', fontSize=9,
fillColor=HexColor('#78909C'), fontName='Helvetica'))
cover.add(String(PAGE_W/2 - 2*cm, 20, "Orris AI | 2026",
textAnchor='middle', fontSize=9,
fillColor=HexColor('#546E7A'), fontName='Helvetica-Oblique'))
story.append(cover)
story.append(Spacer(1, 1.5*cm))
# Topics list on cover
topics = [
"01 Homeostasis", "02 Respiratory System", "03 Gastrointestinal System",
"04 Nervous System", "05 Endocrine Glands", "06 Haematopoietic System",
"07 Immunity", "08 Cardiovascular System", "09 Muscle Physiology",
"10 Adipose Tissue", "11 Male Reproductive System", "12 Female Reproductive System",
"13 Excretory System", "14 Special Senses", "15 Sleep & Dreams"
]
cols = [topics[:8], topics[8:]]
tdata = [[Paragraph(f"<b>{t}</b>", S['small']) for t in row] for row in zip(cols[0], cols[1])]
tbl = make_table(
[["Contents", ""]] + tdata,
[(PAGE_W-4*cm)*0.5, (PAGE_W-4*cm)*0.5],
header_color=MED_BLUE
)
story.append(tbl)
story.append(PageBreak())
# ── SECTION 1: HOMEOSTASIS ───────────────────────────────────────────────
story.append(SectionHeader(1, "HOMEOSTASIS", DARK_BLUE))
story.append(Spacer(1, 6))
story.append(Paragraph("Homeostasis is the body's ability to maintain a stable internal environment despite external and internal changes. Introduced by Claude Bernard as 'milieu intérieur' and named by Walter Cannon.", S['body']))
story.append(Spacer(1, 4))
story.append(Paragraph("Core Mechanism: Negative Feedback Loop", S['h2']))
story.append(make_homeostasis_diagram(430, 195))
story.append(Paragraph("Fig 1.1 — Negative Feedback Loop (the cornerstone of homeostasis)", S['caption']))
story.append(Spacer(1, 6))
story.append(Paragraph("Key Concepts", S['h2']))
homeostasis_data = [
["Mechanism", "Direction", "Example"],
["Negative Feedback", "Opposes deviation from set point", "High glucose → insulin → glucose falls"],
["Positive Feedback", "Amplifies deviation", "LH surge, childbirth contractions, blood clotting"],
["Feedforward Control", "Anticipates change", "Salivating before eating; shivering before cold"],
]
story.append(make_table(homeostasis_data, [4.5*cm, 7*cm, 6*cm]))
story.append(Spacer(1, 4))
story.append(Paragraph("Regulated Variables:", S['h3']))
for item in [
"Osmolality: 285–295 mOsm/kg",
"Blood pH: 7.35–7.45 (arterial 7.40)",
"Core temperature: 37°C",
"Blood glucose: 70–110 mg/dL (fasting)",
"Arterial pO₂: 75–100 mmHg | pCO₂: 35–45 mmHg",
]:
story.append(Paragraph(f"• {item}", S['bullet']))
story.append(PageBreak())
# ── SECTION 2: RESPIRATORY SYSTEM ───────────────────────────────────────
story.append(SectionHeader(2, "RESPIRATORY SYSTEM", MED_BLUE))
story.append(Spacer(1, 6))
story.append(make_respiratory_diagram(430, 180))
story.append(Paragraph("Fig 2.1 — Respiratory System with Gas Exchange Values", S['caption']))
story.append(Spacer(1, 4))
story.append(Paragraph("Lung Volumes & Capacities", S['h2']))
lung_vol_data = [
["Parameter", "Value", "Definition"],
["Tidal Volume (TV)", "~500 mL", "Air per normal breath"],
["Inspiratory Reserve (IRV)", "~3000 mL", "Extra air inhaled forcibly beyond TV"],
["Expiratory Reserve (ERV)", "~1100 mL", "Extra air exhaled beyond normal expiration"],
["Residual Volume (RV)", "~1200 mL", "Air remaining after maximal expiration"],
["Total Lung Capacity (TLC)", "~5800 mL", "TV + IRV + ERV + RV"],
["Vital Capacity (VC)", "~4600 mL", "TLC - RV (max breath in + breath out)"],
["FRC (Functional Residual)", "~2300 mL", "ERV + RV (volume at rest end-expiration)"],
["Dead Space (anatomical)", "~150 mL", "Air in conducting airways, no gas exchange"],
]
story.append(make_table(lung_vol_data, [4*cm, 3*cm, 9.5*cm]))
story.append(Spacer(1, 4))
story.append(Paragraph("Gas Transport in Blood", S['h2']))
for item in [
"O₂ transport: 97% as oxyhemoglobin (HbO₂); 3% dissolved in plasma",
"CO₂ transport: 70% as bicarbonate (HCO₃⁻); 23% carbamino compounds; 7% dissolved",
"Bohr effect: ↑CO₂/↑H⁺/↑temperature → shifts O₂ dissociation curve RIGHT → ↑O₂ release to tissues",
"Haldane effect: Oxygenation of Hb → promotes CO₂ release from blood",
]:
story.append(Paragraph(f"• {item}", S['bullet']))
story.append(Spacer(1, 4))
story.append(Paragraph("Control of Breathing", S['h2']))
ctrl_data = [
["Center/Receptor", "Location", "Stimulus", "Effect"],
["DRG (Dorsal Resp. Group)", "Medulla", "Sets rhythm", "Inspiration"],
["VRG (Ventral Resp. Group)", "Medulla", "Active breathing", "Inspiration + Expiration"],
["Pneumotaxic center", "Pons", "Continuous", "Limits inspiratory duration"],
["Central chemoreceptors", "Medulla", "↑CO₂ / ↓pH in CSF", "↑ Ventilation (primary driver)"],
["Peripheral chemoreceptors", "Carotid & Aortic bodies", "↓pO₂ < 60mmHg, ↑CO₂, ↓pH", "↑ Ventilation"],
]
story.append(make_table(ctrl_data, [3.8*cm, 3.2*cm, 4.5*cm, 5*cm]))
story.append(PageBreak())
# ── SECTION 3: GASTROINTESTINAL ──────────────────────────────────────────
story.append(SectionHeader(3, "GASTROINTESTINAL SYSTEM", ACCENT_GREEN))
story.append(Spacer(1, 6))
story.append(Paragraph("The GI tract (≈9 m long) performs motility, secretion, digestion, and absorption. The enteric nervous system ('second brain') contains ≈100 million neurons and largely controls GI function independently.", S['body']))
story.append(Spacer(1, 4))
story.append(Paragraph("GI Secretions Summary", S['h2']))
secretion_data = [
["Organ", "Volume/day", "Key Secretions", "Stimulated by"],
["Salivary glands", "~1.5 L", "Amylase, mucus, lingual lipase", "Parasympathetics, food sight/smell"],
["Stomach", "~2 L", "HCl (parietal), pepsinogen (chief), intrinsic factor", "Gastrin, ACh, histamine"],
["Pancreas (exocrine)", "~1.5 L", "Bicarbonate, lipase, amylase, trypsin, chymotrypsin", "Secretin (HCO₃⁻), CCK (enzymes)"],
["Liver/Bile", "~0.5 L", "Bile salts, cholesterol, bilirubin, phospholipids", "Secretin, CCK"],
["Small intestine", "~2 L", "Succus entericus, brush-border enzymes", "Local distension"],
]
story.append(make_table(secretion_data, [3.2*cm, 2.5*cm, 6.3*cm, 4.5*cm], ACCENT_GREEN))
story.append(Spacer(1, 4))
story.append(Paragraph("GI Hormones (The Big 4)", S['h2']))
hormone_data = [
["Hormone", "Source", "Stimulus", "Major Actions"],
["Gastrin", "G cells (gastric antrum)", "Protein, distension, vagal stimulation", "↑ HCl, ↑ pepsinogen, ↑ gastric motility"],
["Secretin", "S cells (duodenum)", "Acid (low pH) in duodenum", "↑ Pancreatic HCO₃⁻, ↓ gastric acid"],
["CCK", "I cells (duodenum)", "Fats + proteins in duodenum", "↑ Pancreatic enzymes, gallbladder contraction, ↓ gastric emptying"],
["GIP", "K cells (duodenum)", "Fat + glucose in duodenum", "↓ Gastric acid; incretin (↑ insulin release)"],
]
story.append(make_table(hormone_data, [2.5*cm, 3.5*cm, 4.5*cm, 6*cm], ACCENT_GREEN))
story.append(Spacer(1, 4))
story.append(Paragraph("Nutrient Absorption Mechanisms", S['h3']))
for item in [
"Carbohydrates: Starch → (amylase) → maltose → (brush-border) → glucose/galactose → SGLT1 cotransport; fructose → GLUT5",
"Proteins: → (pepsin, trypsin, chymotrypsin) → amino acids → Na⁺-coupled cotransport; di/tripeptides → PepT1",
"Fats: → (bile salt emulsification) → (lipase) → fatty acids + monoglycerides → micelles → diffuse into enterocytes → chylomicrons → lacteals → lymphatics (not portal vein)",
"Vitamin B12: Binds intrinsic factor (gastric parietal cells) → complex absorbed in terminal ileum",
"Iron: Absorbed as Fe²⁺ (ferrous) in duodenum; regulated by hepcidin",
]:
story.append(Paragraph(f"• {item}", S['bullet']))
story.append(PageBreak())
# ── SECTION 4: NERVOUS SYSTEM ────────────────────────────────────────────
story.append(SectionHeader(4, "NERVOUS SYSTEM", DARK_BLUE))
story.append(Spacer(1, 6))
story.append(Paragraph("The Action Potential", S['h2']))
story.append(make_action_potential_diagram(430, 175))
story.append(Paragraph("Fig 4.1 — Ventricular/Neuronal Action Potential Phases", S['caption']))
story.append(Spacer(1, 6))
story.append(Paragraph("Phases of the Action Potential", S['h3']))
ap_data = [
["Phase", "Ion", "Movement", "Membrane Potential"],
["Phase 0 — Depolarization", "Na⁺", "Rapid INWARD (fast Na⁺ channels)", "-70 mV → +30 to +40 mV"],
["Phase 1 — Early Repolarization", "K⁺ (Ito)", "Transient outward", "+40 → ~0 mV"],
["Phase 2 — Plateau (cardiac only)", "Ca²⁺ (L-type)", "INWARD; K⁺ delayed outward", "Maintained ~0 mV"],
["Phase 3 — Repolarization", "K⁺ (IKr, IKs)", "Rapid OUTWARD", "0 → -70 mV"],
["Phase 4 — Resting (neurons)", "K⁺ leak", "Na⁺/K⁺-ATPase restores", "-70 mV"],
]
story.append(make_table(ap_data, [4.5*cm, 2.5*cm, 4.5*cm, 5*cm]))
story.append(Spacer(1, 4))
story.append(Paragraph("Autonomic Nervous System", S['h2']))
ans_data = [
["Feature", "Sympathetic", "Parasympathetic"],
["Origin", "Thoracolumbar T1–L2", "Craniosacral: CN III, VII, IX, X; S2–S4"],
["Preganglionic NT", "Acetylcholine (nAChR)", "Acetylcholine (nAChR)"],
["Postganglionic NT", "Norepinephrine (adrenergic)", "Acetylcholine (mAChR)"],
["Heart rate", "↑ (β₁)", "↓ (M₂)"],
["Bronchi", "Dilate (β₂)", "Constrict (M₃)"],
["GI motility", "↓ (α₂, β₂)", "↑ (M₃)"],
["Pupils", "Dilate — mydriasis (α₁)", "Constrict — miosis (M₃)"],
["Bladder", "Relaxes (β₂), contracts sphincter (α₁)", "Contracts detrusor (M₃), relaxes sphincter"],
["Adrenal medulla", "ACh → epinephrine/NE release", "No direct innervation"],
]
story.append(make_table(ans_data, [4*cm, 6.5*cm, 6*cm]))
story.append(Spacer(1, 4))
story.append(Paragraph("Key Neurotransmitters", S['h3']))
nt_data = [
["Neurotransmitter", "Location", "Receptor", "Function"],
["Acetylcholine (ACh)", "NMJ, ANS, CNS", "nAChR (ionotropic), mAChR (GPCR)", "Motor control, memory, attention"],
["Dopamine (DA)", "Substantia nigra, VTA", "D1–D5 (GPCR)", "Reward, motor control, motivation"],
["Serotonin (5-HT)", "Raphe nuclei", "5-HT receptors", "Mood, sleep, appetite, GI motility"],
["GABA", "CNS (widespread)", "GABA-A (Cl⁻ channel), GABA-B", "Primary inhibitory NT; reduces neuronal firing"],
["Glutamate", "CNS (widespread)", "NMDA, AMPA, mGluR", "Primary excitatory NT; learning (LTP)"],
["Norepinephrine", "Locus coeruleus, sympathetic", "α, β adrenergic", "Arousal, attention, sympathetic effects"],
]
story.append(make_table(nt_data, [3.5*cm, 3*cm, 4*cm, 6*cm]))
story.append(PageBreak())
# ── SECTION 5: ENDOCRINE ─────────────────────────────────────────────────
story.append(SectionHeader(5, "ENDOCRINE GLANDS", ACCENT_PURP))
story.append(Spacer(1, 6))
story.append(Paragraph("The HPA/HPT/HPG axes all follow the same hierarchical pattern:", S['body']))
story.append(Spacer(1, 4))
# HPA axis diagram side by side with table
story.append(make_hpa_axis_diagram(300, 220))
story.append(Paragraph("Fig 5.1 — Hypothalamic-Pituitary Axis (applies to HPA, HPT, and HPG axes)", S['caption']))
story.append(Spacer(1, 4))
story.append(Paragraph("Major Endocrine Glands", S['h2']))
endo_data = [
["Gland", "Hormone(s)", "Class", "Key Actions"],
["Hypothalamus", "TRH, CRH, GnRH, GHRH, Somatostatin, Dopamine", "Peptide/Amine", "Regulate anterior pituitary; autonomic control"],
["Ant. Pituitary", "TSH, ACTH, FSH, LH, GH, Prolactin", "Peptide/Glycoprotein", "Stimulate target glands; growth; lactation"],
["Post. Pituitary", "ADH (Vasopressin), Oxytocin", "Peptide", "Water reabsorption; uterine contraction/milk ejection"],
["Thyroid", "T3, T4, Calcitonin", "Amine/Peptide", "↑ BMR, growth, development; ↓ blood Ca²⁺"],
["Parathyroid", "PTH", "Peptide", "↑ Blood Ca²⁺ (bone resorption, renal Ca reabsorption, activates Vit D)"],
["Adrenal Cortex", "Cortisol (GC), Aldosterone (MC), Androgens", "Steroid", "Stress; Na⁺/K⁺ balance; sex hormone precursors"],
["Adrenal Medulla", "Epinephrine, Norepinephrine", "Amine (catecholamine)", "Fight-or-flight: ↑HR, ↑BP, ↑glucose, bronchodilation"],
["Pancreas", "Insulin (β), Glucagon (α), Somatostatin (δ)", "Peptide", "↓/↑ blood glucose; suppress both (somatostatin)"],
["Pineal", "Melatonin", "Amine", "Circadian rhythm; sleep onset"],
]
story.append(make_table(endo_data, [2.8*cm, 4.5*cm, 2.7*cm, 6.5*cm], ACCENT_PURP))
story.append(PageBreak())
# ── SECTION 6: HAEMATOPOIETIC ────────────────────────────────────────────
story.append(SectionHeader(6, "HAEMATOPOIETIC SYSTEM", ACCENT_RED))
story.append(Spacer(1, 6))
story.append(Paragraph("Haematopoiesis occurs primarily in red bone marrow (pelvis, sternum, vertebrae, ribs, skull in adults). All blood cells derive from the pluripotent Haematopoietic Stem Cell (HSC).", S['body']))
story.append(Spacer(1, 4))
story.append(Paragraph("Blood Cell Reference Values", S['h2']))
blood_data = [
["Cell Type", "Normal Range", "Lifespan", "Key Function", "Regulator"],
["RBC (Erythrocytes)", "4.5–5.5 ×10⁶/μL", "~120 days", "O₂ transport via hemoglobin", "EPO (kidneys)"],
["Neutrophils", "60–70% of WBC", "6–12 h (tissue)", "First-line phagocytosis of bacteria", "G-CSF"],
["Eosinophils", "2–4%", "8–12 days", "Parasitic defense; allergic inflammation", "IL-5"],
["Basophils", "<1%", "Days", "Histamine release; IgE receptor", "IL-3"],
["Monocytes", "3–8%", "Days→ tissue macrophage", "Phagocytosis; differentiate to macrophages", "M-CSF"],
["Lymphocytes", "20–30%", "Weeks–years", "Adaptive immunity (B and T cells)", "IL-2, IL-4, IL-7"],
["Platelets", "150–400 ×10³/μL", "7–10 days", "Primary hemostasis; coagulation cofactors", "TPO (liver)"],
]
story.append(make_table(blood_data, [3*cm, 3*cm, 3*cm, 4.5*cm, 3*cm], ACCENT_RED))
story.append(Spacer(1, 4))
story.append(Paragraph("Haemostasis: Step-by-step", S['h2']))
hemo_steps = [
("1. Vascular Spasm", "Immediate vasoconstriction; reduces blood flow. Triggered by endothelin release."),
("2. Primary Hemostasis", "Platelet adhesion via vWF → GPIb → platelet activation → TXA₂/ADP release → aggregation via GPIIb/IIIa → PLATELET PLUG"),
("3. Secondary Hemostasis", "Extrinsic: TF + VII → VIIa. Intrinsic: XII → XI → IX → X. Common: Xa + Va → Prothrombin → THROMBIN → Fibrinogen → FIBRIN clot"),
("4. Fibrinolysis", "t-PA activates Plasminogen → Plasmin → cleaves fibrin. Regulated by PAI-1 (inhibits t-PA)."),
]
for (title, desc) in hemo_steps:
story.append(Paragraph(f"<b>{title}:</b> {desc}", S['bullet']))
story.append(PageBreak())
# ── SECTION 7: IMMUNITY ──────────────────────────────────────────────────
story.append(SectionHeader(7, "IMMUNITY", ACCENT_TEAL))
story.append(Spacer(1, 6))
story.append(make_immune_diagram(430, 190))
story.append(Paragraph("Fig 7.1 — Innate vs. Adaptive Immunity: Key Cell Types", S['caption']))
story.append(Spacer(1, 4))
story.append(Paragraph("Innate vs. Adaptive Comparison", S['h2']))
immunity_data = [
["Feature", "Innate Immunity", "Adaptive Immunity"],
["Speed", "Immediate (minutes-hours)", "Days to weeks (first exposure)"],
["Specificity", "Non-specific (PAMPs)", "Highly specific (unique antigens)"],
["Memory", "No memory", "Immunological memory (lifelong)"],
["Key cells", "Neutrophils, macrophages, NK cells, dendritic cells", "T lymphocytes (CD4+, CD8+), B lymphocytes"],
["Recognition", "TLRs, PRRs", "TCR (T cells), BCR/antibodies (B cells)"],
["Effector molecules", "Cytokines, complement, defensins", "Antibodies, perforin, granzymes"],
]
story.append(make_table(immunity_data, [3.5*cm, 6.5*cm, 6.5*cm], ACCENT_TEAL))
story.append(Spacer(1, 4))
story.append(Paragraph("MHC (Major Histocompatibility Complex) — Critical Concept", S['h3']))
mhc_data = [
["MHC Class", "Found On", "Recognized By", "Presents", "Outcome"],
["MHC Class I", "All nucleated cells", "CD8+ CTL", "Intracellular antigens (viral, tumor)", "Cytotoxic killing (perforin/granzymes)"],
["MHC Class II", "APCs only (macrophages, DCs, B cells)", "CD4+ T helper", "Extracellular antigens (bacterial)", "Activation of B cells + macrophages"],
]
story.append(make_table(mhc_data, [2.5*cm, 4*cm, 2.5*cm, 4*cm, 3.5*cm], ACCENT_TEAL))
story.append(PageBreak())
# ── SECTION 8: CARDIOVASCULAR ────────────────────────────────────────────
story.append(SectionHeader(8, "CARDIOVASCULAR SYSTEM", ACCENT_RED))
story.append(Spacer(1, 6))
story.append(make_cardiac_conduction_diagram(350, 200))
story.append(Paragraph("Fig 8.1 — Cardiac Conduction System", S['caption']))
story.append(Spacer(1, 4))
story.append(Paragraph("Cardiac Output & Frank-Starling Law", S['h2']))
story.append(Paragraph("CO = Heart Rate × Stroke Volume. Normal: 60–80 bpm × ~70 mL = ~5 L/min", S['body']))
story.append(Paragraph("Frank-Starling Law: Increased venous return → increased EDV → increased myocyte stretch → increased force of contraction → increased SV. 'The heart pumps whatever blood it receives.'", S['body']))
story.append(Spacer(1, 4))
story.append(Paragraph("Cardiac Cycle Events", S['h2']))
cycle_data = [
["Phase", "Valves", "Pressure", "Volume Change"],
["Isovolumetric Contraction", "All valves CLOSED", "LV pressure ↑ rapidly", "No change (isovolumetric)"],
["Rapid Ejection (Systole)", "Aortic/Pulmonic OPEN", "LV pressure > Aortic", "EDV → ESV (SV ejected)"],
["Isovolumetric Relaxation", "All valves CLOSED", "LV pressure ↓ rapidly", "No change"],
["Rapid Filling (Early Diastole)", "Mitral/Tricuspid OPEN", "LA pressure > LV", "ESV → rapid filling"],
["Slow Filling + Atrial kick", "Mitral OPEN", "Atrial contraction", "Final 20% filling (lost in AF)"],
]
story.append(make_table(cycle_data, [4*cm, 4*cm, 3.5*cm, 5*cm]))
story.append(Spacer(1, 4))
story.append(Paragraph("Blood Pressure Regulation", S['h2']))
bp_data = [
["Mechanism", "Timeframe", "How It Works"],
["Baroreceptor Reflex", "Seconds", "Carotid sinus + aortic arch → medulla → ↑/↓ HR and vasomotor tone"],
["RAAS", "Minutes–hours", "Low BP → Renin → Ang I → Ang II → vasoconstriction + aldosterone → Na⁺ retention → ↑ BP"],
["ADH (Vasopressin)", "Minutes–hours", "Hypothalamus → posterior pituitary → ↑ water reabsorption → ↑ blood volume → ↑ BP"],
["Pressure Natriuresis", "Days", "Kidneys: ↑ BP → ↑ Na⁺ + H₂O excretion → ↓ blood volume → ↓ BP (long-term)"],
]
story.append(make_table(bp_data, [4.5*cm, 3*cm, 9*cm]))
story.append(PageBreak())
# ── SECTION 9: MUSCLE PHYSIOLOGY ─────────────────────────────────────────
story.append(SectionHeader(9, "MUSCLE PHYSIOLOGY", ACCENT_ORG))
story.append(Spacer(1, 6))
story.append(make_sliding_filament_diagram(430, 140))
story.append(Paragraph("Fig 9.1 — Sarcomere Structure: Sliding Filament Theory", S['caption']))
story.append(Spacer(1, 4))
story.append(Paragraph("The Cross-Bridge Cycle (E-C Coupling)", S['h2']))
steps = [
"AP travels down T-tubule → activates dihydropyridine receptor (DHPR)",
"DHPR signals ryanodine receptor (RyR) in SR → Ca²⁺ released into cytoplasm",
"Ca²⁺ binds Troponin C → conformational change → tropomyosin shifts → exposes myosin-binding sites on actin",
"Myosin head (loaded with ADP+Pi) binds actin → POWER STROKE (ADP+Pi released) → filaments slide",
"ATP binds myosin → cross-bridge releases actin → ATP hydrolysis re-cocks myosin head",
"Relaxation: SERCA pump restores Ca²⁺ to SR; Troponin/tropomyosin blocks actin binding sites",
]
for i, step in enumerate(steps, 1):
story.append(Paragraph(f"Step {i}: {step}", S['bullet']))
story.append(Spacer(1, 4))
story.append(Paragraph("Muscle Fiber Types", S['h2']))
fiber_data = [
["Type", "Speed", "Metabolism", "Fatigue", "Myoglobin", "Use"],
["Type I (Slow Oxidative)", "Slow", "Aerobic (oxidative)", "Resistant", "High (red)", "Posture, endurance (marathons)"],
["Type IIa (Fast Oxid-Glyc)", "Fast", "Mixed", "Moderate", "Medium", "Intermediate activities"],
["Type IIx/IIb (Fast Glycolytic)", "Very Fast", "Anaerobic (glycolytic)", "Easy", "Low (white)", "Sprinting, heavy lifting"],
]
story.append(make_table(fiber_data, [3.5*cm, 2*cm, 2.5*cm, 2*cm, 2.5*cm, 4*cm], ACCENT_ORG))
story.append(PageBreak())
# ── SECTION 10: ADIPOSE TISSUE ───────────────────────────────────────────
story.append(SectionHeader(10, "ADIPOSE TISSUE", HexColor('#795548')))
story.append(Spacer(1, 6))
story.append(Paragraph("Adipose tissue is an active endocrine organ, not merely a passive fat store. It secretes hormones (adipokines) that regulate metabolism, inflammation, and appetite.", S['body']))
story.append(Spacer(1, 4))
story.append(Paragraph("Types of Adipose Tissue", S['h2']))
fat_type_data = [
["Type", "Color", "Lipid Droplets", "UCP1", "Function", "Location"],
["White (WAT)", "White/yellow", "Unilocular (single large)", "Absent", "Energy storage, endocrine signaling", "Subcutaneous, visceral"],
["Brown (BAT)", "Brown", "Multilocular (many small)", "Present", "Non-shivering thermogenesis", "Neonates; interscapular, perirenal"],
["Beige/Brite", "Variable", "Multilocular (inducible)", "Inducible", "Thermogenesis on demand", "Within WAT depots"],
]
story.append(make_table(fat_type_data, [2*cm, 2*cm, 3.5*cm, 2*cm, 4.5*cm, 3*cm], HexColor('#795548')))
story.append(Spacer(1, 4))
story.append(Paragraph("Key Adipokines", S['h2']))
adipokine_data = [
["Adipokine", "Stimulus for release", "Target", "Effect"],
["Leptin", "↑ Fat stores", "Hypothalamus (ARC)", "↓ Appetite (inhibit NPY/AgRP); ↑ energy expenditure; deficiency → obesity"],
["Adiponectin", "Fasting, exercise", "Muscle, liver", "↑ Insulin sensitivity (AMPK); anti-inflammatory; ↓ in obesity"],
["Resistin", "Obesity, inflammation", "Liver, muscle", "↑ Insulin resistance; pro-inflammatory"],
["TNF-α", "Obesity", "Systemic", "↑ Insulin resistance; inflammation; links obesity to metabolic syndrome"],
["IL-6", "Obesity (visceral WAT)", "Liver, systemic", "Acute phase response; contributes to insulin resistance"],
]
story.append(make_table(adipokine_data, [2.5*cm, 3.5*cm, 3*cm, 7.5*cm], HexColor('#795548')))
story.append(PageBreak())
# ── SECTION 11: MALE REPRODUCTIVE ───────────────────────────────────────
story.append(SectionHeader(11, "MALE REPRODUCTIVE PHYSIOLOGY", MED_BLUE))
story.append(Spacer(1, 6))
story.append(Paragraph("Testes: Dual Function", S['h2']))
story.append(Paragraph("<b>Spermatogenesis</b> (in seminiferous tubules, supported by Sertoli cells):", S['h3']))
sperm_steps = [
"Spermatogonia (2n) → Mitosis → Primary spermatocyte (2n)",
"Primary spermatocyte → Meiosis I → Secondary spermatocyte (n)",
"Secondary spermatocyte → Meiosis II → Spermatids (n)",
"Spermatids → Spermiogenesis → Spermatozoa (n)",
"Total time: ~74 days | ~300 million sperm/day",
"Requires scrotal temperature 2–3°C below core body temperature",
]
for s in sperm_steps:
story.append(Paragraph(f"→ {s}", S['bullet']))
story.append(Spacer(1, 4))
story.append(Paragraph("HPG Axis (Male)", S['h2']))
male_hpg_data = [
["Signal", "Source", "Target", "Action"],
["GnRH (pulsatile)", "Hypothalamus", "Anterior pituitary", "Stimulates LH + FSH release"],
["LH", "Anterior pituitary", "Leydig cells", "Testosterone synthesis"],
["FSH", "Anterior pituitary", "Sertoli cells", "Spermatogenesis support; inhibin B production"],
["Testosterone", "Leydig cells", "Multiple targets", "Spermatogenesis, secondary sex characteristics, libido, anabolic effects. Negative feedback on hypothalamus/pituitary"],
["Inhibin B", "Sertoli cells", "Pituitary", "Selectively inhibits FSH (negative feedback)"],
]
story.append(make_table(male_hpg_data, [2.5*cm, 3*cm, 3*cm, 8*cm], MED_BLUE))
story.append(Spacer(1, 4))
story.append(Paragraph("Testosterone Metabolism", S['h3']))
for item in [
"Synthesized from cholesterol via steroidogenic pathway (LH → StAR protein → cholesterol → pregnenolone → testosterone)",
"Transported in blood: 44% bound to SHBG (sex hormone-binding globulin); 54% albumin-bound; 2% free (bioactive)",
"Peripheral conversion: → DHT (5α-reductase) in prostate/skin — drives prostate growth, male pattern baldness",
"Aromatization: → Estradiol (E₂) in adipose tissue — important for bone density and libido even in males",
]:
story.append(Paragraph(f"• {item}", S['bullet']))
story.append(PageBreak())
# ── SECTION 12: FEMALE REPRODUCTIVE ─────────────────────────────────────
story.append(SectionHeader(12, "FEMALE REPRODUCTIVE PHYSIOLOGY", ACCENT_RED))
story.append(Spacer(1, 6))
story.append(make_menstrual_cycle_diagram(430, 180))
story.append(Paragraph("Fig 12.1 — Menstrual Cycle: Hormone Levels and Phases", S['caption']))
story.append(Spacer(1, 4))
story.append(Paragraph("The Menstrual Cycle (28 days)", S['h2']))
cycle_data2 = [
["Phase", "Days", "Key Events", "Dominant Hormone"],
["Early Follicular", "1–7", "Menstruation; FSH rises → follicle recruitment; endometrium sheds", "FSH"],
["Late Follicular", "8–13", "Dominant follicle → ↑ estrogen → endometrial proliferation", "Estrogen (E₂)"],
["Ovulation", "14", "E₂ surge → LH surge (positive feedback) → ovulation", "LH surge"],
["Early Luteal", "15–21", "Corpus luteum forms → progesterone + E₂; endometrium secretory", "Progesterone"],
["Late Luteal", "22–28", "If no fertilization: corpus luteum degenerates → P + E fall → menstruation", "Progesterone falling"],
]
story.append(make_table(cycle_data2, [3*cm, 2*cm, 7.5*cm, 4*cm], ACCENT_RED))
story.append(Spacer(1, 4))
story.append(Paragraph("Pregnancy Physiology Key Points", S['h3']))
for item in [
"hCG (from trophoblast): maintains corpus luteum in 1st trimester; basis of pregnancy test",
"Placenta takes over P + E₂ production at ~10 weeks (luteal-placental shift)",
"hPL (human placental lactogen): induces maternal insulin resistance → glucose preserved for fetus",
"Cardiovascular: ↑CO 40%, ↑blood volume 50%, ↓SVR, ↓BP (1st/2nd trimester), physiological anemia",
"Lactation: Prolactin (milk production); Oxytocin (milk ejection/let-down reflex). Estrogen inhibits prolactin during pregnancy",
]:
story.append(Paragraph(f"• {item}", S['bullet']))
story.append(PageBreak())
# ── SECTION 13: EXCRETORY/RENAL ──────────────────────────────────────────
story.append(SectionHeader(13, "EXCRETORY SYSTEM (RENAL PHYSIOLOGY)", ACCENT_TEAL))
story.append(Spacer(1, 6))
story.append(make_nephron_diagram(430, 220))
story.append(Paragraph("Fig 13.1 — The Nephron: Site-by-site reabsorption and secretion", S['caption']))
story.append(Spacer(1, 4))
story.append(Paragraph("Nephron Segment Functions", S['h2']))
nephron_data = [
["Segment", "% Na⁺ Reabsorbed", "Key Transporters/Channels", "Key Hormones"],
["Proximal Tubule (PT)", "~67%", "Na⁺/H⁺ exchanger (NHE3), Na⁺-glucose (SGLT2), Na⁺-AA cotransporter", "None (constitutive)"],
["Thin Desc. Loop of Henle", "0% (H₂O only)", "AQP1 (water channels)", "None"],
["Thick Asc. Loop of Henle", "~25%", "Na⁺/K⁺/2Cl⁻ (NKCC2) — target of LOOP DIURETICS", "None (H₂O impermeable)"],
["Distal Convoluted Tubule", "~5%", "NCC (Na⁺/Cl⁻) — target of THIAZIDE diuretics", "PTH (↑Ca²⁺ reabsorp.), Vit D"],
["Collecting Duct", "~3–5%", "ENaC (Na⁺ channel), AQP2 (water)", "Aldosterone (ENaC ↑), ADH (AQP2 ↑)"],
]
story.append(make_table(nephron_data, [3.5*cm, 2.5*cm, 5.5*cm, 5*cm], ACCENT_TEAL))
story.append(Spacer(1, 4))
story.append(Paragraph("Acid-Base Physiology", S['h2']))
ab_data = [
["Disorder", "pH", "Primary Change", "Compensation", "Common Causes"],
["Metabolic Acidosis", "↓ <7.35", "↓ HCO₃⁻", "↓ pCO₂ (hyperventilation)", "Diabetic ketoacidosis, lactic acidosis, diarrhea, renal failure"],
["Metabolic Alkalosis", "↑ >7.45", "↑ HCO₃⁻", "↑ pCO₂ (hypoventilation)", "Vomiting, diuretics, excess antacids, hyperaldosteronism"],
["Respiratory Acidosis", "↓ <7.35", "↑ pCO₂", "↑ HCO₃⁻ (renal — days)", "COPD, narcotic overdose, neuromuscular disease"],
["Respiratory Alkalosis", "↑ >7.45", "↓ pCO₂", "↓ HCO₃⁻ (renal)", "Anxiety, high altitude, pregnancy, PE"],
]
story.append(make_table(ab_data, [3.5*cm, 1.5*cm, 2.5*cm, 4*cm, 5*cm], ACCENT_TEAL))
story.append(PageBreak())
# ── SECTION 14: SPECIAL SENSES ───────────────────────────────────────────
story.append(SectionHeader(14, "SPECIAL SENSES", ACCENT_PURP))
story.append(Spacer(1, 6))
story.append(Paragraph("Overview of the Five Special Senses", S['h2']))
senses_data = [
["Sense", "Receptor", "Cranial Nerve", "Pathway to Brain", "Primary Cortex"],
["Vision", "Rods (dim/B&W) + Cones (color)", "CN II (Optic)", "Optic nerve → chiasm → LGN (thalamus) → V1", "Occipital lobe (V1, striate cortex)"],
["Hearing", "Hair cells (organ of Corti) on basilar membrane", "CN VIII (Cochlear)", "Cochlear nerve → Cochlear nuclei → IC → MGN → A1", "Superior temporal gyrus"],
["Smell", "Olfactory receptor neurons (OSNs)", "CN I (Olfactory)", "Olfactory bulb → Piriform cortex (bypasses thalamus!)", "Piriform cortex (primary olfactory)"],
["Taste", "Taste receptor cells in taste buds", "CN VII, IX, X", "NTS (medulla) → Thalamus (VPM) → Gustatory cortex", "Anterior insula / frontal operculum"],
["Vestibular (Balance)", "Hair cells in semicircular canals, utricle, saccule", "CN VIII (Vestibular)", "Vestibular nuclei → Cerebellum, thalamus, cortex", "Parietal/Temporal cortex"],
]
story.append(make_table(senses_data, [2.5*cm, 3.5*cm, 2.5*cm, 5*cm, 3*cm], ACCENT_PURP))
story.append(Spacer(1, 4))
story.append(Paragraph("Vision: Phototransduction Mechanism", S['h3']))
photo_steps = [
"Photon hits 11-cis-retinal (chromophore of rhodopsin) → isomerizes to all-trans-retinal → rhodopsin activation",
"Activated rhodopsin → activates Transducin (G-protein Gₜ) → activates PDE",
"PDE hydrolyzes cGMP → ↓ cGMP → closure of cGMP-gated Na⁺/Ca²⁺ channels",
"Result: HYPERPOLARIZATION of photoreceptor (dark: depolarized; light: hyperpolarized)",
"↓ Glutamate release onto bipolar cells → ON bipolar cells depolarize → ganglion cells fire",
"Signal: Optic nerve → optic chiasm (nasal fibers cross) → LGN → V1 (Brodmann area 17)",
]
for i, step in enumerate(photo_steps, 1):
story.append(Paragraph(f"Step {i}: {step}", S['bullet']))
story.append(Spacer(1, 4))
story.append(Paragraph("Hearing: Tonotopy (Frequency Map)", S['h3']))
for item in [
"High-frequency sounds detected at the BASE of the cochlea (stiff basilar membrane)",
"Low-frequency sounds detected at the APEX (flexible basilar membrane)",
"Deflection of stereocilia → opens mechanosensitive K⁺ channels (tip links) → depolarization → glutamate release → CN VIII",
]:
story.append(Paragraph(f"• {item}", S['bullet']))
story.append(PageBreak())
# ── SECTION 15: SLEEP & DREAMS ───────────────────────────────────────────
story.append(SectionHeader(15, "SLEEP AND DREAMS", DARK_BLUE))
story.append(Spacer(1, 6))
story.append(make_sleep_diagram(430, 160))
story.append(Paragraph("Fig 15.1 — Sleep Architecture (Hypnogram): Typical Night of 8 Hours", S['caption']))
story.append(Spacer(1, 4))
story.append(Paragraph("Sleep Stages", S['h2']))
sleep_data = [
["Stage", "EEG Waves", "Features", "Functions"],
["NREM N1", "Theta (4–8 Hz)", "Light sleep; hypnic jerks; easy arousal", "Transition to sleep"],
["NREM N2", "Sleep spindles + K-complexes", "True sleep; 50% of total sleep", "Memory consolidation (declarative); cardiac recovery"],
["NREM N3 (SWS)", "Delta (<4 Hz)", "Deep/slow-wave sleep; hardest to arouse", "Physical restoration; GH release; immune repair; glymphatic clearance"],
["REM Sleep", "Low amplitude, mixed freq (like wakefulness)", "Dreams; REMs; muscle atonia; autonomic surges; penile/clitoral erection", "Emotional memory; procedural learning; synaptic pruning; creativity"],
]
story.append(make_table(sleep_data, [2.5*cm, 3.5*cm, 5.5*cm, 5*cm]))
story.append(Spacer(1, 4))
story.append(Paragraph("Regulation of Sleep: Two-Process Model", S['h2']))
story.append(Paragraph("<b>Process S (Sleep Homeostasis):</b> Adenosine accumulates during waking hours → increasing sleep pressure. Cleared by sleep. Caffeine blocks adenosine A1/A2A receptors, reducing sleepiness.", S['body']))
story.append(Paragraph("<b>Process C (Circadian Clock):</b> Suprachiasmatic nucleus (SCN) in anterior hypothalamus generates ~24-hour rhythm. Entrained by light via retinohypothalamic tract. Melatonin (pineal gland) rises at night (darkness) → promotes sleep onset.", S['body']))
story.append(Spacer(1, 4))
story.append(Paragraph("Neurotransmitters Controlling Sleep-Wake", S['h2']))
nt_sleep_data = [
["NT/Neuropeptide", "Source", "Role", "Clinical Note"],
["Norepinephrine", "Locus Coeruleus", "WAKE-promoting", "Silent in REM; promotes arousal"],
["Serotonin (5-HT)", "Raphe Nuclei", "WAKE-promoting", "Silent in REM; regulates mood + sleep architecture"],
["Histamine", "Tuberomammillary nucleus (TMN)", "WAKE-promoting", "1st-gen antihistamines → drowsiness (cross BBB)"],
["Orexin/Hypocretin", "Lateral hypothalamus", "WAKE-promoting (stabilizes wakefulness)", "LOSS → Narcolepsy (cataplexy, REM intrusion)"],
["GABA + Galanin", "VLPO (ventrolateral preoptic area)", "SLEEP-promoting", "Inhibit all wake-promoting centers"],
["Acetylcholine", "PPT/LDT nuclei", "REM generation", "Active in REM; drives PGO waves"],
["Adenosine", "Widespread", "SLEEP-promoting (homeostatic)", "Builds with waking; caffeine = antagonist"],
]
story.append(make_table(nt_sleep_data, [3.5*cm, 3*cm, 3.5*cm, 6.5*cm]))
story.append(Spacer(1, 4))
story.append(Paragraph("Dreams", S['h3']))
for item in [
"Vivid, narrative, emotional dreams primarily occur in REM sleep",
"Activation-Synthesis Theory (Hobson & McCarley): Brain stem activates random signals during REM; cortex synthesizes them into a narrative",
"NREM dreams: vaguer, more thought-like, less bizarre",
"Memory consolidation: Hippocampal-cortical replay during NREM (declarative); REM for emotional/procedural memories",
"REM rebound: After sleep deprivation, recovery sleep has disproportionately more REM",
]:
story.append(Paragraph(f"• {item}", S['bullet']))
story.append(Spacer(1, 4))
story.append(Paragraph("Sleep Disorders Summary", S['h3']))
disorder_data = [
["Disorder", "Mechanism", "Key Features", "Treatment"],
["Narcolepsy", "Loss of orexin/hypocretin neurons", "Excessive daytime sleepiness, cataplexy, sleep paralysis, hypnagogic hallucinations", "Modafinil, sodium oxybate"],
["Obstructive Sleep Apnea", "Pharyngeal collapse during sleep", "Loud snoring, apneic episodes, daytime sleepiness, hypertension", "CPAP, weight loss"],
["REM Sleep Behavior Disorder", "Loss of REM muscle atonia", "Acting out dreams; injury to self/partner; precursor to Parkinsonism (LBD, PD, MSA)", "Clonazepam, melatonin"],
["Insomnia", "Hyperarousal (CNS, HPA)", "Difficulty initiating/maintaining sleep; daytime impairment", "CBT-I (first-line), z-drugs, melatonin"],
]
story.append(make_table(disorder_data, [3*cm, 3.5*cm, 4.5*cm, 5.5*cm]))
story.append(Spacer(1, 0.5*cm))
story.append(HRFlowable(width="100%", thickness=1, color=MED_BLUE, spaceAfter=6))
story.append(Paragraph("Sources: Ganong's Review of Medical Physiology (26th Ed.) | Costanzo Physiology (7th Ed.) | Guyton and Hall Textbook of Medical Physiology | Medical Physiology (Boron & Boulpaep) | Orris AI 2026", S['small']))
# BUILD
doc.build(story, onFirstPage=on_page, onLaterPages=on_page)
print(f"PDF generated: {path}")
if __name__ == '__main__':
output = '/home/daytona/workspace/physiology-guide/Physiology_Study_Guide.pdf'
build_pdf(output)
cd /home/daytona/workspace/physiology-guide && python3 generate_physiology_pdf.p…
~/physiology-guide/generate_physiology_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/physiology-guide/generate_physiology_pdf.py'
cd /home/daytona/workspace/physiology-guide && python3 generate_physiology_pdf.p…
ls -lh /home/daytona/workspace/physiology-guide/Physiology_Study_Guide.pdf && py…
Physiology Study Guide
PDF Document · PDF
| # | Section | Includes |
|---|---|---|
| 1 | Homeostasis | Negative feedback loop diagram; regulated variables table |
| 2 | Respiratory System | Lung anatomy diagram; lung volumes table; gas transport; chemoreceptor table |
| 3 | Gastrointestinal | GI secretions table; Big 4 hormones table; nutrient absorption mechanisms |
| 4 | Nervous System | Action potential graph with phases; ANS comparison table; neurotransmitters table |
| 5 | Endocrine Glands | HPA/HPT/HPG axis diagram; complete hormone table with classes and actions |
| 6 | Haematopoietic | Blood cell reference values table; haemostasis 4-step mechanism |
| 7 | Immunity | Innate vs. adaptive cell diagram; MHC I/II comparison table |
| 8 | Cardiovascular | Cardiac conduction system diagram; cardiac cycle events; BP regulation table |
| 9 | Muscle Physiology | Sarcomere/sliding filament diagram; 6-step E-C coupling; fiber type table |
| 10 | Adipose Tissue | WAT/BAT/beige comparison; adipokines table with obesity links |
| 11 | Male Reproductive | Spermatogenesis steps; HPG axis table; testosterone metabolism |
| 12 | Female Reproductive | Menstrual cycle hormone graph; cycle phases table; pregnancy physiology |
| 13 | Excretory (Renal) | Nephron diagram with transporters; acid-base disorders table |
| 14 | Special Senses | All 5 senses table; phototransduction 6-step mechanism; cochlear tonotopy |
| 15 | Sleep & Dreams | Hypnogram diagram; sleep stages table; neurotransmitters; sleep disorders |
reload the pdf,unable to download
cd /home/daytona/workspace/physiology-guide && python3 generate_physiology_pdf.p…
Physiology Study Guide
PDF Document · PDF
/home/daytona/workspace/physiology-guide/Physiology_Study_Guide.pdf in the sandboxstill unable to download it
cd /home/daytona/workspace/physiology-guide && python3 -c " from pypdf import Pd…
cp /home/daytona/workspace/physiology-guide/Physiology_Study_Guide.pdf /home/day…
cd /home/daytona/workspace && zip Physiology_Study_Guide.zip Physiology_Study_Gu…
cd /home/daytona/workspace/physiology-guide && zip /home/daytona/workspace/physi…
python3 -c " import sys sys.path.insert(0, '/home/daytona/workspace/physiology-g…
PhysioGuide v2
PDF Document · PDF