Complete urine examination
complete urine examination routine urinalysis components physical chemical microscopic
"urinalysis" AND "diagnostic accuracy"
| Parameter | Normal | Significance of abnormality |
|---|---|---|
| Color | Pale yellow (urochrome pigment) | Concentration, foods, drugs, hematuria, bilirubinuria |
| Appearance/turbidity | Clear | Cloudiness from phosphate crystals (alkaline urine), pyuria, bacteria, or lipids |
| Odor | Faint aromatic | Strong odor may reflect concentration or infection |
| Volume | ~1-2 L/day | Oliguria/polyuria patterns |
Create a quick reference guide (PDF) for urinalysis interpretation
mkdir -p /tmp/workspace/urinalysis-guide/output && ls -la /tmp/workspace/
~/urinalysis-guide/build_pdf.py
#!/usr/bin/env python3
"""Quick Reference Guide: Urinalysis Interpretation (PDF)"""
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.lib.units import inch
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
PageBreak, HRFlowable, KeepTogether
)
from reportlab.platypus.flowables import Flowable
# ---------- Colors ----------
NAVY = colors.HexColor("#0B3D5C")
TEAL = colors.HexColor("#12768C")
LIGHT_BLUE = colors.HexColor("#EAF3F7")
LIGHT_GREY = colors.HexColor("#F4F5F6")
AMBER = colors.HexColor("#B8791A")
RED = colors.HexColor("#A63A34")
GREEN = colors.HexColor("#3B7A4E")
WHITE = colors.white
DARK_TEXT = colors.HexColor("#1C2B33")
# ---------- Styles ----------
styles = getSampleStyleSheet()
title_style = ParagraphStyle(
"TitleStyle", parent=styles["Title"], fontName="Helvetica-Bold",
fontSize=22, textColor=WHITE, alignment=TA_CENTER, spaceAfter=2
)
subtitle_style = ParagraphStyle(
"SubtitleStyle", parent=styles["Normal"], fontName="Helvetica",
fontSize=11, textColor=colors.HexColor("#CFE7EF"), alignment=TA_CENTER
)
section_style = ParagraphStyle(
"SectionStyle", parent=styles["Heading2"], fontName="Helvetica-Bold",
fontSize=13.5, textColor=WHITE, backColor=NAVY, spaceBefore=10, spaceAfter=6,
leftIndent=6, borderPadding=(4, 6, 4, 6)
)
subhead_style = ParagraphStyle(
"SubheadStyle", parent=styles["Heading3"], fontName="Helvetica-Bold",
fontSize=10.5, textColor=NAVY, spaceBefore=6, spaceAfter=3
)
body_style = ParagraphStyle(
"BodyStyle", parent=styles["Normal"], fontName="Helvetica",
fontSize=8.7, leading=11.5, textColor=DARK_TEXT
)
cell_style = ParagraphStyle(
"CellStyle", parent=styles["Normal"], fontName="Helvetica",
fontSize=8.3, leading=10.6, textColor=DARK_TEXT
)
cell_bold = ParagraphStyle(
"CellBoldStyle", parent=cell_style, fontName="Helvetica-Bold", textColor=NAVY
)
header_cell = ParagraphStyle(
"HeaderCell", parent=styles["Normal"], fontName="Helvetica-Bold",
fontSize=8.8, textColor=WHITE, alignment=TA_LEFT
)
footer_style = ParagraphStyle(
"FooterStyle", parent=styles["Normal"], fontName="Helvetica-Oblique",
fontSize=7.3, textColor=colors.HexColor("#6E6E6E")
)
pearl_style = ParagraphStyle(
"PearlStyle", parent=styles["Normal"], fontName="Helvetica",
fontSize=8.6, leading=11.5, textColor=DARK_TEXT, leftIndent=4
)
def P(text, style=cell_style):
return Paragraph(text, style)
def section_header(text):
return Table(
[[P(text, ParagraphStyle("s", parent=section_style, textColor=WHITE))]],
colWidths=[7.0 * inch],
style=TableStyle([
("BACKGROUND", (0, 0), (-1, -1), NAVY),
("LEFTPADDING", (0, 0), (-1, -1), 8),
("TOPPADDING", (0, 0), (-1, -1), 5),
("BOTTOMPADDING", (0, 0), (-1, -1), 5),
])
)
def make_table(header_row, rows, col_widths, header_bg=TEAL, zebra=True):
data = [[P(h, header_cell) for h in header_row]] + rows
tbl = Table(data, colWidths=col_widths, repeatRows=1)
style_cmds = [
("BACKGROUND", (0, 0), (-1, 0), header_bg),
("GRID", (0, 0), (-1, -1), 0.5, colors.HexColor("#C9D3D8")),
("VALIGN", (0, 0), (-1, -1), "TOP"),
("LEFTPADDING", (0, 0), (-1, -1), 5),
("RIGHTPADDING", (0, 0), (-1, -1), 5),
("TOPPADDING", (0, 0), (-1, -1), 4),
("BOTTOMPADDING", (0, 0), (-1, -1), 4),
]
if zebra:
for i in range(1, len(data)):
if i % 2 == 0:
style_cmds.append(("BACKGROUND", (0, i), (-1, i), LIGHT_GREY))
tbl.setStyle(TableStyle(style_cmds))
return tbl
# ---------- Header/Footer ----------
def header_footer(canvas, doc):
canvas.saveState()
# Top banner only on page 1 handled separately; footer on every page
canvas.setFont("Helvetica", 7.5)
canvas.setFillColor(colors.HexColor("#6E6E6E"))
canvas.drawString(0.6 * inch, 0.4 * inch,
"Urinalysis Quick Reference Guide - Educational summary. Always correlate with clinical context and lab reference ranges.")
canvas.drawRightString(letter[0] - 0.6 * inch, 0.4 * inch, f"Page {doc.page}")
canvas.setStrokeColor(colors.HexColor("#C9D3D8"))
canvas.line(0.6 * inch, 0.55 * inch, letter[0] - 0.6 * inch, 0.55 * inch)
canvas.restoreState()
# ---------- Build document ----------
doc = SimpleDocTemplate(
"/tmp/workspace/urinalysis-guide/output/Urinalysis_Quick_Reference_Guide.pdf",
pagesize=letter,
topMargin=0.5 * inch, bottomMargin=0.7 * inch,
leftMargin=0.6 * inch, rightMargin=0.6 * inch,
title="Urinalysis Quick Reference Guide"
)
elements = []
# ---- Title banner ----
title_table = Table(
[[Paragraph("URINALYSIS INTERPRETATION", title_style)],
[Paragraph("Quick Reference Guide | Physical - Chemical - Microscopic Examination", subtitle_style)]],
colWidths=[7.0 * inch]
)
title_table.setStyle(TableStyle([
("BACKGROUND", (0, 0), (-1, -1), NAVY),
("TOPPADDING", (0, 0), (0, 0), 12),
("BOTTOMPADDING", (0, 0), (0, 0), 2),
("TOPPADDING", (0, 1), (0, 1), 2),
("BOTTOMPADDING", (0, 1), (0, 1), 12),
]))
elements.append(title_table)
elements.append(Spacer(1, 10))
# ---- Intro ----
elements.append(Paragraph(
"A complete urine examination (CUE / routine urinalysis) evaluates urine through three components: "
"<b>physical (gross)</b>, <b>chemical (dipstick)</b>, and <b>microscopic</b> examination. "
"Use a fresh midstream/clean-catch sample examined within 1-2 hours of collection (refrigerate at 5°C if delayed) "
"to avoid false results from bacterial overgrowth, pH shift, and cast/cell degradation.",
body_style
))
elements.append(Spacer(1, 8))
# =========================================================
# SECTION 1: PHYSICAL EXAMINATION
# =========================================================
elements.append(section_header("1. PHYSICAL (GROSS) EXAMINATION"))
elements.append(Spacer(1, 4))
phys_rows = [
[P("Color", cell_bold), P("Pale yellow (urochrome pigment)"),
P("Dark/amber: concentrated urine, bilirubin. Red/pink: hematuria, hemoglobinuria, myoglobinuria, beets, rifampin. "
"Orange: phenazopyridine (also invalidates dipstick colors). Brown/cola: myoglobinuria, bile pigments. Blue-green: Pseudomonas, some drugs.")],
[P("Appearance / Turbidity", cell_bold), P("Clear"),
P("Cloudy: phosphate crystals (alkaline urine, often benign), pyuria/infection, lipiduria, chyluria.")],
[P("Odor", cell_bold), P("Faint aromatic"),
P("Strong ammoniacal: infection/concentration. Sweet/fruity: ketosis (DKA). Foul: UTI, fistula.")],
[P("Volume", cell_bold), P("~1000-2000 mL/24h"),
P("Oliguria (<400 mL/day): dehydration, AKI, obstruction. Polyuria (>3 L/day): diabetes mellitus/insipidus, diuretics, excess intake.")],
]
elements.append(make_table(
["Parameter", "Normal", "Abnormal / Clinical Significance"],
phys_rows,
col_widths=[1.15 * inch, 1.35 * inch, 4.5 * inch],
header_bg=NAVY
))
elements.append(Spacer(1, 10))
# =========================================================
# SECTION 2: CHEMICAL (DIPSTICK) EXAMINATION
# =========================================================
elements.append(section_header("2. CHEMICAL (DIPSTICK) EXAMINATION"))
elements.append(Spacer(1, 4))
chem_rows = [
[P("Specific Gravity", cell_bold), P("1.001-1.035"),
P("<1.008 dilute: diabetes insipidus, diuretics, overhydration. >1.020 concentrated: dehydration, glycosuria, SIADH. "
"Fixed ~1.010 (isosthenuria): renal insufficiency. Measures cations only - not true osmolality.")],
[P("pH", cell_bold), P("4.5-8.0 (avg 5.5-6.5)"),
P("Persistently alkaline: urease-producing organisms (Proteus), RTA type 1, vegetarian diet, stale sample. "
"Acidic: uric acid/cystine stone risk, metabolic acidosis, high protein diet.")],
[P("Protein", cell_bold), P("Negative / trace"),
P("Glomerular disease (nephrotic/nephritic), UTI, fever, exercise, orthostatic proteinuria, multiple myeloma (dipstick misses light chains - "
"use urine protein electrophoresis).")],
[P("Glucose", cell_bold), P("Negative"),
P("Appears above renal threshold (~180 mg/dL): diabetes mellitus, pregnancy, Fanconi syndrome. Sensitivity for diabetes screening is limited (~10-50%).")],
[P("Ketones", cell_bold), P("Negative"),
P("Diabetic ketoacidosis, starvation, prolonged vomiting, high-fat/low-carb diet, alcoholic ketoacidosis.")],
[P("Blood (Heme)", cell_bold), P("Negative"),
P("Hematuria (glomerular or non-glomerular), hemoglobinuria (hemolysis), myoglobinuria (rhabdomyolysis). "
"False positive: oxidizing contaminants, myoglobin. Not affected by ascorbic acid (unlike glucose/bilirubin).")],
[P("Bilirubin", cell_bold), P("Negative"),
P("Conjugated hyperbilirubinemia - hepatobiliary obstruction, hepatocellular disease. Never present in pure hemolysis (unconjugated).")],
[P("Urobilinogen", cell_bold), P("Normal trace (0.2-1.0 mg/dL)"),
P("Increased: hemolysis, hepatocellular disease. Absent: complete biliary obstruction.")],
[P("Nitrite", cell_bold), P("Negative"),
P("Positive suggests Gram-negative, nitrate-reducing bacteria (e.g., E. coli) - supports UTI. False negative with non-nitrate-reducers "
"(e.g., Enterococcus, Staph saprophyticus) or short bladder incubation time.")],
[P("Leukocyte Esterase", cell_bold), P("Negative"),
P("Enzyme released by neutrophils - supports pyuria/UTI. Can be negative despite pyuria if sample is dilute or delayed.")],
]
elements.append(make_table(
["Test", "Normal", "Abnormal / Clinical Significance"],
chem_rows,
col_widths=[1.15 * inch, 1.35 * inch, 4.5 * inch],
header_bg=TEAL
))
elements.append(Spacer(1, 6))
elements.append(Paragraph(
"<b>Technique pearls:</b> Dip completely into fresh, uncentrifuged urine; hold horizontally (not vertical - causes reagent pad "
"cross-contamination). Read at the specified time against the color chart. Outdated/exposed strips give unreliable results.",
pearl_style
))
elements.append(PageBreak())
# =========================================================
# SECTION 3: MICROSCOPIC EXAMINATION
# =========================================================
elements.append(section_header("3. MICROSCOPIC EXAMINATION (URINE SEDIMENT)"))
elements.append(Spacer(1, 4))
elements.append(Paragraph(
"Centrifuge 10-15 mL fresh urine at 1500-3000 rpm for 5 minutes; decant supernatant; resuspend sediment; "
"examine a drop under coverslip at low- (LPF) and high-power field (HPF).",
body_style
))
elements.append(Spacer(1, 6))
elements.append(Paragraph("Cells", subhead_style))
cell_rows = [
[P("RBCs", cell_bold), P("≤2-3 /HPF"),
P("Dysmorphic RBCs / RBC casts → glomerular bleeding (e.g., IgA nephropathy, GN). "
"Isomorphic RBCs → lower urinary tract source (stones, tumor, infection, trauma).")],
[P("WBCs (pus cells)", cell_bold), P("≤5 /HPF"),
P("Pyuria → UTI, urethritis, pyelonephritis, interstitial nephritis. Sterile pyuria: TB, interstitial nephritis, partially treated UTI.")],
[P("Epithelial cells", cell_bold), P("Few squamous cells"),
P("Squamous: contamination (esp. female sample). Transitional: normal turnover or urothelial irritation. "
"Renal tubular cells: acute tubular injury/necrosis.")],
]
elements.append(make_table(
["Element", "Normal", "Significance"], cell_rows,
col_widths=[1.15 * inch, 1.15 * inch, 4.7 * inch], header_bg=NAVY
))
elements.append(Spacer(1, 8))
elements.append(Paragraph("Casts", subhead_style))
cast_rows = [
[P("Hyaline", cell_bold), P("Normal finding; increases with exercise, dehydration, fever")],
[P("RBC casts", cell_bold), P("Glomerulonephritis (diagnostic of glomerular hematuria)")],
[P("WBC casts", cell_bold), P("Pyelonephritis, interstitial nephritis")],
[P("Granular casts", cell_bold), P("Acute tubular necrosis, chronic renal disease, strenuous exercise")],
[P("Waxy casts", cell_bold), P("Chronic kidney disease / advanced renal failure (stasis in tubules)")],
[P("Fatty casts", cell_bold), P("Nephrotic syndrome (associated with lipiduria, \"Maltese cross\" under polarized light)")],
]
elements.append(make_table(
["Cast Type", "Clinical Association"], cast_rows,
col_widths=[1.6 * inch, 5.4 * inch], header_bg=TEAL
))
elements.append(Spacer(1, 8))
elements.append(Paragraph("Crystals, Organisms & Other", subhead_style))
misc_rows = [
[P("Calcium oxalate", cell_bold), P("Common, often benign; envelope/dumbbell shape. Excess with ethylene glycol toxicity, hyperoxaluria.")],
[P("Uric acid", cell_bold), P("Acidic urine; associated with gout, tumor lysis syndrome, uric acid stones.")],
[P("Triple phosphate (struvite)", cell_bold), P("Alkaline urine; coffin-lid shape; associated with urease-producing UTI and struvite stones.")],
[P("Cystine", cell_bold), P("Hexagonal plates; pathognomonic for cystinuria.")],
[P("Bacteria / Yeast", cell_bold), P("Significant if seen with pyuria in a properly collected fresh sample; yeast common in diabetics, immunosuppressed, vaginal contamination.")],
[P("Mucus threads", cell_bold), P("Usually benign, more common in female samples.")],
]
elements.append(make_table(
["Finding", "Clinical Association"], misc_rows,
col_widths=[1.6 * inch, 5.4 * inch], header_bg=NAVY
))
elements.append(Spacer(1, 10))
# =========================================================
# SECTION 4: INTERPRETATION PATTERNS
# =========================================================
elements.append(section_header("4. QUICK INTERPRETATION PATTERNS"))
elements.append(Spacer(1, 4))
pattern_rows = [
[P("UTI / Cystitis", cell_bold), P("Positive leukocyte esterase + nitrite, pyuria, bacteriuria ± hematuria; usually normal casts.")],
[P("Pyelonephritis", cell_bold), P("Pyuria with WBC casts, positive nitrite/leukocyte esterase, may have mild proteinuria.")],
[P("Glomerulonephritis", cell_bold), P("Dysmorphic RBCs, RBC casts, proteinuria (subnephrotic or nephrotic range).")],
[P("Nephrotic syndrome", cell_bold), P("Heavy proteinuria (3-4+), fatty casts, lipiduria; relatively few cells.")],
[P("Acute tubular necrosis", cell_bold), P("Renal tubular epithelial cells, granular (\"muddy brown\") casts, mild proteinuria.")],
[P("Diabetes mellitus", cell_bold), P("Glycosuria ± ketonuria; microalbuminuria in early diabetic nephropathy.")],
[P("Dehydration / Pre-renal AKI", cell_bold), P("High specific gravity, concentrated color, hyaline casts, normal sediment.")],
[P("Nephrolithiasis", cell_bold), P("Hematuria (often isomorphic), relevant crystals (calcium oxalate, uric acid, struvite, cystine).")],
]
elements.append(make_table(
["Clinical Picture", "Typical Urinalysis Pattern"], pattern_rows,
col_widths=[1.7 * inch, 5.3 * inch], header_bg=TEAL
))
elements.append(Spacer(1, 10))
# =========================================================
# SECTION 5: PITFALLS / FALSE RESULTS
# =========================================================
elements.append(section_header("5. COMMON PITFALLS & FALSE RESULTS"))
elements.append(Spacer(1, 4))
pitfalls = [
"High ascorbic acid (vitamin C): false-negative glucose and bilirubin (does not affect blood detection).",
"Highly alkaline / buffered urine: falsely low specific gravity; false-negative protein.",
"Phenazopyridine (Pyridium): orange discoloration invalidates most dipstick color reactions.",
"Delayed/room-temperature sample: bacterial overgrowth, pH drift, lysis of RBCs/casts, crystal formation (artifactual).",
"Dilute urine (<308 mOsm): RBC lysis may cause underestimation of hematuria.",
"Non-nitrate-reducing organisms (Enterococcus, S. saprophyticus, Pseudomonas): false-negative nitrite despite true UTI.",
"Vaginal/skin contamination: squamous epithelial cells, mixed flora, false pyuria in poorly collected female samples.",
]
for p in pitfalls:
elements.append(Paragraph("• " + p, pearl_style))
elements.append(Spacer(1, 2))
elements.append(Spacer(1, 10))
elements.append(HRFlowable(width="100%", thickness=0.7, color=colors.HexColor("#C9D3D8")))
elements.append(Spacer(1, 4))
elements.append(Paragraph(
"<b>Sources:</b> Campbell-Walsh Wein Urology (3-Vol Set); Tietz Textbook of Laboratory Medicine, 7th Ed.; "
"Park's Textbook of Preventive and Social Medicine; Roberts and Hedges' Clinical Procedures in Emergency Medicine. "
"This guide is an educational summary, not a substitute for full clinical and laboratory correlation.",
footer_style
))
doc.build(elements, onFirstPage=header_footer, onLaterPages=header_footer)
print("PDF created successfully.")
cd /tmp/workspace/urinalysis-guide && python3 build_pdf.py
cd /tmp/workspace/urinalysis-guide && python3 -c " import pdfplumber with pdfplumber.open('output/Urinalysis_Quick_Reference_Guide.pdf') as pdf: print('pages:', len(pdf.pages)) for i,p in enumerate(pdf.pages): print('--- page', i+1, 'size', p.width, p.height) " && ls -la output/
Urinalysis Quick Reference Guide
PDF Document · PDF