Im having pain inleft ankel while night
left ankle pain at night causes diagnosis
"Gout flares have a stereotypic pattern, with rapid onset of maximal pain within 24 hours of onset and gradual resolution over 1 to 2 weeks. These episodes often start during the night."
"Pain typically involves the lower extremities, is usually present at rest, and worsens at night."
| Symptom | Possible Cause |
|---|---|
| Sudden severe pain + redness + swelling | Gout flare or infection (septic arthritis) |
| Burning/tingling + numbness | Nerve compression or neuropathy |
| Pain with rest + morning stiffness | Inflammatory arthritis |
| Fever + hot, swollen joint | Infection - urgent care needed |
| Pain after new exercise/activity | Stress fracture |
Disclaimer: This information is for general educational purposes only and is not a substitute for professional medical advice. Please consult a healthcare provider for a proper diagnosis and treatment plan.
My left ankle makes cracking and poping sounds while moving and I get lost of pain during night
ankle cracking popping sounds with night pain causes crepitus
"Crepitus felt during movement of the joint suggests osteoarthritis."
"Prolonged pain (several weeks to months) following an inversion injury of the ankle, often associated with point tenderness in the area, decreased range of motion, crepitus, and an effusion, should lead the clinician to suspect an osteochondral talar dome fracture."
"In tenosynovitis, pain over the anterior ankle and foot is the primary complaint, and crepitus is common in florid tenosynovitis. Night pain also may be present."
| Question | What it suggests |
|---|---|
| Did you have a previous ankle sprain/injury? | Osteochondral damage, ligament laxity |
| Is the popping on the outer side of ankle? | Peroneal tendon subluxation |
| Is there visible swelling or warmth? | Arthritis, infection, or acute injury |
| Is morning stiffness present (>30 min)? | Inflammatory arthritis (RA, gout) |
| Do you have diabetes or neuropathy? | Diabetic neuropathic arthropathy (Charcot joint) |
| Did pain come on gradually over years? | Osteoarthritis |
Important: Cracking sounds with significant night pain should not be ignored. This combination often means there is structural damage inside the joint that needs imaging to properly diagnose. Please book an appointment with your doctor or an orthopaedic specialist. Early treatment prevents further damage.
Disclaimer: This is educational information only and does not replace a medical consultation.
Vitamin d biochemistry mbbs first year laq
| Form | Source | Chemical Name |
|---|---|---|
| Vitamin D2 (ergocalciferol) | Plants, fungi, fortified foods | Ergocalciferol |
| Vitamin D3 (cholecalciferol) | Animal sources, skin synthesis | Cholecalciferol |
Vitamin D3 has ~10x greater biological potency than D2 due to longer half-life and higher affinity for vitamin D-binding protein.

Memory tip: PTH turns ON kidney hydroxylase; FGF23 and calcitriol turn it OFF.
| Age Group | RDA |
|---|---|
| Children (1-18 years) | 600 IU/day |
| Adults (19-70 years) | 600 IU/day |
| Adults (>70 years) | 800 IU/day |
| Pregnancy/Lactation | 600 IU/day |
| Parameter | Change |
|---|---|
| Serum Ca²⁺ | ↓ or normal |
| Serum Phosphate | ↓ |
| Serum ALP | ↑ (markedly) |
| PTH | ↑ (secondary hyperparathyroidism) |
| 25(OH)D3 | ↓ (best diagnostic marker) |
| 1,25(OH)₂D3 | ↓ (in severe deficiency) |
7-Dehydrocholesterol (Skin)
↓ UV-B
Vitamin D3 (Cholecalciferol)
↓ 25-hydroxylase (Liver)
25(OH)D3 - Calcidiol [Storage form, measured clinically]
↓ 1α-hydroxylase (Kidney) ← Stimulated by PTH, ↓Ca, ↓PO4
1,25(OH)₂D3 - Calcitriol [Active hormone]
↓
VDR → gene expression
→ ↑Ca absorption (gut)
→ ↑Ca reabsorption (kidney)
→ Bone mineralization
→ ↓PTH secretion
Generate practice MCQs on Vitamin D biochemistry and metabolism
| Q | Answer | Topic |
|---|---|---|
| 1 | B | Provitamin in skin |
| 2 | D | Active form name |
| 3 | D | Classification |
| 4 | C | Source of ergosterol |
| 5 | C | Transport protein |
| 6 | B | First hydroxylation |
| 7 | C | Renal activation enzyme |
| 8 | C | Clinical assessment marker |
| 9 | B | 24-hydroxylase role |
| 10 | D | Stimulator of 1-alpha-hydroxylase |
| 11 | C | FGF-23 role |
| 12 | C | Half-life of calcidiol |
| 13 | C | VDR class |
| 14 | C | VDR heterodimerization |
| 15 | B | Calbindin-D |
| 16 | B | Deficiency in children |
| 17 | C | Rachitic rosary |
| 18 | C | Lab finding in deficiency |
| 19 | B | Secondary hyperPTH |
| 20 | B | Toxicity cause |
| 21 | B | CKD bone disease |
| 22 | B | Drug-induced deficiency |
| 23 | C | Best investigation |
| 24 | B | Sarcoidosis hypercalcemia |
| 25 | C | Negative feedback |
Study tip: For exams, focus especially on: the two-step hydroxylation pathway (liver → kidney), regulation of 1-alpha-hydroxylase, calcitriol mechanism via VDR-RXR, and the clinical differences between rickets (children) and osteomalacia (adults). Questions 6-15 are highest yield for MBBS exams.
Create a study guide PDF on Vitamin D with key facts and diagrams
mkdir -p /tmp/workspace/vitamin-d-guide && ls /tmp/workspace/vitamin-d-guide/
~/vitamin-d-guide/create_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, PageBreak
)
from reportlab.platypus.flowables import Flowable
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Arrow, Circle, Polygon
from reportlab.graphics import renderPDF
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Group
import reportlab.graphics.shapes as shapes
# ── Color palette ──────────────────────────────────────────────────────────
SUN_YELLOW = colors.HexColor("#F5A623")
SKIN_PEACH = colors.HexColor("#FFD9B3")
LIVER_RED = colors.HexColor("#C0392B")
KIDNEY_BROWN = colors.HexColor("#8E4B10")
ARROW_GREEN = colors.HexColor("#27AE60")
ARROW_RED = colors.HexColor("#E74C3C")
BOX_BLUE = colors.HexColor("#2980B9")
BOX_LIGHT = colors.HexColor("#EAF4FB")
HEADER_DARK = colors.HexColor("#1A3A5C")
HEADER_MED = colors.HexColor("#2471A3")
ACCENT_TEAL = colors.HexColor("#1ABC9C")
WARN_ORANGE = colors.HexColor("#E67E22")
LIGHT_GREY = colors.HexColor("#F2F3F4")
TABLE_HEADER = colors.HexColor("#1A3A5C")
TABLE_ALT = colors.HexColor("#D6EAF8")
PAGE_BG = colors.white
# ── Page setup ─────────────────────────────────────────────────────────────
PAGE_W, PAGE_H = A4
MARGIN = 1.8 * cm
doc = SimpleDocTemplate(
"/tmp/workspace/vitamin-d-guide/Vitamin_D_Study_Guide.pdf",
pagesize=A4,
leftMargin=MARGIN, rightMargin=MARGIN,
topMargin=MARGIN, bottomMargin=1.5*cm,
title="Vitamin D – MBBS Biochemistry Study Guide",
author="Orris Medical",
)
# ── Styles ──────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
title_style = S("Title2", fontSize=26, textColor=colors.white,
alignment=TA_CENTER, fontName="Helvetica-Bold",
spaceAfter=4, leading=30)
subtitle_style = S("Subtitle", fontSize=13, textColor=colors.HexColor("#D6EAF8"),
alignment=TA_CENTER, fontName="Helvetica", spaceAfter=6)
h1 = S("H1", fontSize=14, textColor=colors.white, fontName="Helvetica-Bold",
spaceBefore=10, spaceAfter=4, leading=18,
backColor=HEADER_DARK, borderPad=6)
h2 = S("H2", fontSize=12, textColor=HEADER_DARK, fontName="Helvetica-Bold",
spaceBefore=8, spaceAfter=3, leading=16,
borderColor=ACCENT_TEAL, borderWidth=0, leftIndent=0)
body = S("Body2", fontSize=9.5, textColor=colors.HexColor("#2C3E50"),
fontName="Helvetica", spaceAfter=4, leading=14, alignment=TA_JUSTIFY)
bullet = S("Bullet2", fontSize=9.5, textColor=colors.HexColor("#2C3E50"),
fontName="Helvetica", spaceAfter=3, leading=14,
leftIndent=14, bulletIndent=4)
bold_body = S("BoldBody", fontSize=9.5, textColor=HEADER_DARK,
fontName="Helvetica-Bold", spaceAfter=3, leading=14)
small = S("Small", fontSize=8, textColor=colors.grey,
fontName="Helvetica", spaceAfter=2, leading=11)
caption = S("Caption", fontSize=8, textColor=colors.HexColor("#5D6D7E"),
fontName="Helvetica-Oblique", alignment=TA_CENTER, spaceAfter=4)
key_fact = S("KeyFact", fontSize=9.5, textColor=colors.HexColor("#1A3A5C"),
fontName="Helvetica-Bold", spaceAfter=3, leading=14,
backColor=colors.HexColor("#FEF9E7"),
borderColor=WARN_ORANGE, borderWidth=1, borderPad=5,
leftIndent=6)
mcq_q = S("McqQ", fontSize=9.5, textColor=HEADER_DARK, fontName="Helvetica-Bold",
spaceAfter=2, leading=14)
mcq_a = S("McqA", fontSize=9, textColor=colors.HexColor("#1D8348"),
fontName="Helvetica-Bold", spaceAfter=1, leading=13)
mcq_opt = S("McqOpt", fontSize=9, textColor=colors.HexColor("#2C3E50"),
fontName="Helvetica", spaceAfter=1, leading=13, leftIndent=10)
# ── Helper flowables ────────────────────────────────────────────────────────
def section_header(text):
"""Coloured section banner."""
data = [[Paragraph(f"<font color='white'><b>{text}</b></font>", h1)]]
t = Table(data, colWidths=[PAGE_W - 2*MARGIN])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), HEADER_DARK),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 10),
("ROUNDEDCORNERS", [4,4,4,4]),
]))
return t
def sub_header(text):
data = [[Paragraph(f"<b>{text}</b>", S("sh", fontSize=11,
textColor=colors.white, fontName="Helvetica-Bold",
leading=15))]]
t = Table(data, colWidths=[PAGE_W - 2*MARGIN])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), HEADER_MED),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 10),
]))
return t
def info_box(text, bg=BOX_LIGHT, border=BOX_BLUE):
data = [[Paragraph(text, S("ib", fontSize=9.5, fontName="Helvetica",
textColor=HEADER_DARK, leading=14))]]
t = Table(data, colWidths=[PAGE_W - 2*MARGIN])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("BOX", (0,0), (-1,-1), 1.5, border),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
]))
return t
def warning_box(text):
return info_box(text, bg=colors.HexColor("#FEF9E7"), border=WARN_ORANGE)
def danger_box(text):
return info_box(text, bg=colors.HexColor("#FDEDEC"), border=ARROW_RED)
def sp(n=1):
return Spacer(1, n * 4)
def hr():
return HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#AED6F1"),
spaceAfter=4, spaceBefore=4)
# ── Metabolism Pathway Diagram ───────────────────────────────────────────────
class MetabolismDiagram(Flowable):
def __init__(self, width, height):
Flowable.__init__(self)
self.width = width
self.height = height
def draw(self):
c = self.canv
w, h = self.width, self.height
# Background
c.setFillColor(colors.HexColor("#F8FBFF"))
c.setStrokeColor(colors.HexColor("#AED6F1"))
c.setLineWidth(1)
c.roundRect(0, 0, w, h, 8, fill=1, stroke=1)
# Title
c.setFillColor(HEADER_DARK)
c.setFont("Helvetica-Bold", 11)
c.drawCentredString(w/2, h - 20, "Vitamin D Metabolism Pathway")
# ── Box positions (x_center, y_center) ──
box_w, box_h = 130, 36
bh = box_h
# Row y positions
y1 = h - 60 # Skin (7-DHC + UV) and Diet
y2 = h - 140 # Cholecalciferol
y3 = h - 220 # Liver → Calcidiol
y4 = h - 300 # Kidney → Calcitriol
y5 = h - 380 # Active & Inactive branches
cx = w / 2 # center X
def draw_box(cx_, cy_, label, sub="", color=BOX_BLUE, text_col=colors.white):
c.setFillColor(color)
c.setStrokeColor(colors.HexColor("#1A3A5C"))
c.setLineWidth(0.8)
c.roundRect(cx_ - box_w/2, cy_ - bh/2, box_w, bh, 6, fill=1, stroke=1)
c.setFillColor(text_col)
c.setFont("Helvetica-Bold", 9)
c.drawCentredString(cx_, cy_ + (6 if sub else 0), label)
if sub:
c.setFont("Helvetica-Oblique", 7.5)
c.drawCentredString(cx_, cy_ - 9, sub)
def draw_arrow(x1, y1_, x2, y2_, col=ARROW_GREEN, label="", label_side="right"):
c.setStrokeColor(col)
c.setLineWidth(1.8)
c.line(x1, y1_, x2, y2_)
# Arrowhead
import math
angle = math.atan2(y2_ - y1_, x2 - x1)
aw = 7
c.setFillColor(col)
c.setStrokeColor(col)
ax = x2 - aw * math.cos(angle)
ay = y2_ - aw * math.sin(angle)
pts = [
(x2, y2_),
(ax + 4*math.sin(angle), ay - 4*math.cos(angle)),
(ax - 4*math.sin(angle), ay + 4*math.cos(angle)),
]
p = c.beginPath()
p.moveTo(*pts[0]); p.lineTo(*pts[1]); p.lineTo(*pts[2]); p.close()
c.drawPath(p, fill=1, stroke=0)
if label:
c.setFont("Helvetica-Oblique", 7.5)
c.setFillColor(colors.HexColor("#5D6D7E"))
lx = (x1+x2)/2 + (10 if label_side == "right" else -60)
ly = (y1_+y2_)/2
c.drawString(lx, ly, label)
# ── Step 0: SUN + SKIN box ──
# Sun symbol
c.setFillColor(SUN_YELLOW)
c.setStrokeColor(colors.HexColor("#E67E22"))
c.setLineWidth(1)
sun_x, sun_y = cx - 145, y1
c.circle(sun_x, sun_y, 14, fill=1, stroke=1)
c.setFont("Helvetica-Bold", 8)
c.setFillColor(colors.white)
c.drawCentredString(sun_x, sun_y - 3, "UV-B")
# Sun rays
c.setStrokeColor(SUN_YELLOW)
c.setLineWidth(1.5)
import math
for i in range(8):
ang = math.radians(i * 45)
c.line(sun_x + 16*math.cos(ang), sun_y + 16*math.sin(ang),
sun_x + 22*math.cos(ang), sun_y + 22*math.sin(ang))
# Skin box
draw_box(cx, y1, "SKIN", "7-Dehydrocholesterol + UV-B", color=SKIN_PEACH,
text_col=HEADER_DARK)
# Diet box (left side)
draw_box(cx - 180, y2, "DIET / SUPPLEMENTS",
"Vit D2 (ergocalciferol) / D3", color=colors.HexColor("#D5F5E3"),
text_col=HEADER_DARK)
# ── Cholecalciferol ──
draw_box(cx, y2, "Cholecalciferol", "(Vitamin D3 – Inactive)",
color=colors.HexColor("#F9E79F"), text_col=HEADER_DARK)
# ── Arrows: Skin → Cholecalciferol ──
draw_arrow(cx, y1 - bh/2, cx, y2 + bh/2, col=ARROW_GREEN,
label="Photolysis + isomerization")
# ── Arrow: Diet → Cholecalciferol ──
draw_arrow(cx - 180 + box_w/2, y2, cx - box_w/2, y2,
col=colors.HexColor("#1ABC9C"), label="gut absorption")
# ── LIVER box ──
draw_box(cx, y3, "LIVER → Calcidiol",
"25(OH)D3 | t½ ≈ 19 days | Storage form",
color=LIVER_RED, text_col=colors.white)
draw_arrow(cx, y2 - bh/2, cx, y3 + bh/2, col=ARROW_GREEN,
label="25-hydroxylase (CYP27A1)")
# ── KIDNEY box ──
draw_box(cx, y4, "KIDNEY → Calcitriol",
"1,25(OH)₂D3 | Active Hormone",
color=KIDNEY_BROWN, text_col=colors.white)
draw_arrow(cx, y3 - bh/2, cx, y4 + bh/2, col=ARROW_GREEN,
label="1α-hydroxylase (CYP27B1)")
# ── Regulation arrows on the right ──
# PTH stimulates (green dashed-like)
reg_x = cx + 175
c.setFillColor(ARROW_GREEN)
c.setFont("Helvetica-Bold", 8)
c.drawString(reg_x - 10, (y3 + y4)/2 + 15, "PTH ↑")
c.setFont("Helvetica", 7.5)
c.setFillColor(colors.HexColor("#5D6D7E"))
c.drawString(reg_x - 10, (y3 + y4)/2 + 4, "↓Ca stimulates")
# Inhibitory: FGF23, Calcitriol
c.setFillColor(ARROW_RED)
c.setFont("Helvetica-Bold", 8)
c.drawString(reg_x - 10, (y3 + y4)/2 - 10, "FGF23 ↓")
c.drawString(reg_x - 10, (y3 + y4)/2 - 22, "Calcitriol ↓")
c.setFont("Helvetica", 7.5)
c.setFillColor(colors.HexColor("#5D6D7E"))
c.drawString(reg_x - 10, (y3 + y4)/2 - 34, "(feedback inhibition)")
# ── Active actions ──
eff_y = y4 - bh/2 - 30
# Intestine, Bone, Kidney boxes
locs = [
(cx - 165, eff_y, "INTESTINE", "↑ Ca²⁺ absorption\n(Calbindin-D)", colors.HexColor("#1ABC9C")),
(cx, eff_y, "BONE", "Mineralization\n↑ Osteocalcin", colors.HexColor("#2471A3")),
(cx + 165, eff_y, "KIDNEY", "↑ Ca/PO₄ reabsorption", colors.HexColor("#8E44AD")),
]
for lx, ly, lbl, lsub, lcol in locs:
draw_box(lx, ly, lbl, lsub, color=lcol)
draw_arrow(cx, y4 - bh/2, lx, ly + bh/2, col=colors.HexColor("#5D6D7E"))
# ── 24-hydroxylase inactivation (right branch from kidney) ──
inact_x = cx + 165
inact_y = y4
# small inactivation label
c.setFillColor(colors.HexColor("#FDEDEC"))
c.setStrokeColor(ARROW_RED)
c.setLineWidth(0.8)
c.roundRect(inact_x - 55, inact_y + 22, 110, 26, 4, fill=1, stroke=1)
c.setFillColor(ARROW_RED)
c.setFont("Helvetica-Bold", 7.5)
c.drawCentredString(inact_x, inact_y + 38, "24-hydroxylase (CYP24A1)")
c.setFont("Helvetica", 7)
c.setFillColor(colors.HexColor("#5D6D7E"))
c.drawCentredString(inact_x, inact_y + 27, "→ Inactive metabolites")
# Legend
leg_y = 14
c.setFont("Helvetica-Bold", 7.5)
c.setFillColor(ARROW_GREEN); c.rect(10, leg_y, 10, 8, fill=1, stroke=0)
c.setFillColor(colors.HexColor("#2C3E50")); c.drawString(24, leg_y+1, "Activation pathway")
c.setFillColor(ARROW_RED); c.rect(140, leg_y, 10, 8, fill=1, stroke=0)
c.setFillColor(colors.HexColor("#2C3E50")); c.drawString(154, leg_y+1, "Inhibition / Inactivation")
c.setFillColor(ARROW_GREEN); c.rect(300, leg_y, 10, 8, fill=1, stroke=0)
c.setFillColor(colors.HexColor("#2C3E50")); c.drawString(314, leg_y+1, "Stimulation (PTH)")
# ── Calcium Homeostasis Diagram ──────────────────────────────────────────────
class CalciumDiagram(Flowable):
def __init__(self, width, height):
Flowable.__init__(self)
self.width = width
self.height = height
def draw(self):
c = self.canv
w, h = self.width, self.height
c.setFillColor(colors.HexColor("#F0FAF5"))
c.setStrokeColor(ACCENT_TEAL)
c.setLineWidth(1)
c.roundRect(0, 0, w, h, 8, fill=1, stroke=1)
c.setFillColor(HEADER_DARK)
c.setFont("Helvetica-Bold", 11)
c.drawCentredString(w/2, h - 20, "Calcium Homeostasis: Role of Calcitriol, PTH & Calcitonin")
box_w, box_h = 110, 32
def box(cx_, cy_, txt, col, tcol=colors.white, sub=""):
c.setFillColor(col); c.setStrokeColor(HEADER_DARK); c.setLineWidth(0.8)
c.roundRect(cx_ - box_w/2, cy_ - box_h/2, box_w, box_h, 5, fill=1, stroke=1)
c.setFillColor(tcol)
c.setFont("Helvetica-Bold", 8.5)
c.drawCentredString(cx_, cy_ + (5 if sub else 0), txt)
if sub:
c.setFont("Helvetica", 7)
c.drawCentredString(cx_, cy_ - 7, sub)
import math
def arrow(x1, y1_, x2, y2_, col=ARROW_GREEN, lbl=""):
c.setStrokeColor(col); c.setLineWidth(1.6)
c.line(x1, y1_, x2, y2_)
angle = math.atan2(y2_ - y1_, x2 - x1)
aw = 7
ax = x2 - aw * math.cos(angle); ay = y2_ - aw * math.sin(angle)
pts = [(x2, y2_),
(ax + 4*math.sin(angle), ay - 4*math.cos(angle)),
(ax - 4*math.sin(angle), ay + 4*math.cos(angle))]
p = c.beginPath(); p.moveTo(*pts[0]); p.lineTo(*pts[1]); p.lineTo(*pts[2]); p.close()
c.setFillColor(col); c.drawPath(p, fill=1, stroke=0)
if lbl:
c.setFont("Helvetica-Oblique", 7)
c.setFillColor(colors.HexColor("#5D6D7E"))
mx, my = (x1+x2)/2, (y1_+y2_)/2
c.drawCentredString(mx, my + 4, lbl)
mid = w / 2
# Serum Ca centre
box(mid, h/2, "Serum Ca²⁺", colors.HexColor("#2980B9"), sub="Normal: 8.5-10.5 mg/dL")
# Low Ca → PTH
box(mid - 190, h/2 + 40, "Parathyroid", LIVER_RED, sub="PTH secreted")
arrow(mid - box_w/2, h/2 + 5, mid - 190 + box_w/2, h/2 + 40, col=ARROW_RED, lbl="↓Ca → PTH↑")
# PTH → Kidney (1α-OH)
box(mid - 190, h/2 - 70, "KIDNEY", KIDNEY_BROWN, sub="1α-OH activated")
arrow(mid - 190, h/2 + 40 - box_h/2, mid - 190, h/2 - 70 + box_h/2, col=ARROW_GREEN, lbl="PTH stimulates")
# Kidney → Calcitriol
box(mid, h/2 - 130, "Calcitriol", colors.HexColor("#8E44AD"), sub="1,25(OH)₂D3")
arrow(mid - 190 + box_w/2, h/2 - 70, mid - box_w/2, h/2 - 130 + box_h/2, col=ARROW_GREEN)
# Calcitriol → Intestine
box(mid + 180, h/2 - 70, "INTESTINE", ACCENT_TEAL, sub="↑ Ca absorption")
arrow(mid + box_w/2, h/2 - 130, mid + 180 - box_w/2, h/2 - 70 + box_h/2, col=ARROW_GREEN, lbl="↑ Calbindin-D")
# Intestine → Serum Ca
arrow(mid + 180, h/2 - 70 + box_h/2, mid + box_w/2, h/2 - 5, col=ARROW_GREEN, lbl="Ca²⁺ absorbed")
# High Ca → Calcitonin
box(mid + 180, h/2 + 50, "Calcitonin", colors.HexColor("#16A085"), sub="(C cells, Thyroid)")
arrow(mid + box_w/2, h/2 + 10, mid + 180 - box_w/2, h/2 + 50, col=ARROW_RED, lbl="↑Ca → Calcitonin↑")
# Calcitonin → Bone (inhibits resorption)
box(mid + 180, h/2 + 130, "BONE", colors.HexColor("#2471A3"), sub="↓ Osteoclast activity")
arrow(mid + 180, h/2 + 50 + box_h/2, mid + 180, h/2 + 130 - box_h/2, col=ARROW_RED, lbl="↓ Resorption")
# PTH → Bone resorption
box(mid - 190, h/2 + 130, "BONE", colors.HexColor("#E74C3C"), sub="↑ Osteoclast activity")
arrow(mid - 190, h/2 + 40 + box_h/2, mid - 190, h/2 + 130 - box_h/2, col=ARROW_GREEN, lbl="PTH → resorption")
# Caption
c.setFont("Helvetica-Oblique", 7.5)
c.setFillColor(colors.HexColor("#5D6D7E"))
c.drawCentredString(w/2, 10, "Green arrows = stimulation/activation | Red arrows = response to hypercalcemia / inhibition")
# ── Cover page ───────────────────────────────────────────────────────────────
class CoverPage(Flowable):
def __init__(self, w, h):
Flowable.__init__(self)
self.width = w
self.height = h
def draw(self):
c = self.canv
w, h = self.width, self.height
# Gradient-like background (two rectangles)
c.setFillColor(HEADER_DARK)
c.rect(0, h*0.45, w, h*0.55, fill=1, stroke=0)
c.setFillColor(colors.HexColor("#2471A3"))
c.rect(0, 0, w, h*0.45, fill=1, stroke=0)
# Sun illustration
import math
sun_x, sun_y, sun_r = w*0.82, h*0.78, 48
c.setFillColor(SUN_YELLOW); c.setStrokeColor(colors.HexColor("#F39C12"))
c.setLineWidth(2)
c.circle(sun_x, sun_y, sun_r, fill=1, stroke=1)
c.setFont("Helvetica-Bold", 10); c.setFillColor(colors.white)
c.drawCentredString(sun_x, sun_y + 3, "UV-B")
for i in range(12):
ang = math.radians(i * 30)
c.setStrokeColor(SUN_YELLOW); c.setLineWidth(2)
c.line(sun_x + (sun_r+6)*math.cos(ang), sun_y + (sun_r+6)*math.sin(ang),
sun_x + (sun_r+16)*math.cos(ang), sun_y + (sun_r+16)*math.sin(ang))
# Title text
c.setFillColor(colors.white)
c.setFont("Helvetica-Bold", 32)
c.drawCentredString(w/2, h*0.72, "VITAMIN D")
c.setFont("Helvetica-Bold", 18)
c.setFillColor(colors.HexColor("#AED6F1"))
c.drawCentredString(w/2, h*0.66, "Biochemistry Study Guide")
c.setFont("Helvetica", 13)
c.setFillColor(colors.HexColor("#D6EAF8"))
c.drawCentredString(w/2, h*0.61, "MBBS First Year | Complete LAQ & MCQ Reference")
# Divider line
c.setStrokeColor(ACCENT_TEAL); c.setLineWidth(2)
c.line(w*0.15, h*0.58, w*0.85, h*0.58)
# Key topics in the lower half
topics = [
"✦ Chemistry & Forms",
"✦ Synthesis Pathway (Skin → Liver → Kidney)",
"✦ Metabolic Activation & Regulation",
"✦ Mechanism of Action via VDR-RXR",
"✦ Functions & Calcium Homeostasis",
"✦ Deficiency: Rickets & Osteomalacia",
"✦ Toxicity & Clinical Pearls",
]
c.setFont("Helvetica", 11)
c.setFillColor(colors.white)
for i, t in enumerate(topics):
c.drawCentredString(w/2, h*0.52 - i*22, t)
# Footer
c.setFont("Helvetica-Oblique", 9)
c.setFillColor(colors.HexColor("#AED6F1"))
c.drawCentredString(w/2, 28, "Orris Medical Education · Sources: Goodman & Gilman, Harrison's, Harper's Biochemistry")
c.drawCentredString(w/2, 16, "For educational purposes only – not a substitute for clinical judgment")
# ──────────────────────────────────────────────────────────────────────────────
# BUILD CONTENT
# ──────────────────────────────────────────────────────────────────────────────
story = []
# ── COVER ──
cover = CoverPage(PAGE_W - 2*MARGIN, PAGE_H - 2*MARGIN)
story.append(cover)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════
# SECTION 1: INTRODUCTION & CHEMISTRY
# ══════════════════════════════════════════════════════════════
story.append(section_header("1. Introduction & Chemistry"))
story.append(sp(2))
story.append(Paragraph(
"Vitamin D is technically a <b>steroid hormone precursor</b> rather than a true dietary vitamin, "
"because under adequate sunlight exposure the human body can synthesise it entirely endogenously. "
"It belongs to the fat-soluble vitamin group (A, D, E, K) and its primary biological role is in "
"<b>calcium and phosphate homeostasis</b>, bone mineralisation, and immune modulation.",
body))
story.append(sp())
# Forms table
story.append(sub_header("Forms of Vitamin D"))
story.append(sp(1))
forms_data = [
["Form", "Chemical Name", "Source", "Notes"],
["Vitamin D2", "Ergocalciferol", "Plants, fungi, fortified foods", "Provitamin: Ergosterol"],
["Vitamin D3", "Cholecalciferol", "Animal tissues, skin synthesis", "Provitamin: 7-Dehydrocholesterol"],
["Calcidiol (25-OHD)", "25-Hydroxycholecalciferol", "Liver (first hydroxylation)", "Major circulating / storage form"],
["Calcitriol", "1,25-Dihydroxycholecalciferol", "Kidney (second hydroxylation)", "ACTIVE HORMONE ← most important"],
["Calcitroic acid", "Degradation product", "Tissues (24-hydroxylase)", "Inactive – excreted in bile"],
]
ft = Table(forms_data, colWidths=[95, 130, 130, 130])
ft.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEADER),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [colors.white, TABLE_ALT]),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("BACKGROUND", (0,5), (-1,5), colors.HexColor("#FDEDEC")),
("FONTNAME", (3,1), (3,1), "Helvetica"),
("FONTNAME", (3,4), (3,4), "Helvetica-Bold"),
("TEXTCOLOR", (3,4), (3,4), LIVER_RED),
]))
story.append(ft)
story.append(sp(2))
story.append(warning_box(
"<b>Key Fact:</b> Vitamin D3 has ~10× greater biological potency than D2 due to a longer "
"half-life and higher affinity for Vitamin D-binding protein (DBP)."
))
story.append(sp(2))
# Sources
story.append(sub_header("Sources of Vitamin D"))
story.append(sp(1))
src_data = [
["Source", "Detail"],
["Sunlight (endogenous)", "UV-B (290–315 nm) photolyses 7-dehydrocholesterol in skin → pre-vitamin D3 → Cholecalciferol (heat-isomerisation)"],
["Dietary (animal)", "Fish liver oil (cod, tuna), egg yolk, butter, liver, fatty fish"],
["Dietary (plant)", "Mushrooms (ergocalciferol after UV exposure), fortified cereals and milk"],
["Supplements", "Available as D2 (ergocalciferol) or D3 (cholecalciferol) capsules"],
]
st = Table(src_data, colWidths=[120, 365])
st.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), HEADER_MED),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [colors.white, TABLE_ALT]),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(st)
story.append(sp(2))
# ══════════════════════════════════════════════════════════════
# SECTION 2: METABOLISM PATHWAY
# ══════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("2. Synthesis & Metabolic Activation Pathway"))
story.append(sp(2))
# Insert the big diagram
diag = MetabolismDiagram(PAGE_W - 2*MARGIN, 430)
story.append(diag)
story.append(sp(1))
story.append(Paragraph(
"<i>Figure 1. Vitamin D metabolism: Skin photosynthesis or dietary absorption → "
"25-hydroxylation in liver (CYP27A1) → 1α-hydroxylation in kidney (CYP27B1) → "
"active calcitriol → organ effects. Inactivation by 24-hydroxylase (CYP24A1).</i>",
caption))
story.append(sp(2))
# Enzyme table
story.append(sub_header("Key Enzymes in Vitamin D Metabolism"))
story.append(sp(1))
enz_data = [
["Enzyme", "Gene", "Location", "Reaction", "Regulation"],
["25-hydroxylase", "CYP27A1 / CYP2R1", "Liver (microsomes + mitochondria)", "Vit D3 → Calcidiol (25-OHD)", "NOT tightly regulated"],
["1α-hydroxylase", "CYP27B1", "Kidney – proximal convoluted tubule", "Calcidiol → Calcitriol", "TIGHTLY REGULATED ★"],
["24-hydroxylase", "CYP24A1", "Kidney, intestine, other tissues", "Calcidiol → 24,25(OH)₂D3 (inactive)\nCalcitriol → 1,24,25(OH)₃D3 (inactive)", "Induced by Calcitriol & FGF23"],
]
et = Table(enz_data, colWidths=[90, 70, 110, 120, 100])
et.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEADER),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8),
("ROWBACKGROUNDS",(0,1), (-1,-1), [colors.white, TABLE_ALT]),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("FONTNAME", (4,2), (4,2), "Helvetica-Bold"),
("TEXTCOLOR", (4,2), (4,2), LIVER_RED),
]))
story.append(et)
story.append(sp(2))
# Regulation box
story.append(sub_header("Regulation of 1α-Hydroxylase (CYP27B1) — KEY EXAM TOPIC"))
story.append(sp(1))
reg_data = [
["STIMULATORS (↑ calcitriol production)", "INHIBITORS (↓ calcitriol production)"],
[
"• Parathyroid hormone (PTH) — MAIN stimulator\n"
"• Hypocalcemia (↓ serum Ca²⁺)\n"
"• Hypophosphatemia (↓ serum PO₄)\n"
"• Prolactin, Growth hormone (minor)",
"• Calcitriol itself (product/feedback inhibition)\n"
"• FGF-23 (fibroblast growth factor-23) from osteocytes\n"
"• Hypercalcemia\n"
"• Hyperphosphatemia\n"
"• Calcitonin (weak)"
],
]
rt = Table(reg_data, colWidths=[240, 245])
rt.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), colors.HexColor("#D5F5E3")),
("BACKGROUND", (1,0), (1,0), colors.HexColor("#FDEDEC")),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("GRID", (0,0), (-1,-1), 0.8, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "TOP"),
("FONTSIZE", (0,1), (-1,1), 8.5),
]))
story.append(rt)
story.append(sp(2))
story.append(warning_box(
"<b>Memory Tip:</b> PTH <b>turns ON</b> the kidney hydroxylase. "
"FGF-23 and calcitriol (product) <b>turn it OFF</b>. "
"Think: when calcium is low → PTH rises → kidney makes more calcitriol → gut absorbs more calcium. "
"When enough calcium restored → calcitriol feeds back to suppress PTH and its own synthesis."
))
# ══════════════════════════════════════════════════════════════
# SECTION 3: MECHANISM OF ACTION
# ══════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("3. Mechanism of Action — VDR Nuclear Receptor"))
story.append(sp(2))
story.append(Paragraph(
"Calcitriol is lipid-soluble and crosses the cell membrane freely. It acts through the "
"<b>Vitamin D Receptor (VDR)</b>, a member of the nuclear receptor superfamily (same family as "
"steroid hormone, thyroid hormone, and retinoic acid receptors).",
body))
story.append(sp(1))
moa_steps = [
("Step 1", "Calcitriol diffuses into the target cell across the plasma membrane (lipid-soluble)."),
("Step 2", "Binds the intracellular Vitamin D Receptor (VDR) with high affinity."),
("Step 3", "VDR-calcitriol complex heterodimerises with Retinoid X Receptor (RXR), which requires 9-cis-retinoic acid (Vitamin A metabolite) as its ligand."),
("Step 4", "VDR–RXR heterodimer translocates to the nucleus and binds Vitamin D Response Elements (VDREs) on target gene DNA."),
("Step 5", "Recruits co-activator proteins → chromatin remodelling → transcription activation."),
("Step 6", "Target genes are expressed: Calbindin-D, Ca²⁺-ATPase, osteocalcin, etc."),
]
moa_data = [[Paragraph(f"<b>{s}</b>", bold_body), Paragraph(d, body)] for s, d in moa_steps]
mt = Table(moa_data, colWidths=[55, 430])
mt.setStyle(TableStyle([
("ROWBACKGROUNDS", (0,0), (-1,-1), [colors.HexColor("#EAF4FB"), colors.white]),
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(mt)
story.append(sp(2))
story.append(info_box(
"<b>Vitamin A & D Interaction:</b> RXR needs 9-cis-retinoic acid (a Vitamin A derivative) to form the "
"heterodimer with VDR. Therefore <b>Vitamin A deficiency impairs Vitamin D signalling</b> even when "
"calcitriol levels are normal — because RXR cannot bind DNA without its own ligand. "
"Conversely, excess Vitamin A forms RXR homodimers, leaving no RXR free to partner with VDR."
))
story.append(sp(2))
# VDR distribution
story.append(sub_header("VDR Distribution and Extra-Skeletal Effects"))
story.append(sp(1))
vdr_data = [
["Tissue / Organ", "Effect of Calcitriol"],
["Small intestine (duodenum)", "↑ Calbindin-D9K & D28K → transcellular Ca²⁺ absorption (PRIMARY function)"],
["Kidney (distal tubule)", "↑ Ca²⁺ and PO₄ reabsorption"],
["Bone (osteoblasts)", "↑ Osteocalcin, bone matrix proteins; at high doses → ↑ osteoclastogenesis"],
["Parathyroid glands", "↓ PTH gene transcription (negative feedback)"],
["Skin (keratinocytes)", "↓ Proliferation, ↑ differentiation → used in psoriasis treatment (calcipotriol)"],
["Immune cells (monocytes, T-cells)", "↑ Macrophage maturation; immunomodulation; ↓ autoimmunity"],
["Muscle", "Maintains muscle function; deficiency → proximal myopathy"],
["Pancreas (β-cells)", "Insulin secretion support; VDD linked to type 2 DM risk"],
]
vt = Table(vdr_data, colWidths=[160, 325])
vt.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEADER),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [colors.white, TABLE_ALT]),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"),
]))
story.append(vt)
# ══════════════════════════════════════════════════════════════
# SECTION 4: CALCIUM HOMEOSTASIS
# ══════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("4. Calcium Homeostasis Diagram"))
story.append(sp(2))
cal_diag = CalciumDiagram(PAGE_W - 2*MARGIN, 360)
story.append(cal_diag)
story.append(sp(1))
story.append(Paragraph(
"<i>Figure 2. Calcium homeostasis loop. Low serum Ca²⁺ → PTH ↑ → 1α-hydroxylase activation → "
"calcitriol ↑ → intestinal absorption ↑ → Ca²⁺ restored. High Ca²⁺ → calcitonin released → "
"osteoclast inhibition → Ca²⁺ lowered.</i>",
caption))
story.append(sp(2))
# Three hormones compare
story.append(sub_header("Comparison: PTH vs Calcitriol vs Calcitonin"))
story.append(sp(1))
comp_data = [
["Parameter", "PTH", "Calcitriol (Active Vit D)", "Calcitonin"],
["Secreted by", "Parathyroid chief cells", "Produced in kidney", "Thyroid C cells (parafollicular)"],
["Stimulus", "↓ Ca²⁺, ↓ Mg²⁺", "PTH, ↓ Ca²⁺, ↓ PO₄", "↑ Ca²⁺"],
["Effect on serum Ca", "↑ (raises Ca)", "↑ (raises Ca)", "↓ (lowers Ca)"],
["Effect on bone", "↑ Resorption (osteoclast)", "Mineralisation; mobilises Ca at high dose", "↓ Resorption (osteoclast inhibition)"],
["Effect on kidney", "↑ Ca reabsorption, ↓ PO₄ reabsorption (phosphaturia)", "↑ Ca + PO₄ reabsorption", "Minor"],
["Effect on gut", "Indirect (via calcitriol)", "↑↑ Ca + PO₄ absorption (MAIN effect)", "Minimal"],
["Half-life", "Minutes", "4–6 hours", "Minutes"],
]
ct = Table(comp_data, colWidths=[90, 120, 130, 115])
ct.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEADER),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8),
("ROWBACKGROUNDS",(0,1), (-1,-1), [colors.white, TABLE_ALT]),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "TOP"),
("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"),
]))
story.append(ct)
# ══════════════════════════════════════════════════════════════
# SECTION 5: DEFICIENCY
# ══════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("5. Vitamin D Deficiency — Rickets & Osteomalacia"))
story.append(sp(2))
story.append(sub_header("Causes of Vitamin D Deficiency"))
story.append(sp(1))
cause_data = [
["Category", "Examples"],
["Inadequate sunlight", "Indoor lifestyle, dark skin (melanin blocks UV-B), high-latitude living, winter months, sunscreen overuse"],
["Low dietary intake", "Vegan diet (no fish/eggs), exclusively breastfed infants (human milk is poor in Vit D)"],
["Malabsorption", "Celiac disease, Crohn's disease, cystic fibrosis, short bowel syndrome (fat malabsorption)"],
["Liver disease", "↓ 25-hydroxylation (CYP27A1 impaired)"],
["Renal failure (CKD)", "↓ 1α-hydroxylation (CYP27B1 impaired) → renal osteodystrophy"],
["Drug-induced", "Phenytoin, phenobarbitone (induce CYP450 → accelerate Vit D catabolism) — give supplements!"],
["Hereditary", "Vit D-dependent rickets type 1 (CYP27B1 mutation), type 2 (VDR mutation)"],
["Increased metabolism", "Hyperthyroidism, hyperparathyroidism, sarcoidosis (excess 1α-hydroxylase in macrophages)"],
]
caut = Table(cause_data, colWidths=[130, 355])
caut.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEADER),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [colors.white, TABLE_ALT]),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("FONTNAME", (0,1), (0,-1), "Helvetica-Bold"),
]))
story.append(caut)
story.append(sp(2))
# Rickets vs Osteomalacia side-by-side
story.append(sub_header("Rickets (Children) vs Osteomalacia (Adults)"))
story.append(sp(1))
rv_data = [
[Paragraph("<b>RICKETS</b>\n(Children — open growth plates)",
S("rh", fontSize=10, fontName="Helvetica-Bold", textColor=colors.white, alignment=TA_CENTER)),
Paragraph("<b>OSTEOMALACIA</b>\n(Adults — closed growth plates)",
S("rh2", fontSize=10, fontName="Helvetica-Bold", textColor=colors.white, alignment=TA_CENTER))],
[
Paragraph(
"• <b>Craniotabes</b> — softening of skull bones (earliest sign)\n"
"• <b>Frontal bossing</b> — square-shaped head\n"
"• <b>Delayed fontanelle closure</b>\n"
"• <b>Rachitic rosary</b> — enlarged costochondral junctions\n"
"• <b>Harrison's sulcus</b> — horizontal groove along lower ribs\n"
"• <b>Pigeon chest / pectus carinatum</b>\n"
"• <b>Genu varum</b> (bow legs) or <b>Genu valgum</b> (knock knees)\n"
"• Delayed dentition, pot-belly\n"
"• X-ray: Cupped, frayed, widened epiphyses\n ('paintbrush' / 'champagne glass' appearance)",
S("ric", fontSize=8.5, fontName="Helvetica", leading=14, textColor=HEADER_DARK)),
Paragraph(
"• <b>Bone pain</b> and diffuse tenderness (especially pelvis, spine, femur)\n"
"• <b>Proximal muscle weakness</b> — waddling gait\n"
"• <b>Pathological fractures</b>\n"
"• <b>Looser's zones (Milkman's fractures)</b> — "
"pseudofractures on X-ray\n"
"• Tetany if hypocalcaemia is severe\n"
"• Pelvic deformity in women → difficult labour\n"
"• X-ray: Generalised osteopenia, cortical thinning,\n Looser's zones (pathognomonic)",
S("ost", fontSize=8.5, fontName="Helvetica", leading=14, textColor=HEADER_DARK)),
],
]
rvt = Table(rv_data, colWidths=[242, 242])
rvt.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,0), LIVER_RED),
("BACKGROUND", (1,0), (1,0), KIDNEY_BROWN),
("BACKGROUND", (0,1), (0,1), colors.HexColor("#FDEDEC")),
("BACKGROUND", (1,1), (1,1), colors.HexColor("#FDFEFE")),
("GRID", (0,0), (-1,-1), 0.8, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(rvt)
story.append(sp(2))
# Lab findings
story.append(sub_header("Laboratory Findings in Vitamin D Deficiency"))
story.append(sp(1))
lab_data = [
["Parameter", "Change", "Reason"],
["Serum 25(OH)D3 (calcidiol)", "↓↓ (< 20 ng/mL = deficient)", "Best diagnostic marker of body stores"],
["Serum Ca²⁺", "↓ or normal", "Compensated by secondary ↑PTH"],
["Serum Phosphate", "↓", "PTH causes phosphaturia"],
["Alkaline Phosphatase (ALP)", "↑↑ (MARKEDLY)", "Osteoblast overactivity trying to mineralise osteoid"],
["Parathyroid Hormone (PTH)", "↑↑ (secondary hyperPTH)", "Hypocalcaemia drives parathyroid"],
["Serum 1,25(OH)₂D3 (calcitriol)", "↓ in severe deficiency; may be normal early", "PTH can maintain calcitriol temporarily"],
["Urinary calcium", "↓ (hypocalciuria)", "Less gut absorption, kidney conserves Ca"],
]
lt = Table(lab_data, colWidths=[160, 120, 205])
lt.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEADER),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [colors.white, TABLE_ALT]),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("BACKGROUND", (0,4), (-1,4), colors.HexColor("#FDFEFE")),
("FONTNAME", (1,4), (1,4), "Helvetica-Bold"),
("TEXTCOLOR", (1,4), (1,4), LIVER_RED),
]))
story.append(lt)
# ══════════════════════════════════════════════════════════════
# SECTION 6: TOXICITY & REQUIREMENTS
# ══════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("6. Toxicity, Requirements & Clinical Pearls"))
story.append(sp(2))
# Daily requirements
story.append(sub_header("Daily Requirements (RDA)"))
story.append(sp(1))
rda_data = [
["Age Group", "RDA (IU/day)", "Note"],
["Infants (0-12 months)", "400 IU", "Supplement if breastfed"],
["Children & Adults (1-70 years)", "600 IU", "Standard recommendation"],
["Adults > 70 years", "800 IU", "Reduced skin synthesis with age"],
["Pregnancy & Lactation", "600 IU", "Monitor serum 25-OHD"],
["Tolerable Upper Limit (adults)", "4000 IU/day", "Above this: risk of toxicity"],
]
rdat = Table(rda_data, colWidths=[160, 100, 225])
rdat.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEADER),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [colors.white, TABLE_ALT]),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("BACKGROUND", (0,6), (-1,6), colors.HexColor("#FDEDEC")),
("FONTNAME", (0,6), (-1,6), "Helvetica-Bold"),
]))
story.append(rdat)
story.append(sp(2))
# Toxicity
story.append(sub_header("Hypervitaminosis D (Vitamin D Toxicity)"))
story.append(sp(1))
story.append(info_box(
"<b>Cause:</b> ALWAYS due to excessive oral supplementation (NOT sunlight). "
"Sunlight causes photodegradation of excess pre-vitamin D3 to inactive lumisterol and tachysterol — "
"a natural protective mechanism.\n\n"
"<b>Mechanism:</b> Excess calcitriol → hypercalcaemia + hypercalciuria\n\n"
"<b>Features:</b> Nausea, vomiting, anorexia, polyuria, polydipsia, constipation, weakness, "
"confusion. Metastatic calcification (kidneys, blood vessels, soft tissues). Renal stones → renal failure.\n\n"
"<b>Lab:</b> ↑↑ serum Ca²⁺, ↑ urinary Ca, ↑ 25-OHD, ↓ PTH (suppressed)\n\n"
"<b>Treatment:</b> Stop supplements · restrict dietary calcium · IV fluids · furosemide (calciuresis) · "
"glucocorticoids (↓ intestinal Ca absorption) · bisphosphonates if severe"
))
story.append(sp(2))
# Clinical pearls
story.append(sub_header("High-Yield Clinical Pearls for Exams"))
story.append(sp(1))
pearls = [
("Best marker of Vitamin D status", "Serum 25(OH)D3 (calcidiol) — NOT calcitriol"),
("Best marker of active function", "Serum 1,25(OH)₂D3 (calcitriol)"),
("Site of 25-hydroxylation", "Liver (CYP27A1) — NOT regulated"),
("Site of 1α-hydroxylation", "Kidney PCT (CYP27B1) — TIGHTLY regulated"),
("Major stimulator of 1α-OH", "PTH (parathyroid hormone)"),
("Major inhibitors of 1α-OH", "FGF-23 and calcitriol itself (feedback inhibition)"),
("Inactivating enzyme", "24-hydroxylase (CYP24A1) — induced by calcitriol + FGF23"),
("VDR heterodimerises with", "RXR (Retinoid X Receptor — requires Vitamin A)"),
("Primary intestinal action", "Induces calbindin-D → transcellular Ca²⁺ absorption"),
("Why rickets ≠ osteomalacia", "Rickets = children (open growth plates deformed); Osteomalacia = adults"),
("Pathognomonic X-ray in osteomalacia", "Looser's zones (Milkman's pseudofractures)"),
("Earliest sign of rickets", "Craniotabes (ping-pong ball feel on skull)"),
("Drug causing Vit D deficiency", "Phenytoin / phenobarbitone (CYP inducers accelerate Vit D catabolism)"),
("Sarcoidosis + hypercalcaemia", "Macrophages in granulomas express unregulated 1α-hydroxylase → excess calcitriol"),
("CKD bone disease treatment", "1-alpha-calcidol or calcitriol (bypasses defective kidney step)"),
("Toxicity NOT from sunlight", "Photodegradation to lumisterol/tachysterol limits skin synthesis automatically"),
]
for param, value in pearls:
row_data = [[
Paragraph(f"<b>{param}</b>", S("pp", fontSize=8.5, fontName="Helvetica-Bold",
textColor=HEADER_DARK, leading=12)),
Paragraph(value, S("pv", fontSize=8.5, fontName="Helvetica",
textColor=colors.HexColor("#2C3E50"), leading=12)),
]]
pt = Table(row_data, colWidths=[185, 300])
pt.setStyle(TableStyle([
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("ROWBACKGROUNDS",(0,0), (-1,-1), [colors.HexColor("#EAF4FB")]),
]))
story.append(pt)
story.append(sp(2))
# ══════════════════════════════════════════════════════════════
# SECTION 7: QUICK REFERENCE SUMMARY
# ══════════════════════════════════════════════════════════════
story.append(PageBreak())
story.append(section_header("7. Quick Reference Summary Diagram"))
story.append(sp(2))
# ASCII-style pathway as a nice table
story.append(sub_header("Step-by-Step Synthesis Pathway (Exam Diagram)"))
story.append(sp(1))
path_data = [
["STEP", "LOCATION", "SUBSTRATE → PRODUCT", "ENZYME", "REGULATION"],
["0 (Photo)", "Skin", "7-Dehydrocholesterol + UV-B → Pre-Vit D3 → Cholecalciferol (D3)", "Photolysis + heat isomerisation", "Melanin, sunscreen ↓"],
["1", "Liver", "Cholecalciferol → 25(OH)D3 (Calcidiol)", "25-Hydroxylase CYP27A1", "NOT regulated (substrate-driven)"],
["2 ★", "Kidney PCT", "25(OH)D3 → 1,25(OH)₂D3 (Calcitriol)", "1α-Hydroxylase CYP27B1", "PTH ↑, ↓Ca ↑, FGF23 ↓, Calcitriol ↓"],
["Inactivation", "Kidney, tissues", "Calcidiol/Calcitriol → 24,25-OH / 1,24,25-OH forms", "24-Hydroxylase CYP24A1", "Induced by calcitriol & FGF23"],
]
pat = Table(path_data, colWidths=[52, 62, 160, 110, 105])
pat.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TABLE_HEADER),
("TEXTCOLOR", (0,0), (-1,0), colors.white),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8),
("ROWBACKGROUNDS",(0,1), (-1,-1), [colors.HexColor("#F0FFF0"), colors.white,
colors.HexColor("#FEF9E7"), colors.HexColor("#FDEDEC")]),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("FONTNAME", (0,3), (0,3), "Helvetica-Bold"),
("TEXTCOLOR", (0,3), (0,3), LIVER_RED),
("BACKGROUND", (0,3), (-1,3), colors.HexColor("#FEF9E7")),
]))
story.append(pat)
story.append(sp(2))
story.append(danger_box(
"<b>★ Step 2 (1α-hydroxylation in kidney) is the KEY REGULATED STEP and the most common exam focus.</b>\n"
"Stimulated by: PTH, ↓Ca, ↓PO₄ | Inhibited by: Calcitriol (product inhibition), FGF-23, ↑Ca"
))
story.append(sp(2))
# Final memory box
story.append(sub_header("Must-Remember Facts (Viva Voce Ready)"))
story.append(sp(1))
must_facts = [
"Vitamin D is a HORMONE PRECURSOR, not truly a vitamin when sunlight is adequate.",
"Two forms: D2 (ergocalciferol from plants) and D3 (cholecalciferol from skin/animals). D3 is more potent.",
"Provitamin in human skin = 7-DEHYDROCHOLESTEROL. Provitamin in plants = ERGOSTEROL.",
"First hydroxylation at C-25 in the LIVER (CYP27A1) → Calcidiol (storage form, measured clinically, t½ = 19 days).",
"Second hydroxylation at C-1α in the KIDNEY PCT (CYP27B1) → Calcitriol (active form, t½ = 4-6 hours).",
"Calcitriol acts via VDR–RXR heterodimer → nuclear receptor → gene transcription.",
"Primary action: ↑ intestinal Ca²⁺ absorption via CALBINDIN-D induction.",
"Deficiency in children = RICKETS (growth plate deformity). In adults = OSTEOMALACIA (Looser's zones).",
"ALP is markedly ↑ in both rickets and osteomalacia (hallmark lab finding).",
"Secondary hyperPTH occurs in Vit D deficiency due to hypocalcaemia.",
"Vitamin D TOXICITY comes only from supplements — sunlight NEVER causes toxicity (photodegradation).",
"Sarcoidosis causes hypercalcaemia via unregulated 1α-hydroxylase in granuloma macrophages.",
"Phenytoin/phenobarbitone induce CYP450 → accelerate Vit D degradation → supplement these patients.",
"CKD patients get renal osteodystrophy due to ↓ 1α-hydroxylation → treat with calcitriol directly.",
]
for i, fact in enumerate(must_facts):
bg = colors.HexColor("#EAF4FB") if i % 2 == 0 else colors.white
fd = [[Paragraph(f"<b>{i+1}.</b> {fact}",
S("mf", fontSize=8.5, fontName="Helvetica", leading=13,
textColor=HEADER_DARK))]]
ft2 = Table(fd, colWidths=[PAGE_W - 2*MARGIN])
ft2.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#AED6F1")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
]))
story.append(ft2)
story.append(sp(3))
story.append(Paragraph(
"<i>Study Guide compiled from: Goodman & Gilman's Pharmacological Basis of Therapeutics | "
"Harrison's Principles of Internal Medicine 22E | Harper's Illustrated Biochemistry 32nd Ed. "
"For educational use only.</i>",
S("disc", fontSize=7.5, textColor=colors.grey, fontName="Helvetica-Oblique",
alignment=TA_CENTER)))
# ── Build PDF ──────────────────────────────────────────────────────────────
doc.build(story)
print("PDF created successfully!")
cd /tmp/workspace/vitamin-d-guide && python create_pdf.py 2>&1
~/vitamin-d-guide/create_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/vitamin-d-guide/create_pdf.py'
cd /tmp/workspace/vitamin-d-guide && python create_pdf.py 2>&1
~/vitamin-d-guide/create_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/vitamin-d-guide/create_pdf.py'
cd /tmp/workspace/vitamin-d-guide && python create_pdf.py 2>&1
ls -lh /tmp/workspace/vitamin-d-guide/Vitamin_D_Study_Guide.pdf
Vitamin D Study Guide
PDF Document · PDF
| Section | Content |
|---|---|
| Cover Page | Illustrated cover with UV-B sun graphic and topic overview |
| 1. Introduction & Chemistry | Forms table (D2/D3/Calcidiol/Calcitriol), sources, key facts |
| 2. Metabolism Pathway | Full colour pathway diagram: Skin → Liver → Kidney → Organs, enzyme table, regulation stimulators vs inhibitors table |
| 3. Mechanism of Action | VDR-RXR step-by-step table, VDR tissue distribution table, Vitamin A-D interaction |
| 4. Calcium Homeostasis | Diagram showing PTH/Calcitriol/Calcitonin feedback loop, comparison table of all three hormones |
| 5. Deficiency | Causes table, Rickets vs Osteomalacia side-by-side comparison, lab findings table |
| 6. Toxicity & Clinical Pearls | RDA table, toxicity facts, 16 high-yield exam pearls |
| 7. Quick Reference | Complete 5-column pathway summary table, 14 must-remember facts |