What is multiple myeloma

Reading File
Finding Sources
Searching PubMed

"multiple myeloma"[MeSH Terms] AND treatment

Reading File
Reading File
Finding Sources
Reading File
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
I now have comprehensive content from authoritative sources. Let me compile the full answer.

Multiple Myeloma

Multiple myeloma is a malignant neoplasm of plasma cells (terminally differentiated B lymphocytes) that infiltrate the bone marrow, secrete a monoclonal immunoglobulin (M protein), and destroy bone. It accounts for about 1% of all malignancies and slightly more than 10% of hematologic malignancies in the United States, with roughly 30,000 new cases diagnosed annually.

Epidemiology

  • Median age at diagnosis: ~65-70 years; only 2% of patients are younger than 40
  • More common in males than females
  • Incidence in Black Americans is nearly twice that in White Americans
  • Environmental exposures (radiation, benzene, organic solvents, herbicides, insecticides) may be contributing factors
  • Familial clustering has been reported
  • Goldman-Cecil Medicine, p. 1977; Robbins & Kumar Basic Pathology, p. 420

Pathogenesis

Origin and Precursor State

Almost all cases evolve from monoclonal gammopathy of undetermined significance (MGUS), a premalignant plasma cell condition. MGUS progresses to myeloma at approximately 1% per year. The main molecular events driving progression from MGUS to myeloma are RAS mutations and MYC abnormalities.

Chromosomal Abnormalities

  • ~40% of cases: Primary IgH locus translocations (chromosome 14q32), fusing IgH to oncogenes such as cyclin D1 or cyclin D3 - this drives increased cell proliferation
  • ~40% of cases: Hyperdiploid myeloma with trisomies (without IgH translocations)
  • ~15% of cases: Both IgH translocations and trisomies
  • Secondary abnormalities (deletion 17p, MYC translocations) arise later and indicate more aggressive disease

Key Growth Factor: IL-6

Interleukin-6 (IL-6), produced mainly by bone marrow stromal fibroblasts and macrophages, is a major growth factor supporting myeloma cell proliferation.

Bone Destruction Mechanism

Myeloma cells cause pure osteolytic disease by:
  1. Upregulating RANKL expression by bone marrow stromal cells, activating osteoclasts
  2. Simultaneously suppressing osteoblasts via IL-3, IL-7, and DKK1
  3. Releasing factors including MIP-1-alpha, SDF-alpha, IL-1 beta, and IL-6
The net result: increased bone resorption (osteoclasts active) without compensatory new bone formation (osteoblasts suppressed).
  • Goldman-Cecil Medicine, p. 1978; Robbins & Kumar Basic Pathology, p. 420-421

Immunoglobulin Production

The M protein type breakdown:
M Protein TypeFrequency
IgG52-60%
IgA20-25%
Light chain only16%
IgD2%
Biclonal2%
Nonsecretory1-3%
Light chain type: kappa (K) in 65%, lambda (λ) in 35%.

Clinical Features - "CRAB" Criteria

The hallmark clinical manifestations are captured by the acronym CRAB:
LetterManifestationMechanism
CHypercalcemiaOsteoclast activation causing bone resorption
RRenal insufficiencyBence Jones protein casts, light chain deposition, hypercalcemia
AAnemiaBone marrow infiltration; present in ~75% at diagnosis
BBone lesions/painLytic lesions, pathologic fractures

Bone Disease

Lesions are typically "punched-out" defects 1-4 cm in diameter, most commonly affecting the vertebral column, ribs, skull, pelvis, femur, clavicle, and scapula. Pathologic fractures most often occur in the vertebral column and femur.

Renal Disease (Myeloma Kidney)

  • Bence Jones protein casts obstruct distal convoluted tubules and collecting ducts, surrounded by multinucleate giant cells
  • Light chain amyloidosis (AL type) deposits in glomeruli
  • Light chain deposition disease can cause nephrotic syndrome
  • Hypercalcemia causes dehydration and renal stones
  • Renal failure occurs in up to 50% of patients and is a leading cause of death

Immunosuppression

Despite elevated total immunoglobulin levels (due to M protein), production of functional antibodies is profoundly depressed. Normal B cells are compromised by mechanisms that remain uncertain. Patients are highly susceptible to bacterial infections, which are a leading cause of death.

Neurologic Complications

  • Radiculopathy (thoracic or lumbosacral) - the most frequent neurologic complication
  • Spinal cord compression occurs in up to 10% of patients
  • Peripheral neuropathy (usually from amyloidosis)
  • Intracranial plasmacytomas (extensions of skull lesions)

Diagnosis

Laboratory Studies

  • Serum protein electrophoresis (SPEP): M protein detected in 80% of patients
  • Serum immunofixation: M protein in 93% of patients
  • SPEP + urine protein electrophoresis + immunofixation combined: 97% detection
  • Serum free light chain assay: Convenient alternative to urine studies
  • CBC: Normocytic normochromic anemia; often leukopenia and thrombocytopenia

Bone Marrow Examination

  • Plasma cells constitute >10% of nucleated cells in 96% of patients
  • Myeloma cells are typically: cytoplasmic Ig+, CD38+, CD45-, CD138+, CD56+; only 20% express CD20
  • Abnormal K/λ ratio (>4:1 for clonal K, or <1:2 for clonal λ) confirms clonality

Imaging

  • Classic finding: "punched-out" lytic bone lesions on plain X-ray
  • MRI, CT, and PET scan are used to assess disease extent
  • PET imaging shows lytic lesions and extramedullary disease, with resolution visible after treatment

Diagnostic Criteria (Goldman-Cecil)

Multiple myeloma is defined by:
  1. ≥10% clonal plasma cells on bone marrow examination
  2. M protein in serum or urine (except nonsecretory myeloma)
  3. Evidence of ≥1 myeloma-defining event (end-organ damage: CRAB features, or high-risk biomarkers)

Staging

The Revised International Staging System (R-ISS) incorporates:
  • Serum beta-2 microglobulin and albumin levels
  • Specific cytogenetic abnormalities (e.g., del 17p, t(4;14), t(14;16))
  • Lactate dehydrogenase (LDH)
Adverse cytogenetic features: del(17p), t(4;14), t(14;16), gain/amplification of 1q, del(1p)

Treatment

Smoldering Myeloma

  • Low/intermediate risk: observation every 3-4 months; no treatment until symptomatic myeloma develops
  • High-risk smoldering myeloma: lenalidomide (25 mg days 1-21 of 28-day cycle) ± low-dose dexamethasone for ~2 years significantly reduces progression risk and improves overall survival

Active Myeloma - Induction Regimens

RegimenAbbreviation
Bortezomib + cyclophosphamide + dexamethasoneVCd
Bortezomib + lenalidomide + dexamethasoneVRd
Carfilzomib + lenalidomide + dexamethasoneKRd
Daratumumab + bortezomib + lenalidomide + dexamethasoneDVRd
Daratumumab + lenalidomide + dexamethasoneDRd

Autologous Stem Cell Transplantation (ASCT)

  • Standard of care after induction for eligible patients
  • Conditioning: melphalan 200 mg/m²
  • Transplant mortality: <1%
  • Stem cells may be collected and cryopreserved, with transplant delayed until first relapse in standard-risk disease - outcomes are comparable to early transplant

Drug Classes

Drug ClassExamplesMechanism
Proteasome inhibitorsBortezomib, carfilzomib, ixazomibBlock protein degradation - myeloma cells accumulate misfolded immunoglobulins and undergo apoptosis
Immunomodulatory drugs (IMiDs)Thalidomide, lenalidomide, pomalidomideAnti-angiogenic, immune stimulation, direct anti-tumor effects
Anti-CD38 monoclonal antibodiesDaratumumab, isatuximabTarget CD38 expressed on plasma cells
Anti-SLAMF7ElotuzumabTargets SLAMF7 on myeloma cells
CorticosteroidsDexamethasoneAnti-inflammatory, direct cytotoxicity to plasma cells

Newer/Emerging Therapies (2024)

Recent meta-analyses confirm the emerging role of CAR T-cell therapy and bispecific antibodies in relapsed/refractory myeloma (3rd line and beyond). CAR T-cell therapy has shown impressive response rates in heavily pretreated patients. [PMID: 39551604]

Prognosis

  • Median survival with modern therapy: approximately 5 years; significantly better in younger patients with standard-risk disease
  • Patients with multiple bony lesions, if untreated, rarely survive more than 6-12 months
  • "Smoldering myeloma" patients may be asymptomatic for many years
  • Disease remains incurable in most patients, though responses can be durable
The key causes of death are:
  1. Infections (due to compromised humoral immunity)
  2. Renal failure

Summary Diagram

MGUS → Smoldering Myeloma → Symptomatic Multiple Myeloma
          (1%/year risk)           (CRAB criteria)
                                        ↓
              Bone marrow: ≥10% clonal plasma cells
              M protein: IgG (52%), IgA (21%), light chain (16%)
              Lytic bone lesions → fractures, hypercalcemia
              Bence Jones proteins → renal failure
              Immune suppression → bacterial infections
                                        ↓
                      VRd / DVRd induction → ASCT
                     Proteasome inhibitors + IMiDs + anti-CD38

Sources: Robbins & Kumar Basic Pathology, pp. 420-423; Goldman-Cecil Medicine (International Ed.), pp. 1977-1982
Recent evidence note: A 2024 meta-analysis (PMID: 39551604) found that CAR T-cell therapy and bispecific antibodies have comparable efficacy as 3rd-line therapy for relapsed/refractory myeloma - both represent important advances over traditional salvage regimens.

Create a summary document on myeloma diagnosis and staging I can share with colleagues

Asking for Preferences
Reading File
Running Command

mkdir -p /home/daytona/workspace/myeloma-summary && ls /home/daytona/workspace/myeloma-summary/

Writing File

~/myeloma-summary/build_pdf.py

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

OUTPUT = "/home/daytona/workspace/myeloma-summary/Multiple_Myeloma_Diagnosis_Staging.pdf"

# ── Colour palette ────────────────────────────────────────────────────────────
NAVY    = HexColor("#1a2e4a")
TEAL    = HexColor("#1a7a8a")
LTBLUE  = HexColor("#e8f4f8")
LTGREY  = HexColor("#f5f5f5")
MIDGREY = HexColor("#cccccc")
WHITE   = colors.white
BLACK   = colors.black
RED     = HexColor("#c0392b")
AMBER   = HexColor("#e67e22")
GREEN   = HexColor("#27ae60")

def make_doc():
    doc = SimpleDocTemplate(
        OUTPUT,
        pagesize=A4,
        leftMargin=2*cm, rightMargin=2*cm,
        topMargin=2.5*cm, bottomMargin=2.5*cm,
        title="Multiple Myeloma – Diagnosis & Staging",
        author="Orris Medical Summary",
        subject="Multiple Myeloma"
    )

    styles = getSampleStyleSheet()

    # Custom paragraph styles
    def S(name, parent='Normal', **kw):
        return ParagraphStyle(name, parent=styles[parent], **kw)

    title_style = S('DocTitle', fontSize=22, textColor=WHITE, alignment=TA_CENTER,
                    fontName='Helvetica-Bold', spaceAfter=4, leading=28)
    subtitle_style = S('DocSub', fontSize=11, textColor=LTBLUE, alignment=TA_CENTER,
                       fontName='Helvetica', spaceAfter=2)
    tagline_style = S('TagLine', fontSize=9, textColor=LTBLUE, alignment=TA_CENTER,
                      fontName='Helvetica-Oblique', spaceAfter=0)

    h1 = S('H1', fontSize=13, textColor=WHITE, fontName='Helvetica-Bold',
           spaceAfter=0, spaceBefore=0, leading=18)
    h2 = S('H2', fontSize=11, textColor=NAVY, fontName='Helvetica-Bold',
           spaceAfter=3, spaceBefore=8, leading=15)
    body = S('Body', fontSize=9.5, textColor=BLACK, fontName='Helvetica',
             spaceAfter=5, leading=14, alignment=TA_JUSTIFY)
    bullet = S('Bullet', fontSize=9.5, textColor=BLACK, fontName='Helvetica',
               spaceAfter=3, leading=13, leftIndent=14, firstLineIndent=-10)
    small = S('Small', fontSize=8, textColor=HexColor("#555555"), fontName='Helvetica-Oblique',
              spaceAfter=3, leading=11)
    table_hdr = S('TblHdr', fontSize=9, textColor=WHITE, fontName='Helvetica-Bold',
                  alignment=TA_CENTER, leading=12)
    table_cell = S('TblCell', fontSize=8.5, textColor=BLACK, fontName='Helvetica',
                   alignment=TA_LEFT, leading=12)
    table_cell_c = S('TblCellC', fontSize=8.5, textColor=BLACK, fontName='Helvetica',
                     alignment=TA_CENTER, leading=12)
    emph = S('Emph', fontSize=9.5, textColor=NAVY, fontName='Helvetica-Bold',
             spaceAfter=5, leading=14)
    note = S('Note', fontSize=8.5, textColor=HexColor("#444444"), fontName='Helvetica-Oblique',
             spaceAfter=4, leading=12, leftIndent=8)

    story = []

    # ── COVER BANNER ─────────────────────────────────────────────────────────
    banner_data = [[Paragraph("MULTIPLE MYELOMA", title_style)],
                   [Paragraph("Diagnosis &amp; Staging – Clinical Reference Summary", subtitle_style)],
                   [Paragraph("For Medical Students &amp; Trainees  |  Based on Goldman-Cecil Medicine &amp; Robbins Pathology", tagline_style)]]
    banner = Table(banner_data, colWidths=[17*cm])
    banner.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,-1), NAVY),
        ('TOPPADDING',    (0,0), (-1,0), 16),
        ('BOTTOMPADDING', (0,2), (-1,-1), 14),
        ('LEFTPADDING',   (0,0), (-1,-1), 12),
        ('RIGHTPADDING',  (0,0), (-1,-1), 12),
    ]))
    story.append(banner)
    story.append(Spacer(1, 0.5*cm))

    # ── Helper: section header ────────────────────────────────────────────────
    def section_header(text):
        tbl = Table([[Paragraph(text, h1)]], colWidths=[17*cm])
        tbl.setStyle(TableStyle([
            ('BACKGROUND', (0,0), (-1,-1), TEAL),
            ('TOPPADDING',    (0,0), (-1,-1), 6),
            ('BOTTOMPADDING', (0,0), (-1,-1), 6),
            ('LEFTPADDING',   (0,0), (-1,-1), 10),
            ('RIGHTPADDING',  (0,0), (-1,-1), 10),
        ]))
        return tbl

    def bullet_item(text):
        return Paragraph(f"• {text}", bullet)

    def sub_bullet(text):
        return Paragraph(f"  – {text}", S('SubBullet', parent='Normal', fontSize=9,
                         fontName='Helvetica', spaceAfter=2, leading=12,
                         leftIndent=24, firstLineIndent=-10, textColor=BLACK))

    # ═══════════════════════════════════════════════════════════════════════════
    # 1. OVERVIEW
    # ═══════════════════════════════════════════════════════════════════════════
    story.append(section_header("1.  OVERVIEW"))
    story.append(Spacer(1, 0.3*cm))

    overview_data = [
        [Paragraph("Definition", emph),
         Paragraph("Malignant neoplasm of clonal plasma cells infiltrating the bone marrow, secreting a monoclonal immunoglobulin (M protein), and causing skeletal destruction.", body)],
        [Paragraph("Incidence", emph),
         Paragraph("~30,000 new cases/year in the US. Accounts for ~1% of all malignancies and >10% of haematologic malignancies.", body)],
        [Paragraph("Demographics", emph),
         Paragraph("Median age at diagnosis 65–70 years; only 2% &lt;40 years. More common in males. Incidence in Black Americans is ~2× that of White Americans.", body)],
        [Paragraph("Precursor", emph),
         Paragraph("Nearly all cases evolve from MGUS (monoclonal gammopathy of undetermined significance), which progresses at ~1%/year.", body)],
    ]
    overview_tbl = Table(overview_data, colWidths=[3.5*cm, 13.5*cm])
    overview_tbl.setStyle(TableStyle([
        ('VALIGN',       (0,0), (-1,-1), 'TOP'),
        ('ROWBACKGROUNDS',(0,0),(-1,-1), [LTGREY, WHITE]),
        ('TOPPADDING',   (0,0), (-1,-1), 5),
        ('BOTTOMPADDING',(0,0), (-1,-1), 5),
        ('LEFTPADDING',  (0,0), (-1,-1), 6),
        ('RIGHTPADDING', (0,0), (-1,-1), 6),
        ('GRID',         (0,0), (-1,-1), 0.25, MIDGREY),
    ]))
    story.append(overview_tbl)
    story.append(Spacer(1, 0.4*cm))

    # ═══════════════════════════════════════════════════════════════════════════
    # 2. M PROTEIN TYPES
    # ═══════════════════════════════════════════════════════════════════════════
    story.append(section_header("2.  M PROTEIN DISTRIBUTION"))
    story.append(Spacer(1, 0.3*cm))

    mp_data = [
        [Paragraph("M Protein Type", table_hdr), Paragraph("Frequency", table_hdr),
         Paragraph("Light Chain", table_hdr), Paragraph("Frequency", table_hdr)],
        ["IgG", "52%", "Kappa (κ)", "65%"],
        ["IgA", "21%", "Lambda (λ)", "35%"],
        ["Light chain only", "16%", "", ""],
        ["IgD", "2%", "", ""],
        ["Biclonal", "2%", "", ""],
        ["Nonsecretory", "1–3%", "", ""],
    ]
    for row in mp_data[1:]:
        for i in range(len(row)):
            if isinstance(row[i], str):
                row[i] = Paragraph(row[i], table_cell_c)

    mp_tbl = Table(mp_data, colWidths=[4.5*cm, 3.5*cm, 5*cm, 3.5*cm])
    mp_tbl.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,0), NAVY),
        ('ROWBACKGROUNDS', (0,1), (-1,-1), [LTGREY, WHITE]),
        ('GRID',       (0,0), (-1,-1), 0.5, MIDGREY),
        ('FONTNAME',   (0,0), (-1,0), 'Helvetica-Bold'),
        ('ALIGN',      (0,0), (-1,-1), 'CENTER'),
        ('VALIGN',     (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING',(0,0), (-1,-1), 4),
        ('SPAN',       (2,3), (3,5)),
    ]))
    story.append(mp_tbl)
    story.append(Spacer(1, 0.4*cm))

    # ═══════════════════════════════════════════════════════════════════════════
    # 3. CLINICAL FEATURES – CRAB
    # ═══════════════════════════════════════════════════════════════════════════
    story.append(section_header('3.  CLINICAL FEATURES – "CRAB" CRITERIA'))
    story.append(Spacer(1, 0.3*cm))

    crab_data = [
        [Paragraph("Letter", table_hdr), Paragraph("Feature", table_hdr),
         Paragraph("Mechanism", table_hdr), Paragraph("Key Points", table_hdr)],
        [Paragraph("C", ParagraphStyle('CRed', parent=styles['Normal'], fontSize=14,
                   fontName='Helvetica-Bold', textColor=RED, alignment=TA_CENTER)),
         Paragraph("Hyper-\ncalcaemia", table_cell_c),
         Paragraph("Osteoclast activation → bone resorption", table_cell),
         Paragraph("Confusion, weakness, lethargy, polyuria, constipation", table_cell)],
        [Paragraph("R", ParagraphStyle('CAmb', parent=styles['Normal'], fontSize=14,
                   fontName='Helvetica-Bold', textColor=AMBER, alignment=TA_CENTER)),
         Paragraph("Renal\ninsufficiency", table_cell_c),
         Paragraph("Bence Jones casts, light chain deposition, hypercalcaemia", table_cell),
         Paragraph("Renal failure in up to 50% of patients; leading cause of death", table_cell)],
        [Paragraph("A", ParagraphStyle('CGrn', parent=styles['Normal'], fontSize=14,
                   fontName='Helvetica-Bold', textColor=TEAL, alignment=TA_CENTER)),
         Paragraph("Anaemia", table_cell_c),
         Paragraph("Bone marrow infiltration by plasma cells", table_cell),
         Paragraph("Normocytic normochromic; present in ~75% at diagnosis", table_cell)],
        [Paragraph("B", ParagraphStyle('CNav', parent=styles['Normal'], fontSize=14,
                   fontName='Helvetica-Bold', textColor=NAVY, alignment=TA_CENTER)),
         Paragraph("Bone\nlesions", table_cell_c),
         Paragraph("RANKL/OPG imbalance → osteoclast activation + osteoblast suppression", table_cell),
         Paragraph("Punched-out lytic lesions; pathologic fractures; bone pain", table_cell)],
    ]
    crab_tbl = Table(crab_data, colWidths=[1.5*cm, 3*cm, 6.5*cm, 6*cm])
    crab_tbl.setStyle(TableStyle([
        ('BACKGROUND',   (0,0), (-1,0), NAVY),
        ('ROWBACKGROUNDS',(0,1),(-1,-1), [LTGREY, WHITE, LTGREY, WHITE]),
        ('GRID',         (0,0), (-1,-1), 0.5, MIDGREY),
        ('ALIGN',        (0,0), (1,-1), 'CENTER'),
        ('VALIGN',       (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING',   (0,0), (-1,-1), 5),
        ('BOTTOMPADDING',(0,0), (-1,-1), 5),
        ('LEFTPADDING',  (0,0), (-1,-1), 6),
    ]))
    story.append(crab_tbl)
    story.append(Spacer(1, 0.3*cm))
    story.append(Paragraph(
        "Additional features: recurrent bacterial infections (depressed normal Ig production), "
        "radiculopathy/spinal cord compression (nerve compression by vertebral lesions), "
        "peripheral neuropathy (usually from AL amyloidosis).",
        note))
    story.append(Spacer(1, 0.3*cm))

    # ═══════════════════════════════════════════════════════════════════════════
    # 4. DIAGNOSTIC CRITERIA
    # ═══════════════════════════════════════════════════════════════════════════
    story.append(section_header("4.  DIAGNOSTIC CRITERIA  (IMWG 2014)"))
    story.append(Spacer(1, 0.3*cm))

    story.append(Paragraph(
        "Multiple myeloma is diagnosed when ALL THREE of the following are met:", body))

    criteria = [
        ("1", "≥10% clonal plasma cells on bone marrow biopsy", TEAL),
        ("2", "Serum and/or urine M protein (except nonsecretory myeloma)", TEAL),
        ("3", "One or more myeloma-defining events (MDE):", TEAL),
    ]
    mde_items = [
        "Hypercalcaemia: serum Ca >0.25 mmol/L above upper limit of normal, or >2.75 mmol/L",
        "Renal insufficiency: creatinine clearance <40 mL/min or serum creatinine >177 μmol/L",
        "Anaemia: Hb >20 g/L below lower limit of normal, or Hb <100 g/L",
        "Bone lesions: one or more lytic lesions on skeletal survey, CT, or PET-CT",
        "Clonal BMPC ≥60% (biomarker MDE)",
        "Serum involved/uninvolved free light chain (FLC) ratio ≥100 (biomarker MDE)",
        "MRI: >1 focal lesion ≥5 mm (biomarker MDE)",
    ]

    criteria_data = []
    for num, text, col in criteria:
        criteria_data.append([
            Paragraph(num, ParagraphStyle('Num', parent=styles['Normal'],
                      fontSize=12, fontName='Helvetica-Bold',
                      textColor=WHITE, alignment=TA_CENTER)),
            Paragraph(text, body)
        ])
    criteria_tbl = Table(criteria_data, colWidths=[1*cm, 16*cm])
    criteria_tbl.setStyle(TableStyle([
        ('BACKGROUND',   (0,0), (0,-1), TEAL),
        ('BACKGROUND',   (1,0), (1,-1), LTBLUE),
        ('GRID',         (0,0), (-1,-1), 0.5, MIDGREY),
        ('VALIGN',       (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING',   (0,0), (-1,-1), 6),
        ('BOTTOMPADDING',(0,0), (-1,-1), 6),
        ('LEFTPADDING',  (1,0), (1,-1), 10),
    ]))
    story.append(criteria_tbl)
    story.append(Spacer(1, 0.15*cm))
    story.append(Paragraph("<b>Myeloma-Defining Events (MDE) include:</b>", emph))
    for item in mde_items:
        story.append(bullet_item(item))
    story.append(Spacer(1, 0.2*cm))

    # Differentiation box
    diff_data = [[
        Paragraph("<b>Differentiating from Precursor States</b>", 
                  ParagraphStyle('DiffHdr', parent=styles['Normal'], fontSize=10,
                                 fontName='Helvetica-Bold', textColor=WHITE)),
    ],[
        Paragraph(
            "<b>MGUS:</b> M protein &lt;30 g/L, clonal BMPC &lt;10%, <i>no</i> MDE or amyloidosis<br/>"
            "<b>Smoldering MM:</b> M protein ≥30 g/L or urine M ≥500 mg/24h or BMPC 10–60%, <i>no</i> MDE<br/>"
            "<b>Active MM:</b> BMPC ≥10% (or biopsy-proven plasmacytoma) <i>plus</i> ≥1 MDE",
            ParagraphStyle('DiffBody', parent=styles['Normal'], fontSize=9,
                           fontName='Helvetica', leading=14, textColor=BLACK)
        )
    ]]
    diff_tbl = Table(diff_data, colWidths=[17*cm])
    diff_tbl.setStyle(TableStyle([
        ('BACKGROUND',   (0,0), (-1,0), NAVY),
        ('BACKGROUND',   (0,1), (-1,1), LTBLUE),
        ('TOPPADDING',   (0,0), (-1,-1), 6),
        ('BOTTOMPADDING',(0,0), (-1,-1), 6),
        ('LEFTPADDING',  (0,0), (-1,-1), 10),
        ('RIGHTPADDING', (0,0), (-1,-1), 10),
        ('BOX',          (0,0), (-1,-1), 0.5, TEAL),
    ]))
    story.append(diff_tbl)
    story.append(Spacer(1, 0.4*cm))

    # ═══════════════════════════════════════════════════════════════════════════
    # 5. INVESTIGATIONS
    # ═══════════════════════════════════════════════════════════════════════════
    story.append(section_header("5.  INVESTIGATIONS"))
    story.append(Spacer(1, 0.3*cm))

    inv_data = [
        [Paragraph("Test", table_hdr), Paragraph("Finding / Purpose", table_hdr),
         Paragraph("Sensitivity", table_hdr)],
        [Paragraph("Serum protein electrophoresis (SPEP)", table_cell),
         Paragraph("M protein spike (paraprotein band)", table_cell),
         Paragraph("80%", table_cell_c)],
        [Paragraph("Serum immunofixation", table_cell),
         Paragraph("Confirms M protein type (more sensitive)", table_cell),
         Paragraph("93%", table_cell_c)],
        [Paragraph("SPEP + urine electrophoresis + immunofixation", table_cell),
         Paragraph("Combined approach for M protein detection", table_cell),
         Paragraph("97%", table_cell_c)],
        [Paragraph("Serum free light chain (FLC) assay", table_cell),
         Paragraph("Convenient alternative to urine studies; κ/λ ratio", table_cell),
         Paragraph("High", table_cell_c)],
        [Paragraph("24-hour urine protein electrophoresis", table_cell),
         Paragraph("Quantifies Bence Jones protein (free light chains)", table_cell),
         Paragraph("—", table_cell_c)],
        [Paragraph("Bone marrow biopsy", table_cell),
         Paragraph(">10% plasma cells; flow cytometry (CD38+, CD138+, CD45−, CD56+); κ/λ clonality", table_cell),
         Paragraph("Definitive", table_cell_c)],
        [Paragraph("Full blood count", table_cell),
         Paragraph("Normocytic normochromic anaemia; leukopenia; thrombocytopenia", table_cell),
         Paragraph("—", table_cell_c)],
        [Paragraph("Biochemistry panel", table_cell),
         Paragraph("Calcium, creatinine, uric acid, LDH, β2-microglobulin, albumin", table_cell),
         Paragraph("—", table_cell_c)],
        [Paragraph("Imaging: skeletal survey (X-ray)", table_cell),
         Paragraph("Punched-out lytic lesions (vertebrae, ribs, skull, pelvis, femur)", table_cell),
         Paragraph("First-line", table_cell_c)],
        [Paragraph("Imaging: whole-body low-dose CT", table_cell),
         Paragraph("More sensitive than X-ray; preferred for bone assessment", table_cell),
         Paragraph("Preferred", table_cell_c)],
        [Paragraph("PET-CT / MRI", table_cell),
         Paragraph("Extramedullary disease, focal bone marrow lesions, treatment response", table_cell),
         Paragraph("Highest", table_cell_c)],
    ]
    inv_tbl = Table(inv_data, colWidths=[5*cm, 9*cm, 3*cm])
    inv_tbl.setStyle(TableStyle([
        ('BACKGROUND',    (0,0), (-1,0), NAVY),
        ('ROWBACKGROUNDS',(0,1),(-1,-1), [LTGREY, WHITE]),
        ('GRID',          (0,0), (-1,-1), 0.5, MIDGREY),
        ('VALIGN',        (0,0), (-1,-1), 'TOP'),
        ('TOPPADDING',    (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING',   (0,0), (-1,-1), 6),
    ]))
    story.append(inv_tbl)
    story.append(Spacer(1, 0.4*cm))

    # ═══════════════════════════════════════════════════════════════════════════
    # PAGE BREAK before staging
    # ═══════════════════════════════════════════════════════════════════════════
    story.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════════════════
    # 6. STAGING – R-ISS
    # ═══════════════════════════════════════════════════════════════════════════
    story.append(section_header("6.  STAGING  –  REVISED INTERNATIONAL STAGING SYSTEM (R-ISS)"))
    story.append(Spacer(1, 0.3*cm))

    riss_data = [
        [Paragraph("Stage", table_hdr), Paragraph("Criteria", table_hdr),
         Paragraph("Median OS", table_hdr)],
        [Paragraph("I", ParagraphStyle('S1', parent=styles['Normal'], fontSize=13,
                   fontName='Helvetica-Bold', textColor=GREEN, alignment=TA_CENTER)),
         Paragraph(
             "• Serum β2-microglobulin &lt;3.5 mg/L<br/>"
             "• Serum albumin ≥35 g/L<br/>"
             "• Standard-risk cytogenetics<br/>"
             "• Normal LDH",
             table_cell),
         Paragraph("~62 months", table_cell_c)],
        [Paragraph("II", ParagraphStyle('S2', parent=styles['Normal'], fontSize=13,
                   fontName='Helvetica-Bold', textColor=AMBER, alignment=TA_CENTER)),
         Paragraph(
             "• Not Stage I or III<br/>"
             "(intermediate — any combination not meeting Stage I or III)",
             table_cell),
         Paragraph("~44 months", table_cell_c)],
        [Paragraph("III", ParagraphStyle('S3', parent=styles['Normal'], fontSize=13,
                   fontName='Helvetica-Bold', textColor=RED, alignment=TA_CENTER)),
         Paragraph(
             "• Serum β2-microglobulin ≥5.5 mg/L<br/>"
             "• PLUS high-risk cytogenetics: del(17p), t(4;14), or t(14;16)<br/>"
             "• OR elevated LDH",
             table_cell),
         Paragraph("~29 months", table_cell_c)],
    ]
    riss_tbl = Table(riss_data, colWidths=[2*cm, 11.5*cm, 3.5*cm])
    riss_tbl.setStyle(TableStyle([
        ('BACKGROUND',    (0,0), (-1,0), NAVY),
        ('BACKGROUND',    (0,1), (-1,1), HexColor("#e8f8ee")),
        ('BACKGROUND',    (0,2), (-1,2), HexColor("#fff8e8")),
        ('BACKGROUND',    (0,3), (-1,3), HexColor("#fdecea")),
        ('GRID',          (0,0), (-1,-1), 0.5, MIDGREY),
        ('ALIGN',         (0,0), (0,-1), 'CENTER'),
        ('ALIGN',         (2,0), (2,-1), 'CENTER'),
        ('VALIGN',        (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING',    (0,0), (-1,-1), 6),
        ('BOTTOMPADDING', (0,0), (-1,-1), 6),
        ('LEFTPADDING',   (1,0), (1,-1), 10),
    ]))
    story.append(riss_tbl)
    story.append(Spacer(1, 0.2*cm))
    story.append(Paragraph(
        "OS = overall survival with modern treatment. Cytogenetics assessed by FISH.",
        note))
    story.append(Spacer(1, 0.4*cm))

    # ═══════════════════════════════════════════════════════════════════════════
    # 7. CYTOGENETICS
    # ═══════════════════════════════════════════════════════════════════════════
    story.append(section_header("7.  CYTOGENETIC ABNORMALITIES"))
    story.append(Spacer(1, 0.3*cm))

    cyto_data = [
        [Paragraph("Abnormality", table_hdr), Paragraph("Type", table_hdr),
         Paragraph("Frequency", table_hdr), Paragraph("Prognosis", table_hdr)],
        [Paragraph("Hyperdiploidy (trisomies)", table_cell), Paragraph("Primary", table_cell_c),
         Paragraph("~40%", table_cell_c), Paragraph("Standard risk", table_cell_c)],
        [Paragraph("IgH translocations (any)", table_cell), Paragraph("Primary", table_cell_c),
         Paragraph("~40%", table_cell_c), Paragraph("Varies by partner", table_cell_c)],
        [Paragraph("t(11;14) – CCND1", table_cell), Paragraph("Primary", table_cell_c),
         Paragraph("~15%", table_cell_c), Paragraph("Standard risk", table_cell_c)],
        [Paragraph("t(4;14) – FGFR3/MMSET", table_cell), Paragraph("Primary", table_cell_c),
         Paragraph("~15%", table_cell_c),
         Paragraph("HIGH RISK", ParagraphStyle('HR', parent=styles['Normal'], fontSize=8.5,
                   fontName='Helvetica-Bold', textColor=RED, alignment=TA_CENTER))],
        [Paragraph("t(14;16) – MAF", table_cell), Paragraph("Primary", table_cell_c),
         Paragraph("~5%", table_cell_c),
         Paragraph("HIGH RISK", ParagraphStyle('HR2', parent=styles['Normal'], fontSize=8.5,
                   fontName='Helvetica-Bold', textColor=RED, alignment=TA_CENTER))],
        [Paragraph("del(17p) – TP53", table_cell), Paragraph("Secondary", table_cell_c),
         Paragraph("~10%", table_cell_c),
         Paragraph("HIGH RISK", ParagraphStyle('HR3', parent=styles['Normal'], fontSize=8.5,
                   fontName='Helvetica-Bold', textColor=RED, alignment=TA_CENTER))],
        [Paragraph("1q gain/amplification", table_cell), Paragraph("Secondary", table_cell_c),
         Paragraph("~40%", table_cell_c),
         Paragraph("HIGH RISK", ParagraphStyle('HR4', parent=styles['Normal'], fontSize=8.5,
                   fontName='Helvetica-Bold', textColor=RED, alignment=TA_CENTER))],
        [Paragraph("MYC translocation", table_cell), Paragraph("Late/Secondary", table_cell_c),
         Paragraph("Variable", table_cell_c), Paragraph("Aggressive disease", table_cell_c)],
    ]
    cyto_tbl = Table(cyto_data, colWidths=[5.5*cm, 3*cm, 3*cm, 5.5*cm])
    cyto_tbl.setStyle(TableStyle([
        ('BACKGROUND',    (0,0), (-1,0), NAVY),
        ('ROWBACKGROUNDS',(0,1),(-1,-1), [LTGREY, WHITE]),
        ('GRID',          (0,0), (-1,-1), 0.5, MIDGREY),
        ('ALIGN',         (1,0), (-1,-1), 'CENTER'),
        ('VALIGN',        (0,0), (-1,-1), 'MIDDLE'),
        ('TOPPADDING',    (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING',   (0,0), (-1,-1), 6),
    ]))
    story.append(cyto_tbl)
    story.append(Spacer(1, 0.4*cm))

    # ═══════════════════════════════════════════════════════════════════════════
    # 8. BONE MARROW FINDINGS
    # ═══════════════════════════════════════════════════════════════════════════
    story.append(section_header("8.  BONE MARROW &amp; HISTOLOGY FINDINGS"))
    story.append(Spacer(1, 0.3*cm))

    bm_blocks = [
        ("Plasma cell percentage",
         ">10% of nucleated cells in 96% of patients. May be focal — repeat biopsy may be needed."),
        ("Morphology",
         "Plasma cells typically eccentric nucleus with 'clock-face' chromatin and basophilic cytoplasm. "
         "Myeloma cells often show prominent nucleoli or cytoplasmic inclusions (Russell bodies — "
         "eosinophilic immunoglobulin aggregates)."),
        ("Immunophenotype",
         "Cytoplasmic Ig+, CD38+, CD138+, CD45−, CD56+. Only 20% express CD20. "
         "Clonality confirmed by abnormal κ/λ ratio (>4:1 kappa or <1:2 lambda)."),
        ("Skeletal lesions",
         "Punched-out lytic defects 1–4 cm. Most commonly: vertebral column, ribs, skull, pelvis, femur, "
         "clavicle, scapula. Arise in medullary cavity and erode cortex."),
        ("Myeloma kidney",
         "Bence Jones protein casts in distal tubules and collecting ducts, surrounded by multinucleate "
         "giant cells. Adjacent epithelial cells may be necrotic. AL amyloidosis may also affect glomeruli."),
    ]
    for label, text in bm_blocks:
        row_data = [[Paragraph(f"<b>{label}</b>", 
                               ParagraphStyle('BML', parent=styles['Normal'], fontSize=9.5,
                               fontName='Helvetica-Bold', textColor=TEAL, leading=13)),
                     Paragraph(text, body)]]
        rt = Table(row_data, colWidths=[4*cm, 13*cm])
        rt.setStyle(TableStyle([
            ('VALIGN',       (0,0), (-1,-1), 'TOP'),
            ('TOPPADDING',   (0,0), (-1,-1), 4),
            ('BOTTOMPADDING',(0,0), (-1,-1), 4),
            ('LEFTPADDING',  (0,0), (-1,-1), 6),
            ('LINEBELOW',    (0,0), (-1,-1), 0.25, MIDGREY),
        ]))
        story.append(rt)
    story.append(Spacer(1, 0.4*cm))

    # ═══════════════════════════════════════════════════════════════════════════
    # 9. PROGNOSIS
    # ═══════════════════════════════════════════════════════════════════════════
    story.append(section_header("9.  PROGNOSIS"))
    story.append(Spacer(1, 0.3*cm))

    prog_data = [
        [Paragraph("Scenario", table_hdr), Paragraph("Median Survival", table_hdr)],
        [Paragraph("Active multiple myeloma (modern treatment)", table_cell),
         Paragraph("~5 years (significantly better in younger, standard-risk patients)", table_cell)],
        [Paragraph("Multiple bony lesions — untreated", table_cell),
         Paragraph("6–12 months", table_cell)],
        [Paragraph("Smoldering myeloma", table_cell),
         Paragraph("May be asymptomatic for many years; ~1%/year progression risk", table_cell)],
        [Paragraph("High-risk cytogenetics (del17p, t(4;14), t(14;16))", table_cell),
         Paragraph("Significantly shorter — R-ISS III median ~29 months", table_cell)],
    ]
    prog_tbl = Table(prog_data, colWidths=[9*cm, 8*cm])
    prog_tbl.setStyle(TableStyle([
        ('BACKGROUND',    (0,0), (-1,0), NAVY),
        ('ROWBACKGROUNDS',(0,1),(-1,-1), [LTGREY, WHITE]),
        ('GRID',          (0,0), (-1,-1), 0.5, MIDGREY),
        ('VALIGN',        (0,0), (-1,-1), 'TOP'),
        ('TOPPADDING',    (0,0), (-1,-1), 5),
        ('BOTTOMPADDING', (0,0), (-1,-1), 5),
        ('LEFTPADDING',   (0,0), (-1,-1), 6),
    ]))
    story.append(prog_tbl)
    story.append(Spacer(1, 0.2*cm))

    cause_data = [[
        Paragraph("Leading causes of death: (1) Bacterial infections — due to suppressed normal antibody production  |  (2) Renal failure — Bence Jones proteinuria and cast nephropathy",
                  ParagraphStyle('CauseBox', parent=styles['Normal'], fontSize=9,
                                 fontName='Helvetica-Bold', textColor=NAVY, leading=14))
    ]]
    cause_tbl = Table(cause_data, colWidths=[17*cm])
    cause_tbl.setStyle(TableStyle([
        ('BACKGROUND',   (0,0), (-1,-1), HexColor("#fdecea")),
        ('BOX',          (0,0), (-1,-1), 1, RED),
        ('TOPPADDING',   (0,0), (-1,-1), 8),
        ('BOTTOMPADDING',(0,0), (-1,-1), 8),
        ('LEFTPADDING',  (0,0), (-1,-1), 10),
    ]))
    story.append(cause_tbl)
    story.append(Spacer(1, 0.4*cm))

    # ═══════════════════════════════════════════════════════════════════════════
    # 10. QUICK REFERENCE
    # ═══════════════════════════════════════════════════════════════════════════
    story.append(section_header("10.  QUICK DIAGNOSTIC APPROACH"))
    story.append(Spacer(1, 0.3*cm))

    steps = [
        ("Step 1", "Suspect myeloma",
         "Unexplained anaemia, bone pain/lytic lesions, hypercalcaemia, renal impairment, "
         "recurrent infections, or elevated total protein in patient >50 years"),
        ("Step 2", "Initial investigations",
         "FBC, U&E, calcium, LDH, albumin; SPEP + serum immunofixation; serum FLC ratio; "
         "urine electrophoresis + immunofixation; skeletal survey / whole-body CT"),
        ("Step 3", "Bone marrow examination",
         "Trephine biopsy + aspirate; flow cytometry for immunophenotype; FISH for cytogenetics"),
        ("Step 4", "Apply diagnostic criteria",
         "BMPC ≥10% + M protein + ≥1 MDE = active MM. If criteria not fully met, "
         "consider smoldering MM or MGUS"),
        ("Step 5", "Stage with R-ISS",
         "β2-microglobulin, albumin, LDH, FISH cytogenetics → Stage I / II / III"),
        ("Step 6", "Assess transplant eligibility",
         "Age, performance status, comorbidities → determines induction regimen and ASCT suitability"),
    ]
    for step, title, detail in steps:
        sd = [[
            Paragraph(step, ParagraphStyle('StepNum', parent=styles['Normal'], fontSize=9,
                      fontName='Helvetica-Bold', textColor=WHITE, alignment=TA_CENTER)),
            Paragraph(f"<b>{title}</b><br/>{detail}",
                      ParagraphStyle('StepBody', parent=styles['Normal'], fontSize=9,
                                     fontName='Helvetica', leading=13, textColor=BLACK))
        ]]
        st = Table(sd, colWidths=[2*cm, 15*cm])
        st.setStyle(TableStyle([
            ('BACKGROUND',   (0,0), (0,-1), TEAL),
            ('BACKGROUND',   (1,0), (1,-1), LTBLUE),
            ('VALIGN',       (0,0), (-1,-1), 'MIDDLE'),
            ('TOPPADDING',   (0,0), (-1,-1), 6),
            ('BOTTOMPADDING',(0,0), (-1,-1), 6),
            ('LEFTPADDING',  (1,0), (1,-1), 10),
            ('LINEBELOW',    (0,0), (-1,-1), 0.5, WHITE),
        ]))
        story.append(st)
    story.append(Spacer(1, 0.5*cm))

    # ── Footer note ───────────────────────────────────────────────────────────
    story.append(HRFlowable(width="100%", thickness=0.5, color=MIDGREY))
    story.append(Spacer(1, 0.15*cm))
    story.append(Paragraph(
        "Sources: Goldman-Cecil Medicine International Edition (2022), pp. 1977–1982  |  "
        "Robbins &amp; Kumar Basic Pathology 10e, pp. 420–423  |  "
        "IMWG Diagnostic Criteria 2014 (Rajkumar et al., Lancet Oncology)  |  "
        "Revised ISS (Palumbo et al., JCO 2015)  |  "
        "Prepared using Orris Medical Knowledge System  –  June 2026",
        ParagraphStyle('Footer', parent=styles['Normal'], fontSize=7.5,
                       fontName='Helvetica-Oblique', textColor=HexColor("#777777"),
                       alignment=TA_CENTER, leading=11)
    ))

    doc.build(story)
    print(f"PDF written to {OUTPUT}")

make_doc()
Running Command

cd /home/daytona/workspace/myeloma-summary && python build_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/myeloma-summary/

Your PDF is ready:

Multiple Myeloma Diagnosis Staging

PDF Document · PDF

The document is a 2-page A4 reference summary covering 10 sections, formatted for easy reading and sharing:
SectionContents
1. OverviewDefinition, incidence, demographics, MGUS precursor
2. M Protein DistributionIgG/IgA/light chain breakdown with frequencies
3. CRAB CriteriaColour-coded table with mechanism and key points per feature
4. Diagnostic CriteriaIMWG 2014 criteria with full MDE list; differentiation from MGUS/smoldering MM
5. InvestigationsAll key tests with sensitivity — SPEP, immunofixation, FLC, bone marrow biopsy, imaging
6. R-ISS StagingStages I/II/III with full criteria and median OS figures
7. CytogeneticsPrimary vs secondary abnormalities with risk classification
8. Bone Marrow FindingsPlasma cell morphology, immunophenotype, myeloma kidney
9. PrognosisSurvival by scenario; leading causes of death highlighted in a red alert box
10. Quick Diagnostic ApproachStep-by-step 6-step pathway from suspicion to staging
Sources cited at the bottom: Goldman-Cecil Medicine, Robbins Pathology, IMWG 2014, and R-ISS (Palumbo et al. 2015).
This is a shared conversation. Sign in to Orris to start your own chat.