Classification and grading of neuroendocrine neoplasm of digestive system

Reading File
Finding Sources
Finding Sources
Searching PubMed

"neuroendocrine neoplasm" AND "classification" AND "digestive"

Finding Sources
Finding Sources
Reading Article

PMID: 37690447

Reading File
Reading File
Searching the Web

WHO 2019 classification grading neuroendocrine neoplasm digestive system NET NEC

Reading Web Page

https://pmc.ncbi.nlm.nih.gov/articles/PMC9281538

Reading File
Loading Image
Reading Web Page

https://ronnyallan.net/2024/03/11/neuroendocrine-neoplasms-g…

Here is a comprehensive overview of the WHO Classification and Grading of Neuroendocrine Neoplasms (NENs) of the Digestive System, based on the WHO 5th Edition (2019) and updated with the WHO 2022 Endocrine/Neuroendocrine compilation.

Overview and Terminology

Neuroendocrine neoplasms (NENs) of the digestive system arise from neuroendocrine cells distributed throughout the GI tract and pancreas. The term "carcinoid" has been retired in the current WHO framework. The modern umbrella term is NEN, which is divided into two fundamentally distinct categories based on differentiation:
  1. Neuroendocrine Tumor (NET) - well-differentiated
  2. Neuroendocrine Carcinoma (NEC) - poorly differentiated
  3. Mixed Neuroendocrine-Non-Neuroendocrine Neoplasm (MiNEN) - hybrid

WHO 2019/2022 Classification Framework

Category 1: Neuroendocrine Tumors (NETs) - Well-Differentiated

NETs show organoid or nested architecture, uniform nuclear features, coarsely stippled ("salt-and-pepper") chromatin, and minimal necrosis. They express synaptophysin and chromogranin A. They are graded G1 to G3 based on proliferative activity:
GradeMitotic Rate (per 2 mm²)Ki-67 IndexDifferentiation
G1< 2< 3%Well-differentiated
G22-203-20%Well-differentiated
G3> 20> 20%Well-differentiated
Key principle: When mitotic rate and Ki-67 are discordant, the higher result determines the grade. Ki-67 is assessed by counting at least 500 cells in "hotspot" regions of highest labeling.

The G3 NET - A Critical New Addition

The G3 NET category was formally established in WHO 2019 (first introduced for pancreatic NETs in 2017). It recognizes that high proliferative index does NOT equal poor differentiation. G3 NETs:
  • Retain well-differentiated morphology despite Ki-67 >20%
  • Often have intact TP53 and RB1 (unlike NECs)
  • Ki-67 typically <55% (though not a strict cutoff)
  • Less aggressive than NECs but worse prognosis than G1/G2
  • May represent metastases from a previously lower-grade primary

Category 2: Neuroendocrine Carcinomas (NECs) - Poorly Differentiated

NECs are always high-grade by definition and are not assigned a grade (to avoid confusion with G3 NETs). They are characterized by:
  • Ki-67 typically >20%, mitotic rate >20/2 mm²
  • Often extensively necrotic
  • Sheet-like growth with less nested architecture
  • Loss of TP53 and/or RB1 (distinguishes from NET G3 molecularly)
NECs are subtyped by morphology:
SubtypeFeatures
Small Cell NEC (SCNEC)Tightly packed fusiform nuclei, finely granular chromatin, scant cytoplasm - resembles small cell lung cancer
Large Cell NEC (LCNEC)Rounded markedly atypical nuclei, prominent nucleoli, abundant cytoplasm
Both subtypes are highly aggressive, usually present at advanced stage, and behave similarly to small/large cell lung carcinoma.

Category 3: Mixed Neuroendocrine-Non-Neuroendocrine Neoplasm (MiNEN)

Formerly called Mixed Adenoneuroendocrine Carcinoma (MANEC) in earlier WHO editions, renamed MiNEN in WHO 2019 to reflect that the non-neuroendocrine component is not always adenocarcinoma (it may be squamous, acinar, etc.).
  • Definition: Each component (neuroendocrine + non-neuroendocrine) must constitute at least 30% of the tumor based on morphology and IHC
  • Either component can be well- or poorly differentiated
  • Prognosis is generally driven by the highest-grade component present
  • ICD-O code: 8154/3

Grading Summary Table (WHO 2019/2022)

CategoryDifferentiationGradeMitoses/2 mm²Ki-67
NET G1WellG1<2<3%
NET G2WellG22-203-20%
NET G3WellG3>20>20%
NEC (SCNEC/LCNEC)PoorlyHigh (not graded)>20>20%
MiNENMixedPer component--

Site-Based Classification (Anatomical)

NENs of the digestive tract are also grouped by embryonic origin - relevant to secretory profile, behavior, and prognosis:
DivisionSitesCharacteristics
ForegutEsophagus, stomach, duodenum (proximal to ligament of Treitz), pancreasRarely metastasize; gastrinomas may cause Zollinger-Ellison syndrome
MidgutJejunum, ileumOften multiple; tend to be aggressive; associated with carcinoid syndrome when metastatic
HindgutAppendix, colon, rectumAppendiceal NETs nearly always benign; rectal NETs usually small, rarely metastasize
  • Robbins & Kumar Basic Pathology (Robbins Pathology)

Functional Classification

NENs are additionally categorized as:
  • Functional: Secrete hormones causing a clinical syndrome (e.g., insulinoma - hypoglycemia; gastrinoma - Zollinger-Ellison; VIPoma - WDHA syndrome; glucagonoma; somatostatinoma)
  • Non-functional: ~1/3 of all pancreatic NENs; no clinical syndrome despite often having elevated tumor markers

Key Histologic and IHC Features

Architecture: Islands, trabeculae, strands, glands, or sheets of uniform cells
Cytology: Scant pink granular cytoplasm; round-to-oval stippled ("salt-and-pepper") nucleus
IHC markers:
  • Synaptophysin (most sensitive)
  • Chromogranin A (most specific; >90% diagnostic sensitivity for NENs)
  • Ki-67 (for grading)
  • Somatostatin receptor 2/5 (relevant for SSA therapy and imaging)
Serum marker: Chromogranin A - useful for monitoring therapy response; note false positives with PPI use, renal dysfunction, IBD.

Important Distinctions: NET G3 vs. NEC

This is the single most clinically important distinction in the modern classification:
FeatureNET G3NEC
DifferentiationWellPoorly
ArchitectureOrganoid/nestedSheet-like
ChromatinCoarse "salt and pepper"Finely granular (SCNEC) or open (LCNEC)
NecrosisMinimalAbundant
Ki-67>20%, often <55%Usually >55%, can be lower after chemo
TP53/RB1IntactOften mutated/lost
OriginOften de novo or from lower-grade NETDe novo
Response to platinum chemoPoorGood
PrognosisIntermediateVery poor

Historical Evolution of WHO Classification

YearKey Change
WHO 2000Introduced grading based on proliferative activity
WHO 2010Formalized mitotic rate/Ki-67 grading; all NETs classified as malignant
WHO 2017 (Pancreatic)Added G3 NET category for pancreatic NENs
WHO 2019 (Digestive)G3 NET extended to all GI/digestive sites; MANEC renamed MiNEN; "carcinoid" retired
WHO 2022 (Endocrine/NEN)Consolidated all NEN classifications (GEP + non-GEP) into one framework

Histology Images

Below are classic histologic features of a gastrointestinal NET (carcinoid tumor), from Robbins & Kumar Pathology:
GI Carcinoid (NET) - submucosal nodule (A) and salt-and-pepper nuclear pattern (B)
(A) Submucosal nodule with dense fibrous stroma; (B) Bland cytology with the characteristic "salt-and-pepper" chromatin pattern of neuroendocrine differentiation. - Robbins & Kumar Basic Pathology

Key clinical pearls:
  • All NETs must be considered malignant - they carry metastatic potential regardless of grade
  • The term NET should not be used interchangeably with NEN (NEN is the umbrella; NET is specifically the well-differentiated subtype)
  • Referring to G3 NETs as "NECs" is a common but incorrect practice per current classification - Helderman et al., Neuroendocrinology 2024 highlights this as a major source of misinterpretation in the literature
  • For molecular classification updates including DAXX/ATRX mutations in pancreatic NETs, the WHO 2022 framework is the most current reference

Please give pdf

Reading File
Running Command

ls /home/daytona/workspace/ 2>/dev/null || mkdir -p /home/daytona/workspace/nen-…

Running Command

mkdir -p /home/daytona/workspace/nen-pdf

Writing File

~/nen-pdf/generate_nen_pdf.py

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

OUTPUT = "/home/daytona/workspace/nen-pdf/NEN_Digestive_System_Classification_Grading.pdf"

doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    rightMargin=2*cm, leftMargin=2*cm,
    topMargin=2*cm, bottomMargin=2*cm,
    title="Classification & Grading of NENs of the Digestive System",
    author="Orris Medical"
)

styles = getSampleStyleSheet()

# Custom styles
title_style = ParagraphStyle(
    'CustomTitle', parent=styles['Title'],
    fontSize=20, textColor=colors.HexColor('#1a3c5e'),
    spaceAfter=6, leading=24, alignment=TA_CENTER
)
subtitle_style = ParagraphStyle(
    'Subtitle', parent=styles['Normal'],
    fontSize=11, textColor=colors.HexColor('#4a6080'),
    spaceAfter=14, alignment=TA_CENTER, italic=True
)
h1_style = ParagraphStyle(
    'H1', parent=styles['Heading1'],
    fontSize=14, textColor=colors.white,
    backColor=colors.HexColor('#1a3c5e'),
    spaceBefore=14, spaceAfter=6, leading=18,
    leftIndent=-0.3*cm, rightIndent=-0.3*cm,
    borderPad=5
)
h2_style = ParagraphStyle(
    'H2', parent=styles['Heading2'],
    fontSize=12, textColor=colors.HexColor('#1a3c5e'),
    spaceBefore=10, spaceAfter=4, leading=16,
    borderPad=3
)
h3_style = ParagraphStyle(
    'H3', parent=styles['Heading3'],
    fontSize=10.5, textColor=colors.HexColor('#2e6da4'),
    spaceBefore=8, spaceAfter=3, leading=14, italic=True
)
body_style = ParagraphStyle(
    'Body', parent=styles['Normal'],
    fontSize=9.5, leading=14, spaceAfter=4, alignment=TA_JUSTIFY
)
bullet_style = ParagraphStyle(
    'Bullet', parent=styles['Normal'],
    fontSize=9.5, leading=13, spaceAfter=2,
    leftIndent=14, bulletIndent=4
)
note_style = ParagraphStyle(
    'Note', parent=styles['Normal'],
    fontSize=9, leading=13, textColor=colors.HexColor('#555555'),
    backColor=colors.HexColor('#f0f4f8'),
    borderPad=6, spaceAfter=6, leftIndent=4, rightIndent=4
)
footer_style = ParagraphStyle(
    'Footer', parent=styles['Normal'],
    fontSize=8, textColor=colors.grey, alignment=TA_CENTER
)

TABLE_HEADER_BG = colors.HexColor('#1a3c5e')
TABLE_ALT_BG    = colors.HexColor('#eaf2fb')
TABLE_GRID      = colors.HexColor('#aac4de')
TABLE_WARN_BG   = colors.HexColor('#fff3cd')

def section_heading(text):
    return Paragraph(f"&nbsp;&nbsp;{text}", h1_style)

def sub_heading(text):
    return Paragraph(text, h2_style)

def sub3_heading(text):
    return Paragraph(text, h3_style)

def body(text):
    return Paragraph(text, body_style)

def bullet(text):
    return Paragraph(f"&#8226; {text}", bullet_style)

def note(text):
    return Paragraph(f"<b>Note:</b> {text}", note_style)

def spacer(h=0.3):
    return Spacer(1, h*cm)

def hr():
    return HRFlowable(width="100%", thickness=0.5, color=colors.HexColor('#aac4de'), spaceAfter=6)

# ─── Table builder ────────────────────────────────────────────────────────────
def make_table(headers, rows, col_widths=None, alt=True):
    data = [[Paragraph(f"<b>{h}</b>", ParagraphStyle('TH', parent=styles['Normal'],
             fontSize=9, textColor=colors.white, leading=12)) for h in headers]]
    for i, row in enumerate(rows):
        data.append([Paragraph(str(c), ParagraphStyle('TD', parent=styles['Normal'],
                     fontSize=9, leading=12)) for c in row])
    ts = TableStyle([
        ('BACKGROUND', (0,0), (-1,0), TABLE_HEADER_BG),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.white, TABLE_ALT_BG] if alt else [colors.white]),
        ('GRID', (0,0), (-1,-1), 0.4, TABLE_GRID),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 5),
        ('RIGHTPADDING', (0,0), (-1,-1), 5),
    ])
    t = Table(data, colWidths=col_widths, repeatRows=1)
    t.setStyle(ts)
    return t

# ═══════════════════════════════════════════════════════════════════════════════
story = []

# ── TITLE PAGE ─────────────────────────────────────────────────────────────────
story.append(spacer(2))
story.append(Paragraph("Classification & Grading of", title_style))
story.append(Paragraph("Neuroendocrine Neoplasms (NENs)", title_style))
story.append(Paragraph("of the Digestive System", title_style))
story.append(spacer(0.5))
story.append(Paragraph("WHO 5th Edition (2019) · Updated WHO 2022 Framework", subtitle_style))
story.append(HRFlowable(width="80%", thickness=2, color=colors.HexColor('#1a3c5e'), hAlign='CENTER'))
story.append(spacer(0.5))
story.append(Paragraph("Based on: Robbins & Kumar Basic Pathology | Tietz Textbook of Laboratory Medicine | WHO Classification of Digestive System Tumours", subtitle_style))
story.append(spacer(3))

# ── SECTION 1: OVERVIEW ────────────────────────────────────────────────────────
story.append(section_heading("1.  Overview & Terminology"))
story.append(spacer())
story.append(body(
    "Neuroendocrine neoplasms (NENs) are a heterogeneous group of tumors arising from "
    "neuroendocrine cells distributed throughout the GI tract and pancreas. The term "
    "<b>\"carcinoid\"</b> has been retired in the current WHO framework. The umbrella term "
    "<b>NEN</b> is divided into fundamentally distinct categories based on <b>differentiation</b>."
))
story.append(spacer(0.4))

overview_table = make_table(
    ["Category", "Abbreviation", "Differentiation", "Graded?"],
    [
        ["Neuroendocrine Tumor", "NET", "Well-differentiated", "Yes (G1, G2, G3)"],
        ["Neuroendocrine Carcinoma", "NEC", "Poorly differentiated", "No (always high-grade)"],
        ["Mixed Neuroendocrine-Non-Neuroendocrine Neoplasm", "MiNEN", "Mixed", "Per component"],
    ],
    col_widths=[7*cm, 2.5*cm, 4*cm, 3.5*cm]
)
story.append(overview_table)
story.append(spacer())
story.append(note(
    "All NETs should be considered malignant — they carry metastatic potential regardless of grade. "
    "The term NET should NOT be used interchangeably with NEN (NEN is the umbrella; NET is "
    "specifically the well-differentiated subtype)."
))

# ── SECTION 2: WHO GRADING ─────────────────────────────────────────────────────
story.append(spacer())
story.append(section_heading("2.  WHO 2019/2022 Grading System"))
story.append(spacer())
story.append(sub_heading("2.1  Grading of Well-Differentiated NETs (G1 / G2 / G3)"))
story.append(body(
    "NETs are graded G1 to G3 based on two proliferative parameters: <b>mitotic rate</b> (mitoses/2 mm²) "
    "and <b>Ki-67 proliferation index</b>. When the two parameters are discordant, the "
    "<b>higher result determines the grade</b>."
))
story.append(spacer(0.3))

grading_table = make_table(
    ["Grade", "Mitotic Rate (per 2 mm²)", "Ki-67 Index", "Differentiation", "Behavior"],
    [
        ["G1", "< 2", "< 3%", "Well-differentiated", "Indolent; low metastatic risk"],
        ["G2", "2 – 20", "3 – 20%", "Well-differentiated", "Intermediate aggressiveness"],
        ["G3 NET", "> 20", "> 20%", "Well-differentiated", "High proliferation; NOT equivalent to NEC"],
        ["NEC (SCNEC/LCNEC)", "> 20", "> 20% (often >>55%)", "Poorly differentiated", "Highly aggressive; treat as small/large cell carcinoma"],
    ],
    col_widths=[2.5*cm, 3.5*cm, 2.5*cm, 3.5*cm, 5*cm]
)
story.append(grading_table)
story.append(spacer(0.4))

story.append(sub3_heading("Ki-67 Assessment Method"))
for b in [
    "Count at least <b>500 cells</b> in regions of highest labeling (\"hotspots\"), identified by scanning magnification.",
    "When two areas with differing indices are present, select the <b>higher-index area</b> for grading.",
    "Ki-67 can be assessed on small biopsies; mitotic count requires at least 50 HPF (≥10 mm of tissue) and may be unreliable on small samples.",
]:
    story.append(bullet(b))

story.append(spacer())
story.append(sub_heading("2.2  The G3 NET — A Critical New Category (WHO 2019)"))
story.append(body(
    "The G3 NET category was formally established in WHO 2019 (first introduced for pancreatic NETs in 2017). "
    "It recognizes that <b>high proliferative index does NOT equal poor differentiation</b>."
))
story.append(spacer(0.3))

g3_table = make_table(
    ["Feature", "NET G3", "NEC (Poorly Differentiated)"],
    [
        ["Differentiation", "Well", "Poorly"],
        ["Architecture", "Organoid / nested", "Sheet-like, less nested"],
        ["Chromatin pattern", "Coarse 'salt-and-pepper'", "Finely granular (SCNEC) or open nucleoli (LCNEC)"],
        ["Necrosis", "Minimal", "Abundant"],
        ["Ki-67", "> 20%, typically < 55%", "Usually > 55% (can be lower after chemo)"],
        ["TP53 / RB1 status", "Typically intact", "Frequently mutated / lost"],
        ["G3 components / prior low-grade", "May arise from G1/G2 or contain low-grade areas", "De novo"],
        ["Response to platinum-based chemo", "Poor", "Good"],
        ["Prognosis", "Intermediate", "Very poor"],
    ],
    col_widths=[5*cm, 5.5*cm, 6.5*cm]
)
story.append(g3_table)

# ── SECTION 3: NEC ─────────────────────────────────────────────────────────────
story.append(spacer())
story.append(section_heading("3.  Neuroendocrine Carcinomas (NECs)"))
story.append(spacer())
story.append(body(
    "NECs are <b>always high-grade by definition</b> and are <b>not assigned a numeric grade</b> "
    "(to avoid confusion with G3 NETs). They are poorly differentiated epithelial neoplasms with "
    "neuroendocrine differentiation confirmed by morphology and IHC."
))
story.append(spacer(0.3))

nec_table = make_table(
    ["Subtype", "ICD-O Code", "Morphology", "Nuclear Features", "Analogue"],
    [
        ["Small Cell NEC (SCNEC)", "8041/3",
         "Sheets; scant cytoplasm; crush artifact common",
         "Fusiform, finely granular chromatin, inconspicuous nucleoli",
         "Small cell lung carcinoma"],
        ["Large Cell NEC (LCNEC)", "8013/3",
         "Sheets/nests; moderate-abundant cytoplasm; necrosis",
         "Rounded, markedly atypical; prominent nucleoli",
         "Large cell neuroendocrine lung carcinoma"],
    ],
    col_widths=[3.2*cm, 2.2*cm, 4*cm, 4.5*cm, 3.1*cm]
)
story.append(nec_table)
story.append(spacer(0.3))
story.append(note(
    "Previously the term NEC was used for metastatic well-differentiated NETs. In the current "
    "classification, NEC applies ONLY to poorly differentiated neoplasms. Chemotherapy-treated NECs "
    "may show Ki-67 in the 20–50% range, so proliferation index alone cannot differentiate NET G3 from NEC."
))

# ── SECTION 4: MiNEN ───────────────────────────────────────────────────────────
story.append(spacer())
story.append(section_heading("4.  Mixed Neuroendocrine-Non-Neuroendocrine Neoplasm (MiNEN)"))
story.append(spacer())
story.append(body(
    "Formerly termed <b>Mixed Adenoneuroendocrine Carcinoma (MANEC)</b> in earlier WHO editions, "
    "renamed <b>MiNEN</b> in WHO 2019 to reflect that the non-neuroendocrine component is not always "
    "adenocarcinoma (may be squamous, acinar, etc.)."
))
story.append(spacer(0.3))

minen_data = [
    ["ICD-O Code", "8154/3"],
    ["Definition threshold", "Each component (NE + non-NE) ≥ 30% of the tumor (morphology + IHC)"],
    ["Subtypes of NE component", "May be NET or NEC"],
    ["Subtypes of non-NE component", "Adenocarcinoma (most common), squamous, acinar"],
    ["Prognosis driver", "Highest-grade component present"],
]

minen_table_data = [[Paragraph(f"<b>{r[0]}</b>", ParagraphStyle('Key', parent=styles['Normal'], fontSize=9, leading=12)),
                     Paragraph(r[1], ParagraphStyle('Val', parent=styles['Normal'], fontSize=9, leading=12))]
                    for r in minen_data]
minen_table = Table(minen_table_data, colWidths=[5*cm, 12*cm])
minen_table.setStyle(TableStyle([
    ('ROWBACKGROUNDS', (0,0), (-1,-1), [colors.white, TABLE_ALT_BG]),
    ('GRID', (0,0), (-1,-1), 0.4, TABLE_GRID),
    ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
    ('TOPPADDING', (0,0), (-1,-1), 4),
    ('BOTTOMPADDING', (0,0), (-1,-1), 4),
    ('LEFTPADDING', (0,0), (-1,-1), 5),
]))
story.append(minen_table)

# ── SECTION 5: SITE-BASED CLASSIFICATION ──────────────────────────────────────
story.append(PageBreak())
story.append(section_heading("5.  Site-Based (Anatomical / Embryonic) Classification"))
story.append(spacer())
story.append(body(
    "NENs of the digestive tract are grouped by embryonic origin. This influences secretory profile, "
    "biological behavior, and prognosis."
))
story.append(spacer(0.3))

site_table = make_table(
    ["Division", "Sites", "Key Features / Syndromes"],
    [
        ["Foregut",
         "Esophagus, stomach, duodenum (proximal to ligament of Treitz), pancreas",
         "Rarely metastasize; gastrinomas → Zollinger-Ellison syndrome; ECL cell types in stomach"],
        ["Midgut",
         "Jejunum, ileum",
         "Often multiple; tend to be aggressive; serotonin-secreting → carcinoid syndrome when liver metastases present"],
        ["Hindgut",
         "Appendix, colon, rectum",
         "Appendiceal NETs: nearly always benign; rectal NETs: usually small, rarely metastasize; produce polypeptide hormones"],
    ],
    col_widths=[2.8*cm, 6*cm, 8.2*cm]
)
story.append(site_table)

story.append(spacer())
story.append(sub_heading("5.1  Gastric NET Subtypes"))
story.append(body("Gastric NETs arise from ECL (enterochromaffin-like) cells and are classified into 3 types:"))
story.append(spacer(0.3))

gastric_table = make_table(
    ["Type", "Background", "Association", "Behavior"],
    [
        ["Type 1 (ECL cell NET)", "Chronic atrophic gastritis", "Hypergastrinemia (secondary); autoimmune gastritis", "Benign course; rarely metastasize; <1 cm usually"],
        ["Type 2 (ECL cell NET)", "Zollinger-Ellison + MEN-1", "Hypergastrinemia (primary/tumor-driven)", "Intermediate; locally aggressive in some cases"],
        ["Type 3 (Sporadic NET)", "Normal gastric mucosa", "No hypergastrinemia; no underlying disease", "Aggressive; high risk of metastasis; treat as malignant"],
    ],
    col_widths=[3.5*cm, 4*cm, 5*cm, 4.5*cm]
)
story.append(gastric_table)

# ── SECTION 6: FUNCTIONAL CLASSIFICATION ──────────────────────────────────────
story.append(spacer())
story.append(section_heading("6.  Functional Classification"))
story.append(spacer())

func_table = make_table(
    ["Tumor", "Hormone", "Syndrome / Presentation"],
    [
        ["Insulinoma", "Insulin", "Hypoglycemia (Whipple's triad)"],
        ["Gastrinoma", "Gastrin", "Zollinger-Ellison syndrome (peptic ulcers, diarrhea, GERD)"],
        ["VIPoma", "VIP", "WDHA syndrome (watery diarrhea, hypokalemia, achlorhydria / Werner-Morrison)"],
        ["Glucagonoma", "Glucagon", "Necrolytic migratory erythema, diabetes, weight loss"],
        ["Somatostatinoma", "Somatostatin", "Steatorrhea, gallstones, hyperglycemia"],
        ["Non-functional", "None / subclinical", "~1/3 of pancreatic NENs; symptoms from mass effect or detected incidentally"],
    ],
    col_widths=[4*cm, 3*cm, 10*cm]
)
story.append(func_table)

# ── SECTION 7: IHC & MARKERS ──────────────────────────────────────────────────
story.append(spacer())
story.append(section_heading("7.  Histology, IHC Markers & Serum Tests"))
story.append(spacer())

story.append(sub_heading("7.1  Histological Features"))
story.append(body(
    "NETs form intramural or submucosal masses, often yellow-tan in color with an intense desmoplastic reaction. "
    "Microscopically: islands, trabeculae, strands, glands, or sheets of uniform cells with <b>scant pink granular cytoplasm</b> "
    "and <b>round-to-oval stippled (\"salt-and-pepper\") nuclei</b>. NECs show large necrotic areas and less nested architecture."
))

story.append(spacer(0.3))
story.append(sub_heading("7.2  Immunohistochemistry Panel"))

ihc_table = make_table(
    ["Marker", "Sensitivity / Specificity", "Notes"],
    [
        ["Synaptophysin", "Most sensitive", "Positive in virtually all NETs and NECs"],
        ["Chromogranin A (CgA)", "Most specific; >90% diagnostic sensitivity", "Can be false-positive with PPI use, renal failure, IBD; used for monitoring therapy"],
        ["Ki-67 (MIB-1)", "Proliferation marker", "Essential for grading; count in hotspots"],
        ["CD56 (NCAM)", "Moderate", "Supplementary neuroendocrine marker"],
        ["SSTR2 / SSTR5", "Variable", "Relevant for somatostatin analog therapy and 68Ga-DOTATATE PET imaging"],
        ["TP53 / RB1", "Molecular marker", "Loss favors NEC over NET G3 when morphology is ambiguous"],
    ],
    col_widths=[4*cm, 5*cm, 8*cm]
)
story.append(ihc_table)

story.append(spacer(0.3))
story.append(sub_heading("7.3  Serum Tumor Markers"))
for b in [
    "<b>Chromogranin A (CgA)</b>: diagnostic sensitivity >90%; elevated in most NENs; used for monitoring therapy response. "
    "False elevations with PPI use, renal dysfunction, IBD, prostate cancer.",
    "<b>24-hour urine 5-HIAA</b> (5-hydroxyindoleacetic acid): specific for serotonin-secreting midgut NETs; key test for carcinoid syndrome.",
    "<b>Specific hormones</b>: fasting serum gastrin (gastrinoma), insulin/C-peptide (insulinoma), VIP (VIPoma), glucagon (glucagonoma).",
    "<b>NSE (neuron-specific enolase)</b>: less specific; can be elevated in poorly differentiated NECs.",
]:
    story.append(bullet(b))

# ── SECTION 8: HISTORICAL EVOLUTION ───────────────────────────────────────────
story.append(spacer())
story.append(section_heading("8.  Historical Evolution of WHO Classification"))
story.append(spacer())

hist_table = make_table(
    ["Year / Edition", "Key Changes"],
    [
        ["WHO 2000", "Introduced grading based on proliferative activity; classified as benign vs. malignant"],
        ["WHO 2010 (4th Edition)", "Formalized mitotic rate/Ki-67 grading (G1/G2); all NETs classified as malignant with metastatic potential; NECs defined as >20 mitoses/2mm²"],
        ["WHO 2017 (Pancreatic NENs)", "Added G3 NET category for pancreatic NENs (Ki-67 >20% but well-differentiated morphology)"],
        ["WHO 2019 (5th Edition – Digestive)", "G3 NET extended to ALL GI/digestive sites; MANEC renamed MiNEN; 'carcinoid' term retired; NEC strictly = poorly differentiated only"],
        ["WHO 2022 (Endocrine/NEN)", "Landmark consolidation — all GEP-NENs plus non-GEP NENs combined into a single framework; molecular criteria incorporated"],
    ],
    col_widths=[4*cm, 13*cm]
)
story.append(hist_table)

# ── SECTION 9: SUMMARY TABLE ──────────────────────────────────────────────────
story.append(PageBreak())
story.append(section_heading("9.  Complete WHO 2019 Classification Summary"))
story.append(spacer())

full_table = make_table(
    ["Category", "ICD-O", "Differentiation", "Grade", "Mitoses/2mm²", "Ki-67", "Behavior"],
    [
        ["NET G1", "8240/3", "Well", "G1", "< 2", "< 3%", "Indolent"],
        ["NET G2", "8249/3", "Well", "G2", "2–20", "3–20%", "Intermediate"],
        ["NET G3", "8249/3", "Well", "G3", "> 20", "> 20%", "Aggressive (but NOT NEC)"],
        ["NEC – Small Cell (SCNEC)", "8041/3", "Poorly", "High (not graded)", "> 20", "> 20%", "Highly aggressive"],
        ["NEC – Large Cell (LCNEC)", "8013/3", "Poorly", "High (not graded)", "> 20", "> 20%", "Highly aggressive"],
        ["MiNEN", "8154/3", "Mixed", "Per component", "Per component", "Per component", "Per highest-grade component"],
    ],
    col_widths=[3.2*cm, 1.8*cm, 2.5*cm, 2.5*cm, 2.5*cm, 2*cm, 2.5*cm]
)
story.append(full_table)

story.append(spacer())
story.append(note(
    "Referring to G3 NETs as 'NECs' is a common but INCORRECT practice per current classification. "
    "G3 NETs have different molecular biology, prognosis, and treatment response compared to NECs. "
    "This distinction is critical for therapeutic decisions — NECs respond to platinum-based chemotherapy "
    "while NET G3 does not. (Reference: Helderman et al., Neuroendocrinology 2024; PMID 37690447)"
))

story.append(spacer())
story.append(hr())
story.append(Paragraph(
    "References: Robbins & Kumar Basic Pathology (Robbins Pathology); Tietz Textbook of Laboratory Medicine 7th Ed; "
    "WHO Classification of Tumours of the Digestive System 5th Ed (2019); WHO Classification of Endocrine and Neuroendocrine Tumours (2022); "
    "Helderman et al. Neuroendocrinology 2024 (PMID 37690447); Qasim et al. Cureus 2026.",
    footer_style
))

# BUILD
doc.build(story)
print("PDF generated:", OUTPUT)
Running Command

cd /home/daytona/workspace/nen-pdf && python generate_nen_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/nen-pdf/NEN_Digestive_System_Classification_Gradi…

Your PDF is ready for download:

NEN Digestive System Classification Grading

PDF Document · PDF

The PDF includes all 9 sections from the previous response, formatted with color-coded tables and clear headings:
  1. Overview & Terminology - NEN umbrella categories
  2. WHO 2019/2022 Grading System - G1/G2/G3 NET grading table + Ki-67 assessment method
  3. NET G3 vs. NEC comparison table - the critical distinction
  4. Neuroendocrine Carcinomas (NECs) - SCNEC vs. LCNEC subtypes
  5. MiNEN - definition, threshold, prognosis driver
  6. Site-Based Classification - Foregut/Midgut/Hindgut + Gastric NET Types 1/2/3
  7. Functional Classification - Insulinoma, Gastrinoma, VIPoma, etc.
  8. Histology, IHC & Serum Markers - synaptophysin, CgA, Ki-67, SSTR2
  9. Historical WHO Evolution (2000 → 2022) + Complete Classification Summary Table
This is a shared conversation. Sign in to Orris to start your own chat.