Differences between... Neuroblastoma and neuroblastoma radiology

Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Loading Image
Reading File
Loading Image
I now have all I need to write a thorough, well-organized answer. Here is the full comparison:

Neuroblastoma: Pathology vs. Radiology

The question asks about the differences between neuroblastoma as a disease entity (its biology, pathology, clinical behavior) and neuroblastoma radiology (its imaging findings across modalities). These are two different lenses on the same tumor - here is a structured breakdown of each.

1. THE DISEASE - What is Neuroblastoma?

Origin & Epidemiology

Neuroblastoma (NB) arises from primordial neural crest cells that populate the sympathetic ganglia and adrenal medulla. It is the second most common solid malignancy of childhood (after brain tumors), accounting for 7-10% of all pediatric neoplasms and up to 50% of malignancies in infancy. Median age at diagnosis is 2 years; 90% occur before age 5. Most cases are sporadic; 1-2% are familial (autosomal dominant, linked to germline ALK mutations).
  • Robbins & Kumar Basic Pathology, p. 144

Primary Sites

SiteFrequency
Adrenal glands40-48%
Extra-adrenal retroperitoneum / paravertebral25%
Posterior mediastinum15-16%
Neck3%
Pelvis3%
About 50% of patients have metastatic disease at diagnosis, most commonly to skeleton, bone marrow, lymph nodes, and liver.
  • Grainger & Allison's Diagnostic Radiology, p. 1961

Gross & Histological Pathology

Neuroblastoma vs Ganglioneuroma histology
(A) Neuroblastoma: small primitive cells with dark nuclei, scant cytoplasm, Homer-Wright pseudorosettes (tumor cells concentrically arranged around neuropil). (B) Ganglioneuroma (mature end of spectrum): large ganglion cells with vesicular nuclei and abundant cytoplasm (arrow), with Schwann cells in the background stroma.
  • Robbins & Kumar Basic Pathology, Fig. 4.38
Key histological features:
  • Sheets of small round blue cells, dark nuclei, scant cytoplasm
  • Homer-Wright pseudorosettes - tumor cells arranged around central neuropil (no true lumen)
  • Faint eosinophilic neuropil in background
  • Immunohistochemistry positive for neuron-specific enolase (NSE)
  • EM shows membrane-bound catecholamine-containing secretory granules
  • Maturation spectrum: Neuroblastoma → Ganglioneuroblastoma → Ganglioneuroma (Schwannian stroma + gangliocytic differentiation = better prognosis)

Molecular Biology & Prognostic Factors

FactorDetail
MYCN amplificationPresent in 25-30%; most important genetic abnormality; automatically renders tumor "high risk"; EFS 50% vs 90% without amplification
ALK mutationsSomatic gain-of-function in 8-10% of sporadic cases; marker of adverse prognosis
DNA ploidyHyperdiploid (whole chromosome gains) = better prognosis than diploid
Age< 18 months = far better outlook; most are stage 1, 2, or 4S
1p and 11q deletionsAssociated with adverse outcome
17q gainAdverse outcome

Staging - International Neuroblastoma Staging System (INSS)

  • Stage 1-3: Local/regional disease
  • Stage 4: Distant metastases
  • Stage 4S (Special): Localized tumor + spread limited to liver, skin, and bone marrow (without bone involvement) - excellent prognosis and often undergoes spontaneous regression in infants. The biologic basis is not fully clear.

Clinical Features

  • Young children: protuberant abdomen, fever, weight loss
  • Older children: hepatomegaly, ascites, bone pain from metastases
  • Horner syndrome with cervical/thoracic NB (stellate ganglion involvement)
  • Proptosis from orbital metastases ("raccoon eyes")
  • Catecholamine excess (~90% of tumors produce catecholamines): elevated urinary VMA (vanillylmandelic acid) and HVA (homovanillic acid) - key diagnostic biochemical finding; however hypertension is less frequent than in pheochromocytoma
  • VIP production: intractable watery diarrhea
  • MEI (myoclonic encephalopathy of infancy): a paraneoplastic syndrome associated with NB
  • Neonates: deep blue subcutaneous metastases ("blueberry muffin baby")
  • Dumb-bell syndrome: extradural extension via foramina (especially thoracic NB) causing spinal cord compression

2. THE RADIOLOGY - Imaging of Neuroblastoma

Radiology is a separate domain from the pathology - it defines how the tumor appears on each imaging modality and guides staging and surgical planning.

Plain Radiograph

  • Calcified retroperitoneal or thoracic mass
  • Erosion of vertebral pedicles suggests intraspinal extension
  • Skeletal metastases: ill-defined bone destruction, lytic/moth-eaten/permeative areas interspersed with sclerotic trabeculae
  • Periosteal new bone formation parallel to shaft (malignant but non-specific)
  • Most common skeletal sites: skull and metaphyses of long bones (humerus, femur)
  • Grainger & Allison's, p. 1962

Ultrasound (US)

The initial diagnostic modality for abdominal NB and the primary tool for fetal/neonatal masses.
Neonatal neuroblastoma - ultrasound and CT evolution
Spontaneous regression of neonatal adrenal NB: (A) initial cystic mass, (B) becoming partially solid at 6 weeks, (C) much smaller and hyperechoic with calcifications at 31 weeks, (D) coronal CT showing near-complete regression at 45 weeks.
  • Grainger & Allison's Diagnostic Radiology, Fig. 75.22
Key US features:
FeatureDescription
Retroperitoneal locationAnterior displacement of aorta and IVC (confirms retroperitoneal origin, distinguishing from renal origin in Wilms)
EchogenicityVariable; hyperechoic foci = calcifications
VascularisationRich on Colour Doppler (vs. absent in adrenal haemorrhage)
Hypoechoic areasHaemorrhage / necrosis
NeonatalCan be cystic (55%), solid (17.5%), or heterogeneous (27.5%)
Neonatal differential on US: NB vs adrenal haemorrhage vs congenital adrenal hyperplasia vs subdiaphragmatic extralobar pulmonary sequestration. A mass increasing in size or persisting beyond 48 weeks favors NB; a mass regressing, becoming heterogeneous, and showing late calcifications favors adrenal haemorrhage.

CT Scan

The main modality for staging the primary tumor (chest, abdomen, pelvis with IV contrast).
CT FeatureDescription
AppearanceLarge, heterogeneous mass
CalcificationPresent in up to 85% of cases (very characteristic)
Low-attenuation areasNecrosis or haemorrhage
EnhancementMild, heterogeneous
Vascular encasementNB often encases rather than displaces vessels (key difference from Wilms' tumor)
Spinal extensionSuspected but not fully evaluable - MRI required for dumb-bell tumors
Skull metastasesSpheno-orbital region; permeative bone destruction with spiculated changes, scalp soft-tissue extension

MRI

Preferred for paraspinal tumors and intraspinal extension.
MRI FeatureDescription
T1 signalProlonged (low); high T1 = haemorrhage
T2 signalProlonged (high)
Gadolinium enhancementHeterogeneous
Bone marrow involvementLow T1, high T2 signal in marrow
Dumb-bell tumorsBest modality for intraspinal/extradural extension

Radionuclide Imaging - ¹²³I-mIBG Scintigraphy

This is the most specific nuclear medicine tool for NB.
  • mIBG (metaiodobenzylguanidine) is an analogue of noradrenaline, specifically taken up and stored in sympathetic-derived tumors
  • Used for: characterization of mass, localization (especially in MEI where primary may be occult), evaluation of metastatic disease, and follow-up
  • ~20% of primary lesions do not take up mIBG - these cases require alternative nuclear medicine studies
  • ⁹⁹ᵐTc-MDP bone scintigraphy is also used to evaluate skeletal metastases
  • Grainger & Allison's, p. 1964

3. KEY DIFFERENCES SUMMARY: Pathology vs. Radiology

DomainNeuroblastoma (Pathology/Disease)Neuroblastoma Radiology
DefinesWhat the tumor IS (biology, molecular, histology)What the tumor LOOKS LIKE on imaging
ToolsHistology, IHC, molecular genetics, biochemistryX-ray, US, CT, MRI, MIBG
CalcificationNot a primary pathologic featurePresent in up to 85% on CT - hallmark
Vascular relationshipInvasion/encasement histologicallyEncasement of aorta/IVC/renal vessels on CT/MRI (vs Wilms' which displaces)
MaturationSpectrum: NB → GNB → GN (Schwann cells, ganglion cells = better prognosis)All three may look similar radiologically; cannot reliably distinguish by imaging alone
Staging basisINSS stages 1-4, 4S based on surgical/pathological findingsImage-Defined Risk Factors (IDRFs) - SIOPEN/INRG system defines surgical risk from imaging pre-op
RegressionSpontaneous regression is a known biological behavior (especially < 18 months, 4S)Serial US/CT shows shrinkage; key to follow neonatal masses before intervening
Diagnosis confirmationPositive bone marrow + elevated urinary catecholamine metabolites sufficientNo single imaging feature is pathognomonic
Spinal cord riskExtradural extension histologicallyMRI mandatory for paraspinal masses to evaluate cord compression
Bone marrow involvementHistological infiltration by neuroblastsAbnormal T1/T2 signal on MRI; bone scan or mIBG for scintigraphic detection

Sources:

Differences between... Neuroblastoma and nephroblastoma radiology

Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Loading Image
Loading Image
I now have comprehensive, well-sourced data to write the full comparison. Here is the detailed answer:

Neuroblastoma vs. Nephroblastoma (Wilms Tumor) - Radiology

These are the two most common abdominal malignancies of childhood and their differentiation on imaging is one of the classic pediatric radiology challenges. The key distinction starts with origin: neuroblastoma arises from the adrenal gland/sympathetic chain (extra-renal), while nephroblastoma arises within the kidney itself.

Background: The Two Tumors at a Glance

FeatureNeuroblastoma (NB)Nephroblastoma / Wilms Tumor (WT)
OriginNeural crest cells - adrenal medulla, sympathetic gangliaMetanephric blastema - kidney
Peak age2 years (90% < 5 yrs)3 years (peak); 2-5 yrs
GenderSlight male predominanceEqual (M = F)
BilateralRare (< 5%)~10% (two-thirds synchronous)
Biochemical markerUrine catecholamines (VMA, HVA) elevated in ~90%None specific
Associated syndromesFamilial ALK mutationsWAGR, Denys-Drash, Beckwith-Wiedemann
Metastases at diagnosis~50%~10% (stage IV)

Radiological Differences by Modality

1. Plain Radiograph

FeatureNeuroblastomaNephroblastoma
CalcificationCommon - stippled, irregular, amorphous calcifications visible in ~50% on plain filmRare - calcification unusual (<10%)
Mass locationRetroperitoneal, can be thoracic, cervicalAlways intrarenal - right upper quadrant or left upper quadrant
Vertebral pedicle erosionCan occur (dumb-bell extension into spinal canal)Not a feature
Skeletal metastasesCommon - lytic/moth-eaten areas with periosteal new bone formation in long bones and skullLess common; when present - lytic lesions

2. Ultrasound (US) - First-Line in Both

Neuroblastoma on US:
  • Retroperitoneal mass, typically suprarenal or paraaortic
  • Variable echogenicity; hyperechoic foci = calcifications (very common)
  • Hypoechoic areas from haemorrhage/necrosis
  • Rich vascularisation on Colour Doppler
  • Anterior displacement of the aorta and IVC - confirms retroperitoneal origin
  • Does NOT arise from kidney - kidney is displaced but separate, with its own capsule visible
  • In neonates: can be cystic (55%), solid (17.5%), or heterogeneous (27.5%)
Nephroblastoma on US:
Wilms Tumor - Ultrasound
Large heterogeneous mass arising from the upper right kidney with inferior displacement of the lower renal pole - the key US finding that localizes the tumor to the kidney.
  • Grainger & Allison's Diagnostic Radiology, Fig. 72.50
  • Intrarenal - the mass arises FROM the kidney
  • Large, with mixture of solid hyperechoic and cystic areas; cystic components often predominate
  • Normal native renal tissue may be visible, stretched at the periphery ("claw sign")
  • Renal vein and IVC must be assessed for tumour thrombus (can extend to right atrium) - a critical US finding unique to Wilms
  • Movement of the mass separate from the liver suggests no direct invasion (important surgical planning)
  • Calcification is NOT a typical finding
Key US differential point: If you can identify normal kidney tissue separate from the mass - it's neuroblastoma displacing the kidney. If the mass appears to arise FROM within the kidney - it's nephroblastoma.

3. CT Scan

CT FeatureNeuroblastomaNephroblastoma
OriginExtra-renal (adrenal/retroperitoneal) - kidney displaced, beak-sign may show adjacent kidneyIntrarenal - kidney origin; "claw" of residual renal parenchyma wraps around tumor
CalcificationPresent in up to 85% - highly characteristicUnusual (< 10%) - when present, may suggest prior hemorrhage
Vascular relationshipEncases vessels (aorta, IVC, celiac, mesenteric) without displacing them - "vessel encasement" signDisplaces vessels; IVC/renal vein invaded by tumor thrombus (not encased)
Tumour thrombusRareClassic feature - IVC thrombus in up to 10%; can extend to right atrium
EnhancementMild, heterogeneous (areas of necrosis/hemorrhage/cystic change)Heterogeneous; enhances less than normal renal parenchyma
CrossmidlineFrequently crosses midline (especially large retroperitoneal masses)Less commonly crosses midline
Contralateral kidneyAssess for bilateral involvement (rare)Must assess - 10% bilateral; nephroblastomatosis (nephrogenic rests) in contralateral kidney
Lymph nodesParaaortic, celiac, mesentericPara-aortic, regional; peritoneal invasion in stage III
Skeletal metastasesCommon - skull (spheno-orbital), long bone metaphysesStage IV (10%) - lungs first, then liver
Pulmonary metastasesLess commonPresent in stage IV; chest CT value controversial vs. plain CXR
Spinal canal extensionCharacteristic - dumb-bell through foramina; CT can suggest but MRI required to evaluateNot a feature

4. MRI

MRI FeatureNeuroblastomaNephroblastoma
T1 signalProlonged (low); high T1 = hemorrhageHypointense on T1 (similar)
T2 signalProlonged (high)Variably hyperintense on T2
GadoliniumHeterogeneous enhancement; required for spinal canal and vessel assessmentHeterogeneous, often poor enhancement; required for contralateral kidney (nephroblastomatosis), biopsy guidance
Bone marrowAbnormal signal (low T1, high T2) in metastatic diseaseNot a primary concern
Spinal canalMRI is mandatory for any paraspinal mass - evaluate extradural/cord extensionNot indicated for spinal canal
Gold standard for bilateralNot applicableMRI is gold standard for bilateral disease assessment (Fig. 72.51)
Bilateral Wilms Tumor MRI
Bilateral Wilms tumor on coronal MRI - large right-sided mass and a smaller left-sided mass that could easily be overlooked. MRI is now the gold standard for bilateral Wilms assessment.
  • Grainger & Allison's Diagnostic Radiology, Fig. 72.51

5. Nuclear Medicine

ModalityNeuroblastomaNephroblastoma
¹²³I-mIBG scintigraphyEssential - mIBG (noradrenaline analogue) is specifically taken up by sympathetic-derived tumors; used for primary characterization, metastasis mapping, and follow-up. ~20% of NB are mIBG-negativeNot used - no catecholamine uptake
⁹⁹ᵐTc-MDP bone scanUsed to detect skeletal metastases (alongside mIBG)Less commonly used
PET/CTUsed in mIBG-negative casesNot standard
Chest CT vs CXRFor pulmonary metastases stagingStandard staging uses CXR; chest CT controversial as small CT-only metastases have uncertain prognostic significance
mIBG scintigraphy is the single biggest nuclear medicine differentiator - it is pathognomonic for neuroblastoma (sympathetic origin) and has no role in nephroblastoma.

The Single Most Important Differentiating Imaging Sign

CriterionNeuroblastomaNephroblastoma
Relationship to kidneyDisplaces the kidney - kidney is separate, intact, with its own capsuleArises from the kidney - residual renal tissue forms a "claw" or "beak" around the mass
Calcification on CTVery common (85%), coarse/amorphousRare (<10%)
Vessel relationshipEncases aorta/IVC without thrombusIVC tumor thrombus (displaces, not encases)
Crossing midlineCommonLess common
mIBG uptakeYes (80%)No
CatecholaminesUrine VMA/HVA elevatedNormal

Staging Systems (Radiologically Relevant)

Neuroblastoma uses the International Neuroblastoma Risk Group (INRG) system based on Image-Defined Risk Factors (IDRFs) - pre-operative imaging defines the surgical risk by assessing whether the tumor encases major vessels, invades adjacent structures, or extends into the spinal canal.
Nephroblastoma uses the NWTSG staging (North American) or SIOP (European) - both are primarily surgical/pathological staging systems, though imaging (CT/MRI) is required to identify lymphadenopathy, peritoneal deposits, liver lesions, and contralateral kidney involvement pre-operatively.

Sources:

Make a quick reference PDF on pediatric abdominal mass differential diagnosis

Reading File
Running Command

mkdir -p /home/daytona/workspace/peds-abdominal-mass && ls /home/daytona/workspa…

Writing File

~/peds-abdominal-mass/generate_pdf.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_RIGHT
from reportlab.platypus import PageBreak

OUTPUT = "/home/daytona/workspace/peds-abdominal-mass/Pediatric_Abdominal_Mass_DDx.pdf"

# ── Colours ──────────────────────────────────────────────────────────────────
NAVY      = colors.HexColor("#1a3a5c")
TEAL      = colors.HexColor("#1e7f8e")
AMBER     = colors.HexColor("#e67e22")
RED       = colors.HexColor("#c0392b")
GREEN     = colors.HexColor("#27ae60")
PURPLE    = colors.HexColor("#8e44ad")
LTGRAY    = colors.HexColor("#f5f6fa")
MIDGRAY   = colors.HexColor("#dfe3e8")
DARKGRAY  = colors.HexColor("#4a4a5a")
WHITE     = colors.white
BLACK     = colors.black

# ── Styles ────────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

def S(name, **kw):
    """Create a named ParagraphStyle extending 'Normal'."""
    return ParagraphStyle(name, parent=styles["Normal"], **kw)

Title      = S("MyTitle",    fontSize=22, textColor=WHITE,    fontName="Helvetica-Bold",
               alignment=TA_CENTER, leading=28, spaceAfter=4)
Subtitle   = S("MySub",      fontSize=11, textColor=WHITE,    fontName="Helvetica",
               alignment=TA_CENTER, leading=16)
SectionH   = S("SH",         fontSize=12, textColor=WHITE,    fontName="Helvetica-Bold",
               alignment=TA_LEFT,   leading=16, leftIndent=6)
Body       = S("Body",       fontSize=8.5, textColor=DARKGRAY, fontName="Helvetica",
               leading=12, spaceAfter=2)
Bold       = S("Bold",       fontSize=8.5, textColor=BLACK,    fontName="Helvetica-Bold",
               leading=12)
SmallBold  = S("SmallBold",  fontSize=7.5, textColor=DARKGRAY, fontName="Helvetica-Bold",
               leading=11)
Small      = S("Small",      fontSize=7.5, textColor=DARKGRAY, fontName="Helvetica",
               leading=11)
TblHdr     = S("TblHdr",     fontSize=8,   textColor=WHITE,    fontName="Helvetica-Bold",
               alignment=TA_CENTER, leading=11)
TblCell    = S("TblCell",    fontSize=7.5, textColor=DARKGRAY, fontName="Helvetica",
               leading=11, leftIndent=3)
TblCellB   = S("TblCellB",   fontSize=7.5, textColor=BLACK,    fontName="Helvetica-Bold",
               leading=11, leftIndent=3)
FooterS    = S("Footer",     fontSize=7,   textColor=DARKGRAY, fontName="Helvetica-Oblique",
               alignment=TA_CENTER)
RedAlert   = S("RedAlert",   fontSize=8,   textColor=RED,      fontName="Helvetica-Bold",
               leading=12)
GreenText  = S("GreenText",  fontSize=8,   textColor=GREEN,    fontName="Helvetica-Bold",
               leading=12)

# ── Page canvas (header/footer) ───────────────────────────────────────────────
PAGE_W, PAGE_H = A4
MARGIN = 1.5*cm

def on_page(canvas, doc):
    canvas.saveState()
    # top stripe
    canvas.setFillColor(NAVY)
    canvas.rect(0, PAGE_H - 1.2*cm, PAGE_W, 1.2*cm, fill=1, stroke=0)
    canvas.setFillColor(WHITE)
    canvas.setFont("Helvetica-Bold", 8)
    canvas.drawString(MARGIN, PAGE_H - 0.82*cm,
                      "PEDIATRIC ABDOMINAL MASS — QUICK REFERENCE")
    canvas.setFont("Helvetica", 8)
    canvas.drawRightString(PAGE_W - MARGIN, PAGE_H - 0.82*cm,
                           f"Page {doc.page}")
    # bottom stripe
    canvas.setFillColor(MIDGRAY)
    canvas.rect(0, 0, PAGE_W, 0.9*cm, fill=1, stroke=0)
    canvas.setFillColor(DARKGRAY)
    canvas.setFont("Helvetica-Oblique", 6.5)
    canvas.drawCentredString(PAGE_W/2, 0.32*cm,
        "For educational use only. Clinical decisions require full patient assessment.")
    canvas.restoreState()

def on_first_page(canvas, doc):
    on_page(canvas, doc)

# ── Helpers ───────────────────────────────────────────────────────────────────
def section_banner(text, color=TEAL):
    """Coloured banner that acts as a section header."""
    data = [[Paragraph(text, SectionH)]]
    t = Table(data, colWidths=[PAGE_W - 2*MARGIN])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), color),
        ("TOPPADDING",    (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING",   (0,0), (-1,-1), 8),
        ("RIGHTPADDING",  (0,0), (-1,-1), 8),
        ("ROUNDEDCORNERS", [4]),
    ]))
    return t

def colored_table(headers, rows, col_widths, hdr_color=NAVY, alt_color=LTGRAY):
    """Generic coloured table."""
    hdr_row = [Paragraph(h, TblHdr) for h in headers]
    data = [hdr_row]
    for i, row in enumerate(rows):
        data.append([Paragraph(str(c), TblCell) for c in row])
    t = Table(data, colWidths=col_widths, repeatRows=1)
    style = [
        ("BACKGROUND",    (0,0),  (-1,0),  hdr_color),
        ("ROWBACKGROUNDS",(0,1),  (-1,-1), [WHITE, alt_color]),
        ("GRID",          (0,0),  (-1,-1), 0.4, MIDGRAY),
        ("TOPPADDING",    (0,0),  (-1,-1), 4),
        ("BOTTOMPADDING", (0,0),  (-1,-1), 4),
        ("LEFTPADDING",   (0,0),  (-1,-1), 4),
        ("RIGHTPADDING",  (0,0),  (-1,-1), 4),
        ("VALIGN",        (0,0),  (-1,-1), "TOP"),
    ]
    t.setStyle(TableStyle(style))
    return t

def mini_box(title, lines, bg=LTGRAY, title_color=NAVY):
    """Small info box with a title bar."""
    content = [[Paragraph(title, ParagraphStyle("BT", parent=styles["Normal"],
                fontSize=8, textColor=WHITE, fontName="Helvetica-Bold", leading=11))]]
    body_rows = [[Paragraph(l, Small)] for l in lines]
    t_title = Table(content, colWidths=[PAGE_W - 2*MARGIN])
    t_title.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), title_color),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ]))
    t_body = Table(body_rows, colWidths=[PAGE_W - 2*MARGIN])
    t_body.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("TOPPADDING",    (0,0), (-1,-1), 3),
        ("BOTTOMPADDING", (0,0), (-1,-1), 3),
        ("LEFTPADDING",   (0,0), (-1,-1), 10),
        ("GRID",          (0,0), (-1,-1), 0.2, MIDGRAY),
    ]))
    return [t_title, t_body]

# ── Document build ────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    leftMargin=MARGIN, rightMargin=MARGIN,
    topMargin=2.0*cm, bottomMargin=1.5*cm,
    title="Pediatric Abdominal Mass - Quick Reference",
    author="Orris Medical",
    subject="Pediatric Radiology - Differential Diagnosis"
)

story = []
SP = lambda n=4: Spacer(1, n)

# ══════════════════════════════════════════════════════
#  COVER BLOCK
# ══════════════════════════════════════════════════════
cover_data = [[
    Paragraph("PEDIATRIC ABDOMINAL MASS", Title),
    Paragraph("Differential Diagnosis · Quick Reference Card", Subtitle),
    Paragraph("Radiology · Pathology · Key Distinguishing Features", Subtitle),
]]
cover = Table(cover_data, colWidths=[PAGE_W - 2*MARGIN])
cover.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,-1), NAVY),
    ("TOPPADDING",    (0,0), (-1,-1), 18),
    ("BOTTOMPADDING", (0,0), (-1,-1), 18),
    ("LEFTPADDING",   (0,0), (-1,-1), 12),
    ("RIGHTPADDING",  (0,0), (-1,-1), 12),
    ("ROUNDEDCORNERS", [6]),
]))
story.append(cover)
story.append(SP(10))

# ══════════════════════════════════════════════════════
#  SECTION 1 - OVERVIEW TABLE (by age)
# ══════════════════════════════════════════════════════
story.append(section_banner("1. AGE-BASED DIFFERENTIAL OVERVIEW", NAVY))
story.append(SP(4))

age_headers = ["Age Group", "Most Likely Diagnosis", "Other Diagnoses to Consider"]
age_rows = [
    ["Neonate\n(0–1 month)",
     "Hydronephrosis (most common)\nMulticystic dysplastic kidney\nAdrenal haemorrhage",
     "Ovarian cyst (girls)\nMesenteric/enteric cyst\nNeuroblastoma (cystic)\nHepatoblastoma"],
    ["Infant\n(1–12 months)",
     "Wilms tumour (nephroblastoma)\nNeuroblastoma\nHepatoblastoma",
     "Hydronephrosis\nSplenic cyst\nLymphoma\nTeratoma (sacrococcygeal)"],
    ["Toddler\n(1–5 years)",
     "Wilms tumour (peak 3 yrs)\nNeuroblastoma (peak 2 yrs)\nHepatoblastoma",
     "Lymphoma\nRhabdomyosarcoma\nGerm cell tumour\nDuplication cyst"],
    ["School age\n(5–10 years)",
     "Wilms tumour\nLymphoma (NHL)\nHepatocellular carcinoma",
     "Rhabdomyosarcoma\nNeuroblastoma (rare)\nGastrointestinal stromal tumour\nTeratoma"],
    ["Adolescent\n(>10 years)",
     "Lymphoma (most common solid mass)\nOvarian tumour/cyst (girls)\nHepatocellular carcinoma",
     "Rhabdomyosarcoma\nDesmoplastic small round cell tumour\nGastrointestinal tumours\nRenal cell carcinoma"],
]
W = PAGE_W - 2*MARGIN
story.append(colored_table(age_headers, age_rows,
    col_widths=[3.2*cm, W*0.38, W*0.42], hdr_color=TEAL))
story.append(SP(10))

# ══════════════════════════════════════════════════════
#  SECTION 2 - MAJOR DIAGNOSES COMPARISON TABLE
# ══════════════════════════════════════════════════════
story.append(section_banner("2. MAJOR DIAGNOSES — COMPARISON TABLE", NAVY))
story.append(SP(4))

comp_headers = ["Feature", "Neuroblastoma", "Nephroblastoma\n(Wilms)", "Hepatoblastoma",
                "Lymphoma", "Hydronephrosis"]
comp_rows = [
    ["Origin",
     "Adrenal / sympathetic chain (neural crest)",
     "Kidney (metanephric blastema)",
     "Liver (hepatic progenitors)",
     "Lymph nodes / reticuloendothelial",
     "Renal collecting system"],
    ["Peak Age",
     "2 yrs\n(90% < 5 yrs)",
     "3 yrs\n(2–5 yrs)",
     "< 3 yrs\n(90%)",
     "Any; NHL peak\n5–10 yrs",
     "Any age\n(often prenatal)"],
    ["Location",
     "Retroperitoneal;\nsuprarenal;\ncan be thoracic/cervical",
     "Intrarenal;\nRUQ or LUQ",
     "RUQ; hepatic",
     "Mesenteric, retroperitoneal, splenic",
     "Flank; renal fossa"],
    ["Bilateral",
     "Rare (< 5%)",
     "10% of cases",
     "Rare",
     "Diffuse/multi-nodal",
     "10–30% depending on cause"],
    ["Calcification on CT",
     "Very common\n(up to 85%)",
     "Rare (< 10%)",
     "Present in 50%\n(dystrophic)",
     "Rare; post-treatment",
     "None"],
    ["Vessel relationship",
     "Encases aorta/IVC\n(does NOT displace)",
     "Displaces vessels;\nIVC tumour thrombus",
     "Hepatic vein/IVC\ninvasion possible",
     "Displacement;\nno encasement",
     "Hydronephrotic pelvis; ureter dilated"],
    ["Tumour thrombus",
     "Absent",
     "IVC/renal vein\n(up to 10%)",
     "Hepatic vein/IVC",
     "Absent",
     "Not applicable"],
    ["Crosses midline",
     "Common (large masses)",
     "Less common",
     "Can cross midline\nif large",
     "Often bilateral/midline\nnodal disease",
     "Does not cross"],
    ["US key finding",
     "Anterior displacement\nof aorta & IVC;\nhyperechoic foci (Ca++)",
     "Intrarenal mass;\nclaw of normal\nrenal tissue;\nIVC thrombus",
     "Hepatic mass;\nhyperechoic or mixed",
     "Hypoechoic nodal\nmasses; splenomegaly",
     "Dilated pelvicalyceal\nsystem with anechoic\npelvis"],
    ["CT hallmark",
     "Calcification 85%;\nencasement of vessels;\nextension into spinal canal\n(dumb-bell)",
     "Intrarenal; claw sign;\nlow-attenuation areas;\nheterogeneous enhancement",
     "Large liver mass;\nmay show tumour\nthrombus in hepatic veins",
     "Bulky retroperitoneal\nor mesenteric nodes;\nhomogeneous",
     "Dilated pelvis ± ureter;\nthin cortex if longstanding"],
    ["MRI best use",
     "Spinal canal invasion;\nbone marrow metastases",
     "Gold standard for\nbilateral disease;\nnephroblastomatosis",
     "Resectability;\nvascular involvement",
     "Extent of disease;\nspinal cord compression",
     "Anatomy of\nobstruction; duplex"],
    ["Nuclear medicine",
     "¹²³I-mIBG (specific);\n⁹⁹ᵐTc bone scan",
     "Not used",
     "Not standard",
     "FDG-PET/CT",
     "MAG3 / DTPA renogram\n(function + drainage)"],
    ["Biochemical marker",
     "Urine VMA/HVA ↑\n(~90% of cases)",
     "None specific",
     "AFP ↑↑ (> 90%)",
     "LDH ↑; uric acid ↑",
     "None specific"],
    ["Metastases",
     "Bone, bone marrow,\nliver, LN, skin\n(~50% at diagnosis)",
     "Lung (first), liver\n(stage IV ~10%)",
     "Lung most common;\nliver",
     "Widespread by staging;\nbone marrow in NHL",
     "Not a malignancy;\nbilateral = systemic cause"],
    ["Prognosis",
     "Stage & MYCN dependent;\noverall 5-yr ~75%;\nhigh-risk ~40%",
     "Excellent overall;\n5-yr OS 86–96% (I–III);\n70% bilateral (V)",
     "Good if resectable;\n5-yr OS ~70%",
     "Good with\nchemotherapy",
     "Excellent after\nrelief of obstruction"],
]
cw2 = [2.8*cm, (W-2.8*cm)/5, (W-2.8*cm)/5, (W-2.8*cm)/5, (W-2.8*cm)/5, (W-2.8*cm)/5]
story.append(colored_table(comp_headers, comp_rows, col_widths=cw2, hdr_color=NAVY))
story.append(SP(10))

# ══════════════════════════════════════════════════════
#  SECTION 3 - NEUROBLASTOMA vs NEPHROBLASTOMA (focused)
# ══════════════════════════════════════════════════════
story.append(section_banner("3. NEUROBLASTOMA vs. NEPHROBLASTOMA — KEY DIFFERENTIATORS", TEAL))
story.append(SP(4))

diff_headers = ["Criterion", "Neuroblastoma", "Nephroblastoma (Wilms)"]
diff_rows = [
    ["Kidney relationship", "DISPLACES kidney — kidney is separate, intact, with own capsule visible", "ARISES FROM kidney — residual tissue forms a 'claw/beak' around mass"],
    ["Calcification (CT)", "Very common (85%) — coarse, amorphous", "Rare (< 10%)"],
    ["Vessel encasement", "Encases aorta/IVC/mesenteric vessels — classic NB pattern", "Displaces vessels; IVC tumour thrombus in up to 10%"],
    ["mIBG scintigraphy", "POSITIVE in ~80% — pathognomonic", "NEGATIVE — no catecholamine uptake"],
    ["Urine catecholamines", "VMA/HVA elevated in ~90%", "Normal"],
    ["Spinal extension", "Dumb-bell through foramina — MRI mandatory", "Not a feature"],
    ["Bilateral disease", "Rare", "10% — MRI gold standard for bilateral"],
    ["Crossing midline", "Common (large retroperitoneal masses)", "Less common"],
    ["IVC thrombus", "Absent", "Present in up to 10% — assess on US and CT"],
    ["Associated syndromes", "Familial ALK mutations", "WAGR, Denys-Drash, Beckwith-Wiedemann"],
]
cw3 = [3.8*cm, (W-3.8*cm)/2, (W-3.8*cm)/2]
story.append(colored_table(diff_headers, diff_rows, col_widths=cw3, hdr_color=PURPLE))
story.append(SP(10))

# ══════════════════════════════════════════════════════
#  SECTION 4 - IMAGING APPROACH ALGORITHM
# ══════════════════════════════════════════════════════
story.append(section_banner("4. RECOMMENDED IMAGING APPROACH", NAVY))
story.append(SP(4))

algo_data = [
    [Paragraph("<b>STEP 1 — ULTRASOUND (FIRST LINE for all)</b>", Bold)],
    [Paragraph("• Determine organ of origin (renal vs. hepatic vs. retroperitoneal vs. pelvic)\n"
               "• Assess vascularity with Colour Doppler\n"
               "• Identify IVC / renal vein tumour thrombus (critical for Wilms)\n"
               "• Assess for calcification (hyperechoic foci)\n"
               "• Determine cystic vs. solid vs. mixed nature", Body)],
    [Paragraph("<b>STEP 2 — CT ABDOMEN/PELVIS with IV contrast (staging & characterisation)</b>", Bold)],
    [Paragraph("• NB: chest + abdomen + pelvis — early contrast phase for chest, portal phase for abdomen\n"
               "• Wilms: abdomen + pelvis; add chest CT if CXR equivocal for pulmonary metastases\n"
               "• Assess calcification, vessel encasement vs. displacement, lymphadenopathy\n"
               "• Evaluate contralateral kidney (bilateral Wilms / NB)", Body)],
    [Paragraph("<b>STEP 3 — MRI (specific indications)</b>", Bold)],
    [Paragraph("• Paraspinal NB: MANDATORY to evaluate spinal canal extension (dumb-bell)\n"
               "• Bilateral Wilms: GOLD STANDARD — superior to CT for bilateral disease\n"
               "• Nephroblastomatosis: gadolinium required to detect nephrogenic rests\n"
               "• Hepatic tumours: vascular anatomy for surgical planning\n"
               "• Preferred over CT in neonates/infants (no ionising radiation)", Body)],
    [Paragraph("<b>STEP 4 — NUCLEAR MEDICINE (disease-specific)</b>", Bold)],
    [Paragraph("• ¹²³I-mIBG scintigraphy: NEUROBLASTOMA only — characterisation + metastasis staging\n"
               "• ⁹⁹ᵐTc-MDP bone scan: NB skeletal metastases (+ mIBG)\n"
               "• MAG3 / DTPA renogram: HYDRONEPHROSIS — functional assessment\n"
               "• FDG-PET/CT: LYMPHOMA staging and treatment response\n"
               "• Hepatobiliary scan (HIDA): biliary atresia / choledochal cyst", Body)],
]
algo_t = Table([[row[0]] for row in algo_data], colWidths=[W])
algo_style = []
for i in range(len(algo_data)):
    if i % 2 == 0:
        algo_style.append(("BACKGROUND", (0,i), (-1,i), LTGRAY))
    else:
        algo_style.append(("BACKGROUND", (0,i), (-1,i), WHITE))
algo_style += [
    ("GRID",          (0,0), (-1,-1), 0.3, MIDGRAY),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("RIGHTPADDING",  (0,0), (-1,-1), 8),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]
flat_algo = [[Paragraph(row[0].text if hasattr(row[0], 'text') else "", Body)] for row in algo_data]

# Build as simple alternating table
algo_rows_built = []
for i, row in enumerate(algo_data):
    algo_rows_built.append([row[0]])

algo_t2 = Table(algo_rows_built, colWidths=[W])
algo_t2.setStyle(TableStyle([
    ("ROWBACKGROUNDS", (0,0), (-1,-1), [LTGRAY, WHITE]),
    ("GRID",           (0,0), (-1,-1), 0.3, MIDGRAY),
    ("TOPPADDING",     (0,0), (-1,-1), 6),
    ("BOTTOMPADDING",  (0,0), (-1,-1), 6),
    ("LEFTPADDING",    (0,0), (-1,-1), 10),
    ("RIGHTPADDING",   (0,0), (-1,-1), 10),
    ("VALIGN",         (0,0), (-1,-1), "TOP"),
]))
story.append(algo_t2)
story.append(SP(10))

# ══════════════════════════════════════════════════════
#  SECTION 5 - BIOCHEMICAL & CLINICAL RED FLAGS
# ══════════════════════════════════════════════════════
story.append(section_banner("5. CLINICAL & BIOCHEMICAL CLUES", TEAL))
story.append(SP(4))

clue_headers = ["Finding", "Think of...", "Notes"]
clue_rows = [
    ["Elevated urine VMA/HVA", "Neuroblastoma", "Present in ~90%; sufficient with +ve bone marrow to confirm Dx"],
    ["AFP markedly elevated", "Hepatoblastoma", "AFP normally high in neonates; use age-adjusted reference ranges"],
    ["Haematuria", "Wilms tumour", "Microscopic haematuria in 25%; macroscopic less common"],
    ["Hypertension", "Neuroblastoma, Wilms, Phaeochromocytoma, Renovascular", "Catecholamines (NB) vs. renin excess (Wilms)"],
    ["Horner syndrome", "Cervical/thoracic Neuroblastoma", "Stellate ganglion involvement"],
    ["Opsoclonus-myoclonus\n(dancing eyes/feet)", "Neuroblastoma", "Paraneoplastic — MEI; may have small/occult primary"],
    ["Watery diarrhoea\n(intractable)", "Neuroblastoma", "VIP (vasoactive intestinal peptide) production"],
    ["Proptosis /\n'raccoon eyes'", "Neuroblastoma\n(orbital metastases)", "Periorbital ecchymosis — classic NB presentation"],
    ["Aniridia", "Wilms tumour (WAGR syndrome)", "WT1 deletion on 11p13"],
    ["Hemihypertrophy /\nmacroglossia", "Wilms tumour\n(Beckwith-Wiedemann)", "Also hepatoblastoma risk; screen with USS"],
    ["Blueberry muffin skin\nnodules (neonate)", "Neuroblastoma\n(Stage 4S)", "Excellent prognosis; often undergoes spontaneous regression"],
    ["Elevated LDH + uric acid", "Lymphoma", "Tumour lysis risk; treat before biopsy"],
    ["Abdominal mass +\nback pain/leg weakness", "NB (dumb-bell tumour)", "Emergency MRI to rule out cord compression"],
    ["Painless abdominal mass,\ncrossing midline", "Neuroblastoma or\nLymphoma", "Wilms rarely crosses midline"],
    ["Palpable mass with\nrapid growth + fever", "Wilms tumour, Lymphoma", "Ruptured Wilms: peritoneal seeding → upstages to Stage III"],
]
cw5 = [3.8*cm, 3.5*cm, W - 3.8*cm - 3.5*cm]
story.append(colored_table(clue_headers, clue_rows, col_widths=cw5, hdr_color=AMBER))
story.append(SP(10))

# ══════════════════════════════════════════════════════
#  SECTION 6 - STAGING SYSTEMS
# ══════════════════════════════════════════════════════
story.append(section_banner("6. STAGING SYSTEMS", NAVY))
story.append(SP(4))

# Two-column layout: NB staging | Wilms staging
nb_stage = [
    ["<b>NEUROBLASTOMA — INSS Staging</b>"],
    ["Stage 1: Localised, complete gross excision ± microscopic residual"],
    ["Stage 2A: Localised, incomplete excision; ipsilateral LN negative"],
    ["Stage 2B: Localised ± incomplete excision; ipsilateral LN positive"],
    ["Stage 3: Unresectable unilateral tumour infiltrating across midline ± LN; or contralateral LN +ve"],
    ["Stage 4: Distant mets (bone, BM, liver, LN, other) except 4S"],
    ["Stage 4S: Localised primary + spread limited to liver, skin, BM only (no bone); age < 1 yr — excellent prognosis"],
    ["<b>Risk Groups:</b> Low / Intermediate / High (based on INSS + MYCN + ploidy + histology + ALK)"],
    ["<b>MYCN amplification</b> → auto High Risk regardless of stage"],
]

wilms_stage = [
    ["<b>NEPHROBLASTOMA — NWTSG Staging (post-surgical)</b>"],
    ["Stage I (43%): Confined to kidney; complete excision"],
    ["Stage II (23%): Beyond renal capsule; complete excision; vessel infiltration or biopsy pre-resection"],
    ["Stage III (23%): +ve abdominopelvic LN; peritoneal invasion; residual tumour or unresectable"],
    ["Stage IV (10%): Haematogenous spread (lung, liver, bone, brain) or outside abdomen/pelvis"],
    ["Stage V (5%): Bilateral tumours at diagnosis — nephron-sparing surgery goal"],
    ["<b>SIOP (European):</b> Biopsy + neoadjuvant chemo first; then surgical staging"],
    ["<b>Anaplasia:</b> Focal (5%) — better outcome; Diffuse — very poor (4-yr OS: III=45%, IV=7%)"],
    ["<b>4-yr OS:</b> Stage I–III: 86–96% | Stage IV: 83% | Stage V: 70%"],
]

def stage_table(rows, color):
    data = [[Paragraph(r[0], Small)] for r in rows]
    t = Table(data, colWidths=[(W/2) - 0.3*cm])
    row_styles = []
    for i in range(len(data)):
        bg = LTGRAY if i % 2 == 0 else WHITE
        row_styles.append(("BACKGROUND", (0,i), (-1,i), bg))
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,0), color),
        ("ROWBACKGROUNDS",(0,1), (-1,-1), [LTGRAY, WHITE]),
        ("GRID",          (0,0), (-1,-1), 0.3, MIDGRAY),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING",   (0,0), (-1,-1), 6),
        ("RIGHTPADDING",  (0,0), (-1,-1), 6),
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ]))
    return t

# Override first row text color
nb_t = stage_table(nb_stage, TEAL)
wilms_t = stage_table(wilms_stage, PURPLE)

combo = Table([[nb_t, wilms_t]], colWidths=[W/2 - 0.1*cm, W/2 - 0.1*cm],
              hAlign="LEFT")
combo.setStyle(TableStyle([
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("LEFTPADDING",  (0,0), (-1,-1), 0),
    ("RIGHTPADDING", (0,0), (-1,-1), 3),
]))
story.append(combo)
story.append(SP(10))

# ══════════════════════════════════════════════════════
#  SECTION 7 - OTHER IMPORTANT ABDOMINAL MASSES
# ══════════════════════════════════════════════════════
story.append(section_banner("7. OTHER IMPORTANT PEDIATRIC ABDOMINAL MASSES", TEAL))
story.append(SP(4))

other_headers = ["Tumour / Mass", "Key Features", "Radiology Clues", "Biochemistry"]
other_rows = [
    ["Hepatoblastoma",
     "Most common hepatic malignancy in children < 3 yrs. Associated with BWS, prematurity, FAP.",
     "US/CT: hepatic mass, often heterogeneous, calcification in 50%. MRI best for resectability & vascular involvement.",
     "AFP markedly elevated (> 1,000 ng/mL)"],
    ["Hepatic haemangioma\n(infantile)",
     "Most common benign hepatic tumour in infants. Often multiple. Most regress by age 5.",
     "US: hyperechoic nodules. Contrast CT/MRI: peripheral nodular enhancement with centripetal fill-in. No AFP rise.",
     "Normal AFP; Kasabach-Merritt if large"],
    ["Ovarian cyst / tumour",
     "Most common abdominal mass in newborn girls. Follicular cysts common. Germ cell tumours in adolescents.",
     "US: anechoic (simple cyst) or complex (teratoma — fat + calcification on CT). MRI for complex masses.",
     "AFP/βhCG elevated in germ cell tumours"],
    ["Sacrococcygeal teratoma",
     "Most common neonatal tumour. 80% benign in neonates; risk of malignancy rises with age.",
     "US/MRI: mixed cystic-solid mass at sacrococcygeal region extending into pelvis. CT: calcification.",
     "AFP elevated if malignant"],
    ["Choledochal cyst",
     "Congenital biliary dilatation. Presents with pain, jaundice, mass (Charcot's triad). Risk of cholangiocarcinoma.",
     "US: cystic mass in RUQ closely related to bile duct. MRCP for delineation of biliary anatomy.",
     "ALP/GGT elevated; bilirubin"],
    ["Mesenteric / duplication cyst",
     "Benign; may be symptomatic from torsion/bleeding. Duplication cysts share bowel wall.",
     "US: anechoic thin-walled cyst. Duplication cysts: thick muscular wall with 'gut signature' on US.",
     "Normal"],
    ["Lymphoma (NHL / Hodgkin)",
     "Most common abdominal malignancy in > 5 yrs. Burkitt NHL common in ileocaecal region.",
     "US/CT: bulky homogeneous hypoechoic retroperitoneal/mesenteric lymphadenopathy. Splenomegaly. FDG-PET/CT for staging.",
     "LDH ↑, uric acid ↑; β2-microglobulin ↑"],
    ["Rhabdomyosarcoma",
     "Most common soft tissue sarcoma in children. Abdominopelvic sites: bladder, prostate, vagina, retroperitoneum.",
     "US/CT: heterogeneous soft tissue mass. Bladder RMS: irregular filling defect. MRI for pelvic extension.",
     "Non-specific; urinalysis if bladder involved"],
    ["Multicystic dysplastic\nkidney (MCDK)",
     "Benign non-functioning kidney replaced by non-communicating cysts. Usually unilateral. Contralateral UPJO in 15%.",
     "US: multiple non-communicating cysts of varying sizes with no central large cyst. No reniform shape.",
     "MAG3 confirms non-function"],
    ["Hydronephrosis",
     "Most common cause of neonatal abdominal mass. UPJO (ureteropelvic junction obstruction) most common cause.",
     "US: dilated pelvicalyceal system. MAG3 renogram for function and drainage. MRI urography for anatomy.",
     "Creatinine if bilateral"],
]
cw7 = [3.0*cm, (W-3.0*cm)*0.34, (W-3.0*cm)*0.40, (W-3.0*cm)*0.26]
story.append(colored_table(other_headers, other_rows, col_widths=cw7, hdr_color=GREEN))
story.append(SP(10))

# ══════════════════════════════════════════════════════
#  SECTION 8 - RED FLAG BOX
# ══════════════════════════════════════════════════════
story.append(section_banner("8. RED FLAGS — URGENT ASSESSMENT REQUIRED", RED))
story.append(SP(4))

red_lines = [
    "• Abdominal mass + lower limb weakness / bladder/bowel dysfunction → MRI SPINE STAT (NB dumb-bell / lymphoma cord compression)",
    "• Hypertensive crisis + abdominal mass → Neuroblastoma / Phaeochromocytoma (urine catecholamines urgently)",
    "• Rapidly expanding mass + fever + anaemia → Wilms tumour (avoid palpation — risk of rupture)",
    "• Bilateral renal masses → Wilms Stage V — nephron-sparing imperative; consult paediatric oncology",
    "• IVC tumour thrombus extending to right atrium (Wilms) → cardiac surgery team involvement pre-op",
    "• Opsoclonus-myoclonus (dancing eyes) in an infant → Search for occult neuroblastoma (mIBG + urine catecholamines)",
    "• Neonatal abdominal mass crossing the midline → Most likely neuroblastoma; urgent US + catecholamines",
    "• Wilms tumour rupture (peritoneal seeding) → Upstages to Stage III; bilateral coverage chemotherapy required",
]
red_data = [[Paragraph(l, Body)] for l in red_lines]
red_t = Table(red_data, colWidths=[W])
red_t.setStyle(TableStyle([
    ("ROWBACKGROUNDS", (0,0), (-1,-1), [colors.HexColor("#fff5f5"), WHITE]),
    ("GRID",           (0,0), (-1,-1), 0.3, colors.HexColor("#f5c6c6")),
    ("TOPPADDING",     (0,0), (-1,-1), 5),
    ("BOTTOMPADDING",  (0,0), (-1,-1), 5),
    ("LEFTPADDING",    (0,0), (-1,-1), 8),
    ("RIGHTPADDING",   (0,0), (-1,-1), 8),
    ("VALIGN",         (0,0), (-1,-1), "TOP"),
]))
story.append(red_t)
story.append(SP(10))

# ══════════════════════════════════════════════════════
#  SECTION 9 - MNEMONICS
# ══════════════════════════════════════════════════════
story.append(section_banner("9. MNEMONICS & MEMORY AIDS", TEAL))
story.append(SP(4))

mnem_data = [
    [Paragraph("<b>Neuroblastoma — 'NEAT'</b>", SmallBold),
     Paragraph("<b>Wilms — 'RAVEN'</b>", SmallBold),
     Paragraph("<b>Hepatoblastoma — 'HALF'</b>", SmallBold)],
    [Paragraph("<b>N</b>eural crest origin\n<b>E</b>levated VMA/HVA\n<b>A</b>drenal / paraaortic\n<b>T</b>umour calcification 85%", Small),
     Paragraph("<b>R</b>enal origin\n<b>A</b>FP normal\n<b>V</b>ein (IVC) thrombus\n<b>E</b>xcellent prognosis\n<b>N</b>o calcification usually", Small),
     Paragraph("<b>H</b>epatic location\n<b>A</b>FP very high\n<b>L</b>iver mass < 3 yrs\n<b>F</b>AP / BWS association", Small)],
]
mnem_t = Table(mnem_data, colWidths=[W/3, W/3, W/3])
mnem_t.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), LTGRAY),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE]),
    ("GRID",          (0,0), (-1,-1), 0.4, MIDGRAY),
    ("TOPPADDING",    (0,0), (-1,-1), 6),
    ("BOTTOMPADDING", (0,0), (-1,-1), 6),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ("ALIGN",         (0,0), (-1,-1), "LEFT"),
]))
story.append(mnem_t)
story.append(SP(10))

# ══════════════════════════════════════════════════════
#  SECTION 10 - SOURCES
# ══════════════════════════════════════════════════════
story.append(HRFlowable(width="100%", thickness=0.5, color=MIDGRAY))
story.append(SP(4))
story.append(Paragraph(
    "<b>Sources:</b> Grainger &amp; Allison's Diagnostic Radiology (Elsevier) · "
    "Robbins &amp; Kumar Basic Pathology (Elsevier) · "
    "Campbell Walsh Wein Urology · "
    "Robbins, Cotran &amp; Kumar Pathologic Basis of Disease",
    FooterS))

# ── Build ──────────────────────────────────────────────────────────────────────
doc.build(story, onFirstPage=on_first_page, onLaterPages=on_page)
print(f"PDF created: {OUTPUT}")
Running Command

cd /home/daytona/workspace/peds-abdominal-mass && python generate_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/peds-abdominal-mass/Pediatric_Abdominal_Mass_DDx.…

Your quick reference PDF is ready:

Pediatric Abdominal Mass DDx

PDF Document · PDF


Here's what's inside the document:
Section 1 - Age-Based Differential Overview A table organizing the differential by age group: neonate, infant, toddler, school age, and adolescent - showing what to think of first at each stage.
Section 2 - Major Diagnoses Comparison Table Side-by-side comparison of Neuroblastoma, Nephroblastoma (Wilms), Hepatoblastoma, Lymphoma, and Hydronephrosis across 15 features: origin, peak age, location, calcification, vessel relationship, tumour thrombus, US/CT/MRI findings, nuclear medicine, biochemistry, metastases, and prognosis.
Section 3 - Neuroblastoma vs. Nephroblastoma (focused) The 10 most important differentiating criteria (kidney relationship, calcification, mIBG, vessel encasement, IVC thrombus, spinal extension, etc.).
Section 4 - Imaging Approach Algorithm Step-by-step: US first → CT → MRI (with specific indications for each) → Nuclear medicine (which modality for which diagnosis).
Section 5 - Clinical & Biochemical Clues 15 findings mapped to diagnoses - from elevated VMA/HVA and AFP, to opsoclonus-myoclonus, Horner syndrome, raccoon eyes, and blueberry muffin skin.
Section 6 - Staging Systems INSS (Neuroblastoma) and NWTSG/SIOP (Wilms) staging in a two-column layout with survival data.
Section 7 - Other Important Masses Hepatoblastoma, ovarian tumours, sacrococcygeal teratoma, choledochal cyst, duplication cyst, lymphoma, rhabdomyosarcoma, MCDK, and hydronephrosis.
Section 8 - Red Flags 8 urgent scenarios requiring immediate action (cord compression, IVC thrombus, hypertensive crisis, tumour rupture, etc.).
Section 9 - Mnemonics NEAT (Neuroblastoma), RAVEN (Wilms), HALF (Hepatoblastoma).
This is a shared conversation. Sign in to Orris to start your own chat.