Which conditions cause rise in serum igE and also tell me when to consider biologics? what are the indications and absolute contraindications for biologics for treatment of high serum igE . Aslo tell me Which drugs lowers the circulating serum igE levels. If my patients serum ig E is 700 and having recurrent pharyngitis sore throat runny nose what to consider? Also tell me most common cause of High serum ig E among young adult Indian population?

Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Searching the Web

most common cause high serum IgE young adults India allergic disease parasitic

Finding Sources
Finding Sources
Finding Sources
Searching PubMed

elevated serum IgE India prevalence allergy parasitic infection

Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
I now have enough information to provide a comprehensive answer. Let me compile everything.

Elevated Serum IgE: A Comprehensive Overview

Normal IgE Levels

Normal serum total IgE: < 100 IU/mL (some labs use < 150 IU/mL). Levels above this warrant investigation.

1. Conditions Causing Elevated Serum IgE

Allergic/Atopic Diseases (most common in industrialized/semi-urban settings)

  • Allergic rhinitis (hay fever)
  • Bronchial asthma (especially allergic asthma)
  • Atopic dermatitis (eczema)
  • Allergic bronchopulmonary aspergillosis (ABPA) - characteristically very high IgE (>1000 IU/mL), used diagnostically
  • Food allergy / anaphylaxis
  • Urticaria (chronic spontaneous urticaria)
  • Eosinophilic gastroenteritis / eosinophilic esophagitis

Parasitic/Infectious Causes

  • Helminth infections (the primary non-allergic cause worldwide): roundworms (Ascaris), hookworms (Ancylostoma, Necator), Toxocara, Strongyloides, filariasis, Schistosoma, Echinococcus, Paragonimus
  • Tropical pulmonary eosinophilia (TPE) - due to Wuchereria bancrofti/Brugia malayi
  • Visceral larva migrans

Immunodeficiency Syndromes

  • Autosomal Dominant Hyper-IgE Syndrome (AD-HIES, Job's syndrome) - STAT3 mutation; recurrent skin/lung infections, pneumatoceles, facial dysmorphia, retained primary teeth, hyperextensibility, scoliosis - Harrison's 22E
  • Autosomal Recessive Hyper-IgE Syndrome - DOCK8 mutation; severe viral/fungal infections, low T and B lymphocyte counts
  • Omenn syndrome (SCID variant)
  • Wiskott-Aldrich syndrome

Inflammatory/Autoimmune

  • IgG4-related disease (elevated IgG4 and IgE, eosinophilia)
  • Eosinophilic granulomatosis with polyangiitis (Churg-Strauss syndrome)
  • Kimura disease

Malignancy

  • Hodgkin's lymphoma
  • IgE myeloma (rare)
  • Certain T-cell lymphomas

Other

  • HIV infection
  • Graft-versus-host disease (GVHD)
  • Drug hypersensitivity reactions
  • Alcoholic liver disease

2. When to Consider Biologics

Biologics should be considered when:
  1. Moderate-to-severe allergic asthma not adequately controlled on inhaled corticosteroids (ICS) + long-acting beta-agonists (LABA) - Goldman-Cecil Medicine
  2. Patients who cannot stop oral steroids without recurrent uncontrolled bronchospasm (steroid-dependent asthma)
  3. Severe allergic rhinitis refractory to standard therapy
  4. Chronic spontaneous urticaria (CSU) unresponsive to antihistamines
  5. Severe atopic dermatitis not controlled by topical therapy
  6. Eosinophilic asthma with blood eosinophils > 150-300 cells/uL despite maximal ICS therapy
  7. ABPA with persistent elevated IgE and radiologic/clinical activity

3. Biologics Available, Their Indications, and Contraindications

A. Omalizumab (Xolair) - Anti-IgE

  • Mechanism: Humanized monoclonal antibody that binds free circulating IgE, depletes it, and downregulates FceRI (high-affinity IgE receptor) on mast cells and basophils - K.J. Lee's Otolaryngology
  • Indications:
    • Severe persistent allergic asthma, age > 12 years, serum IgE 30-700 IU/mL
    • Chronic spontaneous urticaria (300 mg/month regardless of IgE)
    • Severe allergic rhinitis (clinical trials support benefit)
  • Dosing: Weight- and IgE-level-based; every 2 or 4 weeks subcutaneously
  • Effect on IgE: Decreases free (unbound) IgE; total IgE may paradoxically remain elevated for up to 1 year post-omalizumab (Katzung Pharmacology 16th ed.)
  • Absolute Contraindications:
    • Known hypersensitivity/anaphylaxis to omalizumab
    • Serum IgE < 30 IU/mL or > 700 IU/mL (outside dosing range for asthma indication)
    • Non-allergic asthma
    • Parasitic infections (use caution - may reduce anti-parasite immunity)
  • Adverse effects: Anaphylaxis (monitor 30-60 min post-injection), local site reaction, arteriothrombotic events

B. Mepolizumab (Nucala) - Anti-IL-5

  • Mechanism: Humanized anti-IL-5 antibody; inhibits eosinophil differentiation, maturation, migration, survival
  • Indications: Severe eosinophilic asthma with blood eosinophils > 150 cells/uL; eosinophilic granulomatosis with polyangiitis (Churg-Strauss)
  • Dose: 100 mg SC every 4 weeks
  • Reduces exacerbations ~50%; glucocorticoid-sparing
  • Contraindications: Active/untreated parasitic infections; hypersensitivity

C. Reslizumab (Cinqair) - Anti-IL-5

  • Similar to mepolizumab; 3 mg/kg IV every 4 weeks
  • For severe eosinophilic asthma inadequately controlled on ICS

D. Benralizumab (Fasenra) - Anti-IL-5 Receptor alpha

  • Binds IL-5 receptor alpha; causes near-complete depletion of eosinophils and basophils
  • 30 mg SC every 4-8 weeks; ~50% reduction in exacerbations
  • Contraindications: Hypersensitivity; active helminthic infection

E. Dupilumab (Dupixent) - Anti-IL-4/IL-13 receptor alpha

  • Blocks shared alpha subunit of IL-4 and IL-13 receptor
  • Indications: Moderate-to-severe asthma; moderate-to-severe atopic dermatitis; chronic rhinosinusitis with nasal polyps; eosinophilic esophagitis
  • 300 mg SC every 2 weeks
  • Contraindications: Hypersensitivity to dupilumab

F. Tezepelumab (Tezspire) - Anti-TSLP

  • Human monoclonal antibody against thymic stromal lymphopoietin (TSLP)
  • 210 mg SC every 4 weeks
  • Unique: Effective regardless of blood eosinophil level; broadest biologic for severe asthma
  • Contraindications: Hypersensitivity

General Absolute Contraindications for Biologics (All Classes)

  • Active serious infection (including active parasitic helminthic infection)
  • Known hypersensitivity to the specific biologic
  • Pregnancy (relative for most; dupilumab and others - limited data; individual risk-benefit)
  • Active malignancy (relative)
  • Live vaccines should be administered before starting biologics

4. Drugs That Lower Circulating Serum IgE Levels

DrugMechanismEffect on IgE
OmalizumabBinds free IgEDrastically lowers free IgE; total IgE remains elevated (trapped in IgE-omalizumab complexes) for up to 1 year
Corticosteroids (systemic)Broad immunosuppression, reduces Th2 cytokinesModest reduction in total IgE; primarily reduce inflammatory response
DupilumabBlocks IL-4/IL-13 signaling (which drives IgE class switching)Reduces IgE synthesis over time
CyclosporineSuppresses T-cell function, reduces IL-4/IL-13Reduces IgE in atopic dermatitis
Allergen immunotherapy (AIT)Induces immune tolerance, shifts Th2 to Th1/TregGradually reduces specific and total IgE over years
Anti-helminthic treatmentEradicating parasitic infection removes chronic IgE stimulusNormalizes IgE if parasites were the cause

5. Clinical Scenario: Patient with IgE = 700 IU/mL + Recurrent Pharyngitis, Sore Throat, Runny Nose

What to consider:

Step 1 - Most Likely Diagnosis: Allergic Rhinitis with Post-Nasal Drip

  • IgE of 700 is significantly elevated and fits the allergic range
  • Runny nose + sore throat + recurrent pharyngitis is the classic picture of allergic rhinitis with post-nasal drip - mucus dripping down the posterior pharynx causes chronic pharyngeal irritation and recurrent "pharyngitis"
  • This is often misdiagnosed as recurrent bacterial tonsillitis/pharyngitis and treated with repeated antibiotics

Step 2 - Rule Out/Consider

ConditionWhy considerClue
Allergic rhinitis (primary)Most likelySeasonal or perennial triggers
Helminthic infectionIgE 700 in IndiaEosinophilia, GI symptoms, exposure history
ABPAIgE this high + respiratory symptomsCheck chest X-ray, Aspergillus IgE
Hyper-IgE SyndromeIf recurrent bacterial skin/lung infectionsEczema, pneumatoceles, retained teeth
Chronic sinusitis with nasal polypsConcomitantSmell loss, facial pressure

Recommended Workup

  1. Detailed allergy history - triggers, seasonality, family history of atopy
  2. Eosinophil count (CBC with differential) - eosinophilia points toward allergy or parasites
  3. Specific IgE (RAST/ImmunoCAP) or skin prick test to common aeroallergens (house dust mite, cockroach, mold, pollen) - the most relevant in India
  4. Stool examination / serology for helminthic parasites (Ascaris, hookworm, Toxocara, Strongyloides) if eosinophilia present
  5. Nasal endoscopy - assess for polyps, adenoid hypertrophy, posterior drainage
  6. Total IgE trend over time (is it rising?)

Management

  • If allergic rhinitis confirmed: intranasal corticosteroids (first-line) + antihistamines; saline nasal irrigation
  • Allergen immunotherapy (AIT) if long-term control is needed - this also gradually lowers IgE
  • Treat post-nasal drip specifically: this will resolve the "pharyngitis"
  • If parasitic: appropriate anti-helminthic (albendazole/mebendazole/ivermectin)
  • Omalizumab: consider if severe uncontrolled allergic asthma/rhinitis with IgE in 30-700 range - this patient's IgE of 700 is at the upper limit of the dosing range for omalizumab; it is still eligible for allergic asthma indication but would need weight-based dose calculation

6. Most Common Cause of High Serum IgE in Young Adults in India

Dual etiology:
In rural/semi-urban India: The most common cause is helminthic parasitic infection, particularly:
  • Ascaris lumbricoides (roundworm) - extremely prevalent
  • Hookworm (Ancylostoma duodenale) - common in tropical soil
  • Strongyloides stercoralis
  • Tropical Pulmonary Eosinophilia (TPE) due to filarial species - highly characteristic of the Indian subcontinent
India is a developing-country setting with agrarian populations, poor sanitation in many areas, and warm/humid climate - all of which favor helminthic transmission. As noted in the allergology literature: "In lesser developed, predominantly agrarian countries, parasitic infection is the most common cause of elevated IgE levels."
In urban India (and increasingly pan-India due to westernization/hygiene hypothesis): Allergic rhinitis is becoming the dominant cause, driven by:
  • Urbanization, air pollution, increased indoor allergens (house dust mite, cockroach - the #1 allergen in India)
  • Periplaneta americana (cockroach) is the single most sensitizing aeroallergen in Indian urban populations
  • Prevalence of allergic rhinitis in India is estimated at 20-30% in urban young adults
In young urban Indian adults specifically, the ranking is:
  1. Allergic rhinitis / atopic disease (most common in urban settings)
  2. Helminthic infection (more common in rural/semi-urban)
  3. Bronchial asthma (often co-existing with rhinitis)
  4. Atopic dermatitis
Key clinical pearl for India: Always check a CBC with differential when IgE is elevated. If eosinophilia (> 500/uL) is present alongside elevated IgE, parasitic infection must be actively ruled out before attributing the picture purely to allergy. Both conditions can coexist, and treating the parasite alone may normalize IgE substantially.

Sources: Harrison's Principles of Internal Medicine 22E (2025); Goldman-Cecil Medicine; K.J. Lee's Essential Otolaryngology; Katzung's Basic & Clinical Pharmacology 16th ed.; Fishman's Pulmonary Diseases; WHO/epidemiological data on helminth prevalence in India.

Create a clinical decision flowchart for managing elevated IgE by etiology

Generating Image

Clinical decision flowchart for managing elevated serum IgE by etiology. Professional medical flowchart with clean white background, blue and teal color scheme, clear boxes and arrows. Start at top: "ELEVATED SERUM IgE (>100 IU/mL)" in large bold header box. First branch: "INITIAL WORKUP" box containing: CBC with differential, Eosinophil count, Detailed allergy history, Stool exam/parasitic serology, Specific IgE (RAST/ImmunoCAP), Chest X-ray if respiratory symptoms. Then split into THREE main branches based on etiology: BRANCH 1 (LEFT) - "ALLERGIC/ATOPIC CAUSE" (blue): - Triggers: aeroallergens, food, drugs - Eosinophilia mild-moderate - Specific IgE positive - Sub-boxes: * Allergic Rhinitis → Intranasal steroids + Antihistamines → If severe/refractory → Omalizumab (IgE 30-700) or Allergen Immunotherapy * Allergic Asthma → ICS + LABA → Step up: Add Omalizumab or Dupilumab or Benralizumab/Mepolizumab (if eosinophilic) * Atopic Dermatitis → Topical steroids/calcineurin inhibitors → Dupilumab if moderate-severe * Chronic Urticaria → Antihistamines → Omalizumab 300mg/month if refractory * ABPA → Itraconazole + Prednisolone → Omalizumab adjunct BRANCH 2 (MIDDLE) - "PARASITIC/INFECTIOUS" (green): - Marked eosinophilia (>1000/uL) - Rural/tropical exposure - Stool exam positive / serology positive - Sub-boxes: * Helminthic (Ascaris, Hookworm, Strongyloides) → Albendazole/Mebendazole/Ivermectin → Recheck IgE at 3 months * Tropical Pulmonary Eosinophilia (TPE/Filaria) → Diethylcarbamazine (DEC) → Monitor IgE decline * Toxocara → Albendazole + steroids if visceral involvement * NOTE: Avoid omalizumab until parasites cleared BRANCH 3 (RIGHT) - "IMMUNODEFICIENCY/RARE CAUSES" (orange/red): - Recurrent bacterial/fungal/viral infections - Hyper-IgE Syndrome (HIES/Job's) → STAT3 mutation testing → Prophylactic antibiotics/antifungals, HSCT if AR-HIES - IgG4-Related Disease → Elevated IgG4, steroids first-line, Rituximab if refractory - Malignancy (Hodgkin lymphoma, IgE myeloma) → Oncology referral, chemotherapy - Omenn Syndrome/SCID → HSCT urgently Bottom section: "BIOLOGIC SELECTION GUIDE" summary table: - Omalizumab: IgE 30-700 IU/mL, allergic asthma/CSU/rhinitis - Dupilumab: Atopic dermatitis, asthma, CRSwNP - Mepolizumab/Benralizumab: Eosinophilic asthma, EGPA - Tezepelumab: Severe asthma any phenotype CONTRAINDICATIONS box (red border): Active parasitic infection, IgE outside dosing range (omalizumab), known hypersensitivity, active serious infection, live vaccines within 30 days Footer: "IgE monitoring: Recheck total IgE at 3-6 months. On omalizumab: measure FREE IgE not total IgE"

Clinical Decision Flowchart: Managing Elevated IgE by Etiology
Here is the clinical decision flowchart covering the full management algorithm. A quick walkthrough of the key decision points:
Top - Initial Workup (applies to all) Every patient with IgE > 100 IU/mL starts here: CBC with differential (eosinophil count is your first sorting tool), allergy history, stool exam/parasitic serology, specific IgE testing, and chest X-ray if respiratory symptoms are present.
Three Branches by Etiology
  • Allergic/Atopic (blue) - mild-to-moderate eosinophilia, positive specific IgE, trigger history. Escalate from standard therapy (intranasal steroids, antihistamines, ICS+LABA) to biologics when uncontrolled. Omalizumab is the anchor biologic here (IgE 30-700 IU/mL). Dupilumab for atopic dermatitis and asthma. Eosinophilic asthma gets anti-IL-5 agents.
  • Parasitic/Infectious (green) - marked eosinophilia (often > 1000/uL), tropical/rural exposure. Treat the parasite first (albendazole, ivermectin, DEC for filaria). Recheck IgE at 3 months post-treatment. Do NOT start omalizumab until parasites are cleared - it may reduce anti-parasite immunity.
  • Immunodeficiency/Rare (orange-red) - recurrent bacterial/fungal/viral infections disproportionate to the clinical context. Hyper-IgE syndrome (STAT3/DOCK8 mutations), IgG4-related disease, malignancy, Omenn syndrome. These need subspecialty referral.
Biologic Selection Summary (bottom) A quick reference table matching IgE range and phenotype to the right biologic, plus the contraindications box in red for rapid clinical checking.
Key monitoring note: When a patient is on omalizumab, always measure free IgE, not total IgE - total IgE remains elevated (bound in drug-antibody complexes) for up to 1 year and will be misleading.

Generate a quick reference PDF of IgE-based treatment algorithms

Reading File
Running Command

ls -la /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or missing"

Writing File

~/ige-protocol/generate_ige_pdf.py

#!/usr/bin/env python3
"""
IgE-Based Treatment Algorithm - Quick Reference PDF
Generated using ReportLab
"""

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

OUTPUT = "/home/daytona/workspace/ige-protocol/IgE_Treatment_Algorithm.pdf"

# ── Color palette ──────────────────────────────────────────────────────────────
NAVY      = HexColor("#1a3a5c")
TEAL      = HexColor("#0d7a8a")
LIGHT_BLUE= HexColor("#d6eaf8")
GREEN     = HexColor("#1a6b3c")
LIGHT_GREEN=HexColor("#d5f5e3")
ORANGE    = HexColor("#c0392b")
LIGHT_RED = HexColor("#fde8e8")
AMBER     = HexColor("#d68910")
LIGHT_AMB = HexColor("#fef9e7")
GREY_HDR  = HexColor("#2c3e50")
GREY_LIGHT= HexColor("#f2f3f4")
WHITE     = colors.white
BLACK     = colors.black

# ── Document setup ─────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    leftMargin=15*mm, rightMargin=15*mm,
    topMargin=12*mm, bottomMargin=12*mm,
    title="IgE-Based Treatment Algorithm Quick Reference",
    author="Orris Medical AI",
)

styles = getSampleStyleSheet()

def style(name, parent="Normal", **kwargs):
    return ParagraphStyle(name, parent=styles[parent], **kwargs)

# ── Custom paragraph styles ────────────────────────────────────────────────────
H1 = style("H1", "Heading1", fontSize=17, textColor=WHITE, alignment=TA_CENTER,
           spaceAfter=2, spaceBefore=2)
H2 = style("H2", "Heading2", fontSize=11, textColor=WHITE, alignment=TA_LEFT,
           spaceAfter=1, spaceBefore=1)
H3 = style("H3", "Heading3", fontSize=9.5, textColor=NAVY, spaceBefore=3, spaceAfter=2)
BODY = style("BODY", fontSize=8.2, leading=12, spaceAfter=2)
BODY_SM = style("BODY_SM", fontSize=7.5, leading=11, spaceAfter=1)
BOLD = style("BOLD", fontSize=8.2, leading=12, fontName="Helvetica-Bold")
CAPTION = style("CAPTION", fontSize=7.2, textColor=HexColor("#555555"), leading=10)
RED_BOLD = style("RED_BOLD", fontSize=8.2, textColor=ORANGE, fontName="Helvetica-Bold")
GREEN_BOLD = style("GREEN_BOLD", fontSize=8.2, textColor=GREEN, fontName="Helvetica-Bold")

W = A4[0] - 30*mm  # usable width

story = []

# ══════════════════════════════════════════════════════════════════════════════
# HEADER BANNER
# ══════════════════════════════════════════════════════════════════════════════
header_data = [[
    Paragraph("<b>IgE-Based Treatment Algorithm</b><br/>"
              "<font size=9>Quick Reference Card for Clinical Practice</font>", H1)
]]
header_tbl = Table(header_data, colWidths=[W])
header_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), NAVY),
    ("ROWPADDING", (0,0), (-1,-1), 8),
    ("BOX", (0,0), (-1,-1), 0.5, TEAL),
]))
story.append(header_tbl)
story.append(Spacer(1, 4*mm))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 1 — NORMAL VALUES & CLASSIFICATION
# ══════════════════════════════════════════════════════════════════════════════
def section_header(title, bg=TEAL):
    tbl = Table([[Paragraph(f"<b>{title}</b>", H2)]], colWidths=[W])
    tbl.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("ROWPADDING", (0,0), (-1,-1), 5),
        ("BOX", (0,0), (-1,-1), 0.3, WHITE),
    ]))
    return tbl

story.append(section_header("1.  Normal IgE Values & Interpretation"))
story.append(Spacer(1, 2*mm))

ige_class_data = [
    [Paragraph("<b>Serum IgE (IU/mL)</b>", BOLD),
     Paragraph("<b>Interpretation</b>", BOLD),
     Paragraph("<b>Common Context</b>", BOLD)],
    ["< 10",      "Very low",          "Possible IgE deficiency; recurrent infections"],
    ["10 – 100",  "Normal",            "Healthy adults"],
    ["100 – 500", "Mildly elevated",   "Mild atopy, early sensitisation, low helminth load"],
    ["500 – 2000","Moderately elevated","Active allergy, moderate helminthic infection, ABPA"],
    ["> 2000",    "Markedly elevated", "Hyper-IgE syndrome, heavy helminthiasis, ABPA flare"],
    ["> 10 000",  "Very high",         "Severe HIES (Job's), ABPA, heavy parasitic burden"],
]
t = Table(ige_class_data, colWidths=[W*0.20, W*0.28, W*0.52])
t.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREY_HDR),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",   (0,0), (-1,-1), 8),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID", (0,0), (-1,-1), 0.3, HexColor("#cccccc")),
    ("ROWPADDING", (0,0), (-1,-1), 4),
    ("ALIGN", (0,0), (0,-1), "CENTER"),
]))
story.append(t)
story.append(Spacer(1, 4*mm))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 2 — INITIAL WORKUP ALGORITHM
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("2.  Initial Workup When IgE > 100 IU/mL"))
story.append(Spacer(1, 2*mm))

workup_steps = [
    ["Step", "Investigation", "Purpose / Key Finding"],
    ["1", "CBC with differential + absolute eosinophil count",
     "Eosinophils >500/µL → allergy or parasite; >1500/µL → helminthic or HIES"],
    ["2", "Detailed allergy history (triggers, seasonality, family history)",
     "Guides specific IgE panel selection"],
    ["3", "Specific IgE (ImmunoCAP/RAST) or skin-prick test",
     "Identifies sensitising allergen (HDM, cockroach, mold, food, drug)"],
    ["4", "Stool microscopy × 3 + Strongyloides / Toxocara serology",
     "Mandatory in India/tropical settings; rules out helminthic cause"],
    ["5", "Chest X-ray / CT chest (if respiratory symptoms)",
     "Central bronchiectasis/mucus plugging → ABPA; pneumatoceles → HIES"],
    ["6", "Aspergillus-specific IgE + Aspergillus precipitins",
     "If IgE >1000 + asthma → rule out ABPA"],
    ["7", "IgG4 level (if multi-organ involvement, eosinophilia)",
     "IgG4-related disease: elevated IgG4 + IgE + eosinophilia"],
    ["8", "STAT3 / DOCK8 genetic testing (if recurrent bacterial/viral infections)",
     "Hyper-IgE Syndrome (AD-HIES/AR-HIES)"],
]
tw = [W*0.06, W*0.38, W*0.56]
wt = Table(workup_steps, colWidths=tw)
wt.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREY_HDR),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",   (0,0), (-1,-1), 7.8),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID", (0,0), (-1,-1), 0.3, HexColor("#cccccc")),
    ("ROWPADDING", (0,0), (-1,-1), 4),
    ("ALIGN", (0,0), (0,-1), "CENTER"),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(wt)
story.append(Spacer(1, 4*mm))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 3 — TREATMENT BY ETIOLOGY (3-column layout)
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("3.  Treatment Algorithm by Etiology"))
story.append(Spacer(1, 2*mm))

col_w = (W - 4*mm) / 3

def etiology_box(title, bg, items):
    """Create a coloured etiology column."""
    hdr = Table([[Paragraph(f"<b>{title}</b>",
                            style("eh", fontSize=9, textColor=WHITE, alignment=TA_CENTER))]],
                colWidths=[col_w])
    hdr.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("ROWPADDING", (0,0), (-1,-1), 5),
    ]))
    rows = [[hdr]]
    for bullet, text in items:
        rows.append([Paragraph(f"<b>{bullet}</b> {text}",
                               style("eb", fontSize=7.6, leading=11, leftIndent=4))])
    inner = Table(rows, colWidths=[col_w])
    inner.setStyle(TableStyle([
        ("BOX", (0,0), (-1,-1), 0.5, bg),
        ("ROWPADDING", (0,1), (-1,-1), 3),
        ("VALIGN", (0,0), (-1,-1), "TOP"),
    ]))
    return inner

allergic_items = [
    ("Allergic Rhinitis:", "1st line: Intranasal corticosteroids + 2nd-gen antihistamine + saline irrigation"),
    ("→ Refractory:", "Allergen immunotherapy (AIT) — lowers IgE long-term"),
    ("→ Severe:", "Omalizumab (IgE 30–700 IU/mL) — every 2–4 weeks SC"),
    ("Allergic Asthma:", "Step 1–3: SABA + ICS ± LABA"),
    ("→ Step 4–5:", "Add Omalizumab (allergic) or Mepolizumab/Benralizumab (eosinophilic) or Dupilumab or Tezepelumab"),
    ("Atopic Dermatitis:", "Mild: topical steroids / calcineurin inhibitors"),
    ("→ Moderate–Severe:", "Dupilumab 300 mg SC q2w"),
    ("Chronic Urticaria:", "Antihistamine (up to 4×) → Omalizumab 300 mg/month"),
    ("ABPA:", "Prednisolone + Itraconazole; Omalizumab adjunct if refractory"),
    ("Eosinophilic Esophagitis:", "PPI + topical steroids → Dupilumab"),
]

parasitic_items = [
    ("⚠ Key clue:", "Eosinophils >1000/µL + tropical exposure + rural/India"),
    ("Ascaris/Hookworm:", "Albendazole 400 mg single dose; repeat in 2 weeks"),
    ("Strongyloides:", "Ivermectin 200 µg/kg × 2 days (preferred over albendazole)"),
    ("Toxocara (VLM):", "Albendazole 400 mg BD × 5 days + steroids if severe"),
    ("TPE (Filaria):", "Diethylcarbamazine (DEC) 6 mg/kg/day × 3 weeks"),
    ("Schistosoma:", "Praziquantel 40 mg/kg single dose"),
    ("Echinococcus:", "Albendazole + surgery/PAIR procedure"),
    ("Monitor:", "Recheck total IgE at 3 months post-treatment"),
    ("Biologic use:", "Avoid omalizumab until parasites are cleared — may impair anti-parasite immunity"),
]

rare_items = [
    ("AD-HIES (Job's):", "STAT3 mutation; recurrent bacterial/fungal infections, pneumatoceles, retained teeth"),
    ("Treatment:", "Prophylactic TMP-SMX + antifungal (voriconazole/itraconazole); avoid live vaccines"),
    ("AR-HIES (DOCK8):", "Severe viral infections; indication for HSCT"),
    ("IgG4-RD:", "Oral prednisolone 0.5–1 mg/kg; Rituximab if refractory"),
    ("EGPA:", "High-dose steroids + cyclophosphamide; Mepolizumab for eosinophilic phase"),
    ("Hodgkin Lymphoma:", "Oncology referral; chemotherapy (ABVD/BEV-ABVD)"),
    ("IgE Myeloma:", "Haematology referral; standard myeloma protocols"),
    ("Omenn SCID:", "Urgent HSCT — IgE extremely high (>10,000)"),
]

etiology_table = Table(
    [[etiology_box("ALLERGIC / ATOPIC", TEAL, allergic_items),
      Spacer(2*mm, 1),
      etiology_box("PARASITIC / INFECTIOUS", GREEN, parasitic_items),
      Spacer(2*mm, 1),
      etiology_box("IMMUNODEFICIENCY / RARE", ORANGE, rare_items)]],
    colWidths=[col_w, 2*mm, col_w, 2*mm, col_w]
)
etiology_table.setStyle(TableStyle([
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(etiology_table)
story.append(Spacer(1, 4*mm))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 4 — BIOLOGIC SELECTION GUIDE
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("4.  Biologic Selection Guide"))
story.append(Spacer(1, 2*mm))

bio_data = [
    ["Biologic", "Target", "IgE Requirement", "Approved Indications", "Dose & Route", "Key Adverse Effects"],
    ["Omalizumab\n(Xolair)", "Free IgE\n(anti-IgE)", "30–700 IU/mL\nfor asthma indication;\nCSU: any IgE",
     "Allergic asthma (≥12yr)\nChronic spontaneous urticaria\nAllergic rhinitis (trials)",
     "Weight + IgE-based\nSC every 2–4 weeks\n(CSU: 300 mg/month)",
     "Anaphylaxis (monitor 30–60 min)\nLocal site reaction\nArteriothrombotic events"],
    ["Dupilumab\n(Dupixent)", "IL-4Rα\n(blocks IL-4 + IL-13)", "No IgE threshold\nrequired",
     "Moderate–severe atopic dermatitis\nModerate–severe asthma\nCRSwNP\nEosinophilic esophagitis",
     "300 mg SC q2w\n(loading 600 mg)",
     "Conjunctivitis\nInjection site reaction\nEosinophilia (transient)"],
    ["Mepolizumab\n(Nucala)", "IL-5\n(anti-IL-5)", "Not IgE-based;\neosinophils ≥150/µL",
     "Severe eosinophilic asthma\nEGPA (Churg-Strauss)\nHypereosinophilic syndrome",
     "100 mg SC q4w",
     "Anaphylaxis\nAngioedema\nHeadache"],
    ["Benralizumab\n(Fasenra)", "IL-5Rα\n(anti-IL-5 receptor)", "Not IgE-based;\neosinophils ≥300/µL preferred",
     "Severe eosinophilic asthma",
     "30 mg SC q4w × 3\nthen q8w",
     "Hypersensitivity\nNasopharyngitis"],
    ["Reslizumab\n(Cinqair)", "IL-5\n(anti-IL-5)", "Not IgE-based;\neosinophils ≥400/µL",
     "Severe eosinophilic asthma",
     "3 mg/kg IV q4w",
     "Anaphylaxis (IV infusion)\nMuscle pain"],
    ["Tezepelumab\n(Tezspire)", "TSLP\n(anti-TSLP)", "No IgE/eosinophil\nthreshold required",
     "Severe asthma (any phenotype)\n— broadest biologic",
     "210 mg SC q4w",
     "Pharyngitis\nBack pain\nInjection site reaction"],
]

bio_cw = [W*0.11, W*0.10, W*0.14, W*0.26, W*0.19, W*0.20]
bt = Table(bio_data, colWidths=bio_cw)
bt.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREY_HDR),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",   (0,0), (-1,-1), 7.2),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID", (0,0), (-1,-1), 0.3, HexColor("#cccccc")),
    ("ROWPADDING", (0,0), (-1,-1), 4),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    # Highlight omalizumab row
    ("BACKGROUND", (0,1), (-1,1), LIGHT_BLUE),
    # Highlight tezepelumab row (broadest)
    ("BACKGROUND", (0,6), (-1,6), LIGHT_AMB),
]))
story.append(bt)
story.append(Spacer(1, 4*mm))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 5 — ABSOLUTE CONTRAINDICATIONS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("5.  Absolute / Important Contraindications to Biologics", bg=ORANGE))
story.append(Spacer(1, 2*mm))

contra_data = [
    ["Contraindication", "Applies To", "Rationale"],
    ["Known hypersensitivity / anaphylaxis to the biologic",
     "All biologics", "Class effect; alternate agent required"],
    ["Active helminthic/parasitic infection",
     "All (especially omalizumab)", "May impair protective IgE-mediated anti-parasite immunity; treat parasites first"],
    ["Serum IgE < 30 or > 700 IU/mL (asthma indication)",
     "Omalizumab (asthma)", "Outside validated dosing range; dose cannot be accurately calculated"],
    ["Non-allergic (intrinsic) asthma with normal IgE",
     "Omalizumab", "Mechanism of action requires allergen-IgE pathway"],
    ["Active serious bacterial/viral/fungal infection",
     "All biologics", "Immunomodulation may worsen active infection"],
    ["Live vaccines within 30 days prior to initiation",
     "All biologics (esp. dupilumab)", "Risk of disseminated vaccine-strain infection"],
    ["Active malignancy (relative — case-by-case)",
     "All biologics", "Insufficient safety data; Th2 shift may promote some tumour progression"],
    ["Pregnancy (relative — insufficient data for most)",
     "All biologics", "Risk-benefit discussion required; omalizumab has most data (category B-like)"],
]
cc = [W*0.35, W*0.23, W*0.42]
ct = Table(contra_data, colWidths=cc)
ct.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), HexColor("#7b241c")),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",   (0,0), (-1,-1), 7.5),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_RED]),
    ("GRID", (0,0), (-1,-1), 0.3, HexColor("#cccccc")),
    ("ROWPADDING", (0,0), (-1,-1), 4),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(ct)
story.append(Spacer(1, 4*mm))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 6 — DRUGS THAT LOWER IgE + MONITORING
# ══════════════════════════════════════════════════════════════════════════════
left_w = W * 0.53
right_w = W * 0.45

# Left: Drugs lowering IgE
lower_data = [
    [Paragraph("<b>Drugs / Interventions That Lower Serum IgE</b>",
               style("lh", fontSize=9, textColor=WHITE, alignment=TA_CENTER))],
]
lower_tbl = Table(lower_data, colWidths=[left_w])
lower_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), TEAL),
    ("ROWPADDING", (0,0), (-1,-1), 5),
]))

lower_rows = [
    ["Drug / Intervention", "Effect on IgE", "Notes"],
    ["Omalizumab", "↓ Free IgE dramatically\n(total IgE rises paradoxically)", "Total IgE stays elevated up to 1 yr after stopping — measure FREE IgE on treatment"],
    ["Allergen Immunotherapy (AIT)", "Gradual ↓ specific + total IgE over 3–5 yrs", "Only intervention with long-term remission"],
    ["Dupilumab", "Slow ↓ IgE synthesis (blocks IL-4/IL-13 class switch)", "IgE falls over months; not primarily an IgE-lowering drug"],
    ["Systemic corticosteroids", "Modest ↓ via Th2 suppression", "Short-term effect; not suitable long-term"],
    ["Cyclosporine", "↓ IgE in atopic dermatitis via T-cell suppression", "Second-line for atopic dermatitis"],
    ["Anti-helminthic treatment", "Normalises IgE if parasites were driving it", "Recheck IgE at 3 months post-treatment"],
]
lt = Table(lower_rows, colWidths=[left_w*0.28, left_w*0.34, left_w*0.38])
lt.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREY_HDR),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",   (0,0), (-1,-1), 7.2),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID", (0,0), (-1,-1), 0.3, HexColor("#cccccc")),
    ("ROWPADDING", (0,0), (-1,-1), 3.5),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))

# Right: Monitoring
monitor_data = [
    [Paragraph("<b>Monitoring Protocol</b>",
               style("mh", fontSize=9, textColor=WHITE, alignment=TA_CENTER))],
]
monitor_tbl = Table(monitor_data, colWidths=[right_w])
monitor_tbl.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), NAVY),
    ("ROWPADDING", (0,0), (-1,-1), 5),
]))

monitor_items = [
    ("Baseline:", "Total IgE + specific IgE + CBC with eosinophils"),
    ("On biologic therapy:", "Absolute eosinophil count every 3 months"),
    ("Omalizumab:", "Measure FREE IgE (not total) to assess response\nTotal IgE unreliable for up to 1 year"),
    ("IgE re-check:", "Every 3–6 months during treatment\nAnnually once stable"),
    ("Response criteria:", "≥25% fall in total IgE (ABPA protocol)\nClinical symptom improvement"),
    ("Skin testing:", "Wait ≥8 weeks after stopping omalizumab before skin-prick testing — drug affects wheal/flare"),
    ("India-specific:", "Always re-check stool exam if IgE fails to fall\nCo-infection with helminth is common"),
]
mon_rows = [[Paragraph(f"<b>{k}</b>", style("mk", fontSize=7.5, leading=10)),
             Paragraph(v, style("mv", fontSize=7.5, leading=10))]
            for k, v in monitor_items]
mt = Table([[monitor_tbl]] + [[Table(mon_rows, colWidths=[right_w*0.28, right_w*0.72],
    style=TableStyle([
        ("FONTSIZE",   (0,0), (-1,-1), 7.5),
        ("ROWBACKGROUNDS", (0,0), (-1,-1), [WHITE, GREY_LIGHT]),
        ("GRID", (0,0), (-1,-1), 0.3, HexColor("#cccccc")),
        ("ROWPADDING", (0,0), (-1,-1), 3.5),
        ("VALIGN", (0,0), (-1,-1), "TOP"),
    ]))]],
    colWidths=[right_w]
)
mt.setStyle(TableStyle([
    ("BOX", (0,0), (-1,-1), 0.5, NAVY),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))

combined = Table(
    [[Table([[lower_tbl], [lt]], colWidths=[left_w],
            style=TableStyle([("VALIGN",(0,0),(-1,-1),"TOP"),("BOX",(0,0),(-1,-1),0.5,TEAL)])),
      Spacer(2*mm, 1),
      mt]],
    colWidths=[left_w, 2*mm, right_w]
)
combined.setStyle(TableStyle([("VALIGN",(0,0),(-1,-1),"TOP")]))
story.append(section_header("6.  Drugs That Lower IgE  &  Monitoring Protocol"))
story.append(Spacer(1, 2*mm))
story.append(combined)
story.append(Spacer(1, 4*mm))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 7 — CLINICAL SCENARIO ALGORITHM (IgE 700 + pharyngitis + rhinitis)
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("7.  Clinical Algorithm: IgE = 700 IU/mL + Recurrent Pharyngitis + Rhinitis"))
story.append(Spacer(1, 2*mm))

scenario_data = [
    ["Step", "Action", "Expected Finding / Next Step"],
    ["1. Clinical assessment",
     "Characterise symptoms: seasonal vs perennial?\nTriggered by dust, pollen, cockroach?\nGI symptoms? Travel/rural exposure?\nSkin changes (eczema)?",
     "Seasonal → pollen allergy\nPerennial → HDM, cockroach (most common in India)\nGI symptoms → consider helminth co-infection"],
    ["2. CBC + differential",
     "Eosinophil count",
     "Eos <500/µL → allergic rhinitis likely\nEos >1000/µL → rule out helminthic infection FIRST"],
    ["3. Specific IgE / Skin test",
     "Test for: HDM (D. pteronyssinus/D. farinae), cockroach\n(Periplaneta americana), Alternaria, Aspergillus, food panel",
     "Positive specific IgE confirms allergen(s)\nCockroach IgE most commonly positive in urban India"],
    ["4. Stool exam × 3 + serology",
     "Strongyloides IgG ELISA, Toxocara IgG, Ascaris IgG",
     "If positive → treat parasite first; recheck IgE in 3 months before biologic decision"],
    ["5. Diagnose + treat primary cause",
     "Allergic rhinitis + post-nasal drip:\n→ Intranasal fluticasone/mometasone daily\n→ Cetirizine/loratadine 10 mg OD\n→ Saline nasal irrigation BD",
     "Post-nasal drip is the cause of recurrent 'pharyngitis'\nNo antibiotics needed for this — treat rhinitis"],
    ["6. Escalation if uncontrolled",
     "Allergen immunotherapy (AIT) for long-term remission\nIf severe asthma develops → Omalizumab\n(IgE 700 is at upper limit of dosing range — eligible)",
     "Omalizumab dose at IgE 700: weight-based (use online calculator)\nAlso treats allergic rhinitis (clinical trial evidence)"],
    ["7. Biologic eligibility check",
     "Omalizumab: IgE must be 30–700 IU/mL ✓\nAge ≥12 years ✓\nSensitisation to perennial allergen confirmed ✓\nNo active parasitic infection ✓",
     "Patient is ELIGIBLE for omalizumab IF:\n• Moderate–severe persistent allergic asthma present\n• ICS + LABA insufficient control\n• No active helminthic infection"],
]

sc_cw = [W*0.18, W*0.40, W*0.42]
sct = Table(scenario_data, colWidths=sc_cw)
sct.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREY_HDR),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",   (0,0), (-1,-1), 7.5),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID", (0,0), (-1,-1), 0.3, HexColor("#cccccc")),
    ("ROWPADDING", (0,0), (-1,-1), 4.5),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("BACKGROUND", (0,6), (-1,6), LIGHT_BLUE),  # highlight biologic row
]))
story.append(sct)
story.append(Spacer(1, 4*mm))

# ══════════════════════════════════════════════════════════════════════════════
# SECTION 8 — INDIA-SPECIFIC KEY POINTS
# ══════════════════════════════════════════════════════════════════════════════
story.append(section_header("8.  India-Specific Considerations (Young Adult Population)", bg=AMBER))
story.append(Spacer(1, 2*mm))

india_points = [
    ("#1 Cause – Urban India:", "Allergic rhinitis (sensitised to house dust mite + cockroach). Cockroach (Periplaneta americana) is the single most common sensitising aeroallergen in Indian urban adults."),
    ("#1 Cause – Rural/Semi-urban India:", "Helminthic parasitic infection (Ascaris, hookworm, Strongyloides) — warm humid climate + agrarian soil contact = high transmission. Always rule out before biologic therapy."),
    ("Dual Cause:", "Both allergy AND parasite can coexist. Treat helminth first; IgE may fall significantly — may alter biologic eligibility."),
    ("Tropical Pulmonary Eosinophilia (TPE):", "Filarial infection (Wuchereria bancrofti/Brugia malayi) — classical triad: nocturnal cough + wheeze + eosinophilia >3000/µL + IgE very high. Treat with Diethylcarbamazine (DEC)."),
    ("Hygiene Hypothesis:", "Rapidly urbanising India shows rising atopic prevalence as helminth burden falls. Young adults in metros have allergy rates approaching Western countries (20–30%)."),
    ("Biologic Access:", "Omalizumab and dupilumab available in India but expensive. RAST/ImmunoCAP testing available at tertiary centres. AIT is cost-effective long-term alternative."),
    ("Important Pitfall:", "Recurrent 'pharyngitis' in young Indians with high IgE is most often allergic post-nasal drip — NOT recurrent streptococcal infection. Avoid repeated antibiotic courses; treat rhinitis."),
]

india_rows = [[Paragraph(f"<b>{k}</b>", style("ik", fontSize=7.8, textColor=NAVY, leading=11)),
               Paragraph(v, style("iv", fontSize=7.8, leading=11))]
              for k, v in india_points]
it = Table(india_rows, colWidths=[W*0.28, W*0.72])
it.setStyle(TableStyle([
    ("ROWBACKGROUNDS", (0,0), (-1,-1), [LIGHT_AMB, WHITE]),
    ("GRID", (0,0), (-1,-1), 0.3, HexColor("#cccccc")),
    ("ROWPADDING", (0,0), (-1,-1), 4),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(it)
story.append(Spacer(1, 4*mm))

# ══════════════════════════════════════════════════════════════════════════════
# FOOTER
# ══════════════════════════════════════════════════════════════════════════════
story.append(HRFlowable(width=W, thickness=0.5, color=TEAL))
story.append(Spacer(1, 2*mm))
footer_txt = (
    "<b>Sources:</b> Harrison's Principles of Internal Medicine 22E (2025, McGraw Hill) · "
    "Goldman-Cecil Medicine International Edition · K.J. Lee's Essential Otolaryngology · "
    "Katzung's Basic & Clinical Pharmacology 16th Ed. · Fishman's Pulmonary Diseases · "
    "Murray & Nadel's Textbook of Respiratory Medicine · Fitzpatrick's Dermatology 9th Ed.  |  "
    "<b>Generated by Orris Medical AI · May 2026</b>  |  "
    "<i>For clinical guidance only. Verify doses against current product labelling and institutional protocols.</i>"
)
story.append(Paragraph(footer_txt, style("FT", fontSize=6.5, textColor=HexColor("#666666"), leading=9)))

# ══════════════════════════════════════════════════════════════════════════════
# BUILD
# ══════════════════════════════════════════════════════════════════════════════
doc.build(story)
print(f"PDF generated: {OUTPUT}")
Running Command

cd /home/daytona/workspace/ige-protocol && python3 generate_ige_pdf.py 2>&1

Editing File

~/ige-protocol/generate_ige_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/ige-protocol/generate_ige_pdf.py'
Running Command

cd /home/daytona/workspace/ige-protocol && python3 generate_ige_pdf.py 2>&1

Writing File

~/ige-protocol/generate_ige_pdf.py

#!/usr/bin/env python3
"""
IgE-Based Treatment Algorithm - Quick Reference PDF
"""

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

OUTPUT = "/home/daytona/workspace/ige-protocol/IgE_Treatment_Algorithm.pdf"

# Colors
NAVY       = HexColor("#1a3a5c")
TEAL       = HexColor("#0d7a8a")
LIGHT_BLUE = HexColor("#d6eaf8")
GREEN      = HexColor("#1a6b3c")
LIGHT_GREEN= HexColor("#d5f5e3")
ORANGE     = HexColor("#c0392b")
LIGHT_RED  = HexColor("#fde8e8")
AMBER      = HexColor("#d68910")
LIGHT_AMB  = HexColor("#fef9e7")
GREY_HDR   = HexColor("#2c3e50")
GREY_LIGHT = HexColor("#f2f3f4")
WHITE      = colors.white

W = A4[0] - 30*mm  # usable page width

doc = SimpleDocTemplate(
    OUTPUT, pagesize=A4,
    leftMargin=15*mm, rightMargin=15*mm,
    topMargin=12*mm, bottomMargin=12*mm,
    title="IgE-Based Treatment Algorithm Quick Reference",
    author="Orris Medical AI",
)

styles = getSampleStyleSheet()

def ps(name, **kw):
    return ParagraphStyle(name, parent=styles["Normal"], **kw)

HDR_STYLE  = ps("HDR",  fontSize=16, textColor=WHITE, alignment=TA_CENTER, leading=22)
SEC_STYLE  = ps("SEC",  fontSize=9.5, textColor=WHITE, alignment=TA_LEFT, leading=13)
BODY       = ps("BODY", fontSize=8,   leading=11)
BODY_B     = ps("BODYB",fontSize=8,   leading=11, fontName="Helvetica-Bold")
SMALL      = ps("SMALL",fontSize=7.2, leading=10)
SMALL_B    = ps("SMALLB",fontSize=7.2,leading=10, fontName="Helvetica-Bold")
CAP        = ps("CAP",  fontSize=6.5, textColor=HexColor("#666666"), leading=9)

story = []

# ── helpers ───────────────────────────────────────────────────────────────────

def banner(text, sub="", bg=NAVY):
    content = f"<b>{text}</b>"
    if sub:
        content += f"<br/><font size=9>{sub}</font>"
    t = Table([[Paragraph(content, HDR_STYLE)]], colWidths=[W])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("TOPPADDING",  (0,0), (-1,-1), 8),
        ("BOTTOMPADDING",(0,0),(-1,-1),8),
        ("BOX", (0,0), (-1,-1), 0.5, TEAL),
    ]))
    return t

def sec_hdr(text, bg=TEAL):
    t = Table([[Paragraph(f"<b>{text}</b>", SEC_STYLE)]], colWidths=[W])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("TOPPADDING",  (0,0), (-1,-1), 5),
        ("BOTTOMPADDING",(0,0),(-1,-1),5),
    ]))
    return t

def simple_table(rows, col_widths, header_bg=GREY_HDR, row_bgs=None):
    if row_bgs is None:
        row_bgs = [WHITE, GREY_LIGHT]
    t = Table(rows, colWidths=col_widths)
    style_cmds = [
        ("BACKGROUND", (0,0), (-1,0), header_bg),
        ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
        ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE",   (0,0), (-1,-1), 7.5),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), row_bgs),
        ("GRID", (0,0), (-1,-1), 0.3, HexColor("#cccccc")),
        ("TOPPADDING",  (0,0), (-1,-1), 4),
        ("BOTTOMPADDING",(0,0),(-1,-1),4),
        ("LEFTPADDING", (0,0), (-1,-1), 5),
        ("RIGHTPADDING",(0,0), (-1,-1), 5),
        ("VALIGN", (0,0), (-1,-1), "TOP"),
    ]
    t.setStyle(TableStyle(style_cmds))
    return t

def p(text, sty=None, **kw):
    if sty is None:
        sty = SMALL
    return Paragraph(text, sty)

def pb(text, **kw):
    return Paragraph(f"<b>{text}</b>", SMALL_B)

# ═══════════════════════════════════════════════════════════════════════════════
# PAGE 1
# ═══════════════════════════════════════════════════════════════════════════════

story.append(banner(
    "IgE-Based Treatment Algorithm",
    "Quick Reference Card for Clinical Practice · Orris Medical AI · May 2026"
))
story.append(Spacer(1, 3*mm))

# ── Section 1: Normal values ──────────────────────────────────────────────────
story.append(sec_hdr("1.  Normal IgE Values & Interpretation"))
story.append(Spacer(1, 1.5*mm))

rows = [
    [pb("Serum IgE (IU/mL)"), pb("Interpretation"), pb("Common Context")],
    [p("< 10"),      p("Very low"),           p("Possible IgE deficiency; recurrent sinopulmonary infections")],
    [p("10 – 100"),  p("Normal"),             p("Healthy adult")],
    [p("100 – 500"), p("Mildly elevated"),    p("Mild atopy, early sensitisation, low helminth load")],
    [p("500 – 2000"),p("Moderately elevated"),p("Active allergy, moderate helminthic infection, ABPA watch")],
    [p("> 2000"),    p("Markedly elevated"),  p("Hyper-IgE syndrome, heavy helminthiasis, ABPA flare")],
    [p("> 10 000"),  p("Very high"),          p("Severe HIES (Job's Syndrome), ABPA, heavy parasitic burden")],
]
story.append(simple_table(rows, [W*0.18, W*0.22, W*0.60]))
story.append(Spacer(1, 3*mm))

# ── Section 2: Initial Workup ─────────────────────────────────────────────────
story.append(sec_hdr("2.  Initial Workup When IgE > 100 IU/mL"))
story.append(Spacer(1, 1.5*mm))

rows = [
    [pb("Step"), pb("Investigation"), pb("Key Finding / Purpose")],
    [p("1"), p("CBC with differential + absolute eosinophil count"),
     p("Eos >500/µL → allergy or parasite; >1500/µL → helminthic or HIES strongly suspected")],
    [p("2"), p("Detailed allergy history (triggers, seasonality, family history)"),
     p("Seasonal → pollen; perennial → HDM/cockroach (India: cockroach most common)")],
    [p("3"), p("Specific IgE panel (ImmunoCAP/RAST) or skin-prick test"),
     p("Identifies sensitising allergen. Panel: HDM, cockroach, mold, food, drug")],
    [p("4"), p("Stool microscopy ×3 + Strongyloides IgG / Toxocara IgG / Ascaris IgG"),
     p("Mandatory in India/tropical settings. Rule out before starting biologics")],
    [p("5"), p("Chest X-ray / HRCT chest (if respiratory symptoms)"),
     p("Central bronchiectasis/mucus plugging → ABPA; pneumatoceles → HIES")],
    [p("6"), p("Aspergillus-specific IgE + Aspergillus precipitins (if IgE >1000)"),
     p("ABPA diagnosis requires Aspergillus IgE >0.35 kUA/L + compatible radiology")],
    [p("7"), p("IgG4 level (multi-organ involvement, eosinophilia)"),
     p("IgG4-related disease: elevated IgG4 + IgE + eosinophilia + hypocomplementemia")],
    [p("8"), p("STAT3 / DOCK8 genetic testing (recurrent bacterial/viral/fungal infections)"),
     p("Hyper-IgE Syndrome (AD-HIES = STAT3; AR-HIES = DOCK8)")],
]
story.append(simple_table(rows, [W*0.05, W*0.43, W*0.52]))
story.append(Spacer(1, 3*mm))

# ── Section 3: Treatment by Etiology ─────────────────────────────────────────
story.append(sec_hdr("3.  Treatment Algorithm by Etiology"))
story.append(Spacer(1, 1.5*mm))

# 3a — Allergic/Atopic
t3a_hdr = Table([[p("<b>ALLERGIC / ATOPIC CAUSES</b>", ps("t3ah", fontSize=8.5, textColor=WHITE, alignment=TA_CENTER))]], colWidths=[W])
t3a_hdr.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),TEAL),("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),4)]))
story.append(t3a_hdr)

rows = [
    [pb("Condition"), pb("1st Line"), pb("Escalation"), pb("Biologic Option")],
    [p("Allergic Rhinitis"),
     p("Intranasal corticosteroids (fluticasone/mometasone) + 2nd-gen antihistamine + saline irrigation"),
     p("Allergen immunotherapy (AIT) — lowers IgE long-term; montelukast adjunct"),
     p("Omalizumab (IgE 30–700)\nif severe + asthma coexists")],
    [p("Allergic Asthma\n(Step 1–3)"),
     p("SABA PRN → Low-dose ICS → ICS + LABA"),
     p("Step 4: Medium-high ICS + LABA\nStep 5: Add oral corticosteroid or biologic"),
     p("Omalizumab (allergic, IgE 30–700)\nDupilumab (any IgE)\nTezepelumab (any phenotype)")],
    [p("Eosinophilic Asthma\n(blood Eos ≥150/µL)"),
     p("ICS + LABA"),
     p("Maximise ICS; consider oral prednisone burst"),
     p("Mepolizumab 100 mg SC q4w\nBenralizumab 30 mg SC q4/8w\nReslizumab 3 mg/kg IV q4w")],
    [p("Atopic Dermatitis"),
     p("Emollients + topical steroids / calcineurin inhibitors"),
     p("Cyclosporine / methotrexate (short-term)"),
     p("Dupilumab 300 mg SC q2w\n(mod–severe uncontrolled)")],
    [p("Chronic Spontaneous\nUrticaria (CSU)"),
     p("2nd-gen antihistamine (up to 4× standard dose)"),
     p("Add montelukast; short-course steroids for flare"),
     p("Omalizumab 300 mg SC/month\n(no IgE threshold for CSU)")],
    [p("ABPA"),
     p("Prednisolone 0.5 mg/kg/day × 2 wks then taper\n+ Itraconazole 200 mg BD × 4 months"),
     p("Monitor IgE: ≥25% fall = good response\nLong-term itraconazole for recurrent ABPA"),
     p("Omalizumab adjunct for\nrefractory/recurrent ABPA")],
    [p("Eosinophilic\nEsophagitis"),
     p("PPI + swallowed topical fluticasone/budesonide"),
     p("Dietary elimination therapy (6-food elimination)"),
     p("Dupilumab 300 mg SC q2w")],
]
story.append(simple_table(rows, [W*0.14, W*0.30, W*0.28, W*0.28]))
story.append(Spacer(1, 2*mm))

# 3b — Parasitic
t3b_hdr = Table([[p("<b>PARASITIC / INFECTIOUS CAUSES  —  ⚠ Treat Parasite BEFORE Starting Biologics</b>",
                    ps("t3bh", fontSize=8.5, textColor=WHITE, alignment=TA_CENTER))]],
                colWidths=[W])
t3b_hdr.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),GREEN),("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),4)]))
story.append(t3b_hdr)

rows = [
    [pb("Organism"), pb("Clinical Clue"), pb("Treatment"), pb("IgE Follow-up")],
    [p("Ascaris lumbricoides\n(Roundworm)"),
     p("Loeffler syndrome (transient pulmonary eosinophilia), abdominal pain, worms in stool"),
     p("Albendazole 400 mg single dose OR\nMebendazole 500 mg single dose"),
     p("Recheck at 3 months")],
    [p("Hookworm\n(Ancylostoma/Necator)"),
     p("Iron-deficiency anaemia, hypoproteinaemia, pruritus plantaris, soil exposure"),
     p("Albendazole 400 mg × 3 days\n(single dose less effective for hookworm)"),
     p("IgE may take 6 months to normalise")],
    [p("Strongyloides"),
     p("Larva currens rash, eosinophilia, can disseminate if immunosuppressed — check BEFORE steroids/biologics"),
     p("Ivermectin 200 µg/kg/day × 2 days\n(drug of choice; repeat in 2 weeks)"),
     p("Critical: treat before any immunosuppression")],
    [p("Toxocara (VLM/OLM)"),
     p("Children/dog exposure, hepatomegaly, eosinophilia, positive Toxocara IgG ELISA"),
     p("Albendazole 400 mg BD × 5 days\n+ prednisolone if severe organ involvement"),
     p("Recheck at 3 months")],
    [p("Tropical Pulmonary\nEosinophilia (TPE)\n[Filaria]"),
     p("Nocturnal cough/wheeze + Eos >3000/µL + IgE very high. Endemic: India, SE Asia"),
     p("Diethylcarbamazine (DEC)\n6 mg/kg/day in 3 divided doses × 3 weeks"),
     p("IgE should fall significantly\nafter treatment")],
    [p("Schistosoma"),
     p("Fresh water exposure, Katayama fever, haematuria, hepatosplenomegaly"),
     p("Praziquantel 40 mg/kg as single dose\n(or 20 mg/kg × 2 doses same day)"),
     p("Recheck at 3 months")],
]
story.append(simple_table(rows, [W*0.17, W*0.30, W*0.30, W*0.23]))
story.append(Spacer(1, 2*mm))

# 3c — Rare/Immunodeficiency
t3c_hdr = Table([[p("<b>IMMUNODEFICIENCY / RARE CAUSES</b>",
                    ps("t3ch", fontSize=8.5, textColor=WHITE, alignment=TA_CENTER))]],
                colWidths=[W])
t3c_hdr.setStyle(TableStyle([("BACKGROUND",(0,0),(-1,-1),ORANGE),("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",(0,0),(-1,-1),4)]))
story.append(t3c_hdr)

rows = [
    [pb("Condition"), pb("Key Features"), pb("IgE Level"), pb("Treatment")],
    [p("AD-HIES (Job's Syndrome)\nSTAT3 mutation (dominant)"),
     p("Recurrent staph skin abscesses + pneumonia + pneumatoceles\nFacial dysmorphia, retained primary teeth, scoliosis, hyperextensibility"),
     p(">2000\n(often >10,000)"),
     p("Prophylactic TMP-SMX + antifungal (voriconazole)\nAvoid live vaccines; IVIG if antibody defect")],
    [p("AR-HIES\nDOCK8 mutation (recessive)"),
     p("Severe viral infections (molluscum, HPV, HSV) + recurrent bacterial infections\nLow T and B lymphocyte counts"),
     p("Very high"),
     p("HSCT — definitive cure\nProphylactic antimicrobials until transplant")],
    [p("IgG4-Related Disease"),
     p("Multi-organ fibroinflammatory disease; elevated IgG4 + IgE + eosinophilia\nPancreatitis, cholangitis, sialadenitis, aortitis"),
     p("Mildly–\nmoderately elevated"),
     p("Prednisolone 0.5–1 mg/kg/day → taper\nRituximab for refractory/relapsing disease")],
    [p("EGPA\n(Churg-Strauss)"),
     p("Asthma + eosinophilia + granulomatous vasculitis\nNeuropathy, cardiac involvement, p-ANCA positive"),
     p("Elevated"),
     p("High-dose prednisolone ± cyclophosphamide\nMepolizumab for eosinophilic remission maintenance")],
    [p("Hodgkin Lymphoma"),
     p("B symptoms, painless lymphadenopathy, mediastinal mass, Reed-Sternberg cells"),
     p("Mildly elevated"),
     p("Oncology referral; ABVD/BEV-ABVD chemotherapy")],
    [p("Omenn Syndrome\n(SCID variant)"),
     p("Neonatal erythroderma, diarrhoea, failure to thrive, absent B cells, eosinophilia"),
     p("Extremely high\n(>10,000)"),
     p("Urgent HSCT — life-saving\nSupportive: IVIG, antimicrobial prophylaxis")],
]
story.append(simple_table(rows, [W*0.20, W*0.38, W*0.12, W*0.30]))
story.append(Spacer(1, 3*mm))

# ── Section 4: Biologic selection ────────────────────────────────────────────
story.append(sec_hdr("4.  Biologic Selection Guide"))
story.append(Spacer(1, 1.5*mm))

rows = [
    [pb("Biologic"), pb("Target"), pb("IgE Threshold"), pb("Approved Indications"), pb("Dose & Route"), pb("Key Adverse Effects")],
    [p("Omalizumab\n(Xolair)"),
     p("Free IgE"),
     p("30–700 IU/mL\n(asthma)\nAny IgE (CSU)"),
     p("Allergic asthma ≥12 yr\nChronic spontaneous urticaria\nAllergic rhinitis (trials)"),
     p("Weight + IgE-based\nSC q2–4w\nCSU: 300 mg/month"),
     p("Anaphylaxis (monitor 30–60 min post-injection)\nLocal site reaction\nArteriothrombotic events")],
    [p("Dupilumab\n(Dupixent)"),
     p("IL-4Rα\n(IL-4 + IL-13)"),
     p("No IgE threshold"),
     p("Mod–severe atopic dermatitis\nMod–severe asthma\nCRSwNP\nEosinophilic esophagitis"),
     p("300 mg SC q2w\n(loading 600 mg)"),
     p("Conjunctivitis (common)\nInjection site reaction\nTransient eosinophilia")],
    [p("Mepolizumab\n(Nucala)"),
     p("IL-5"),
     p("Not IgE-based\nEos ≥150/µL"),
     p("Severe eosinophilic asthma\nEGPA (Churg-Strauss)\nHypereosinophilic syndrome"),
     p("100 mg SC q4w"),
     p("Anaphylaxis / angioedema\nHeadache, fatigue\nBack pain")],
    [p("Benralizumab\n(Fasenra)"),
     p("IL-5Rα"),
     p("Not IgE-based\nEos ≥300/µL preferred"),
     p("Severe eosinophilic asthma"),
     p("30 mg SC q4w ×3\nthen q8w"),
     p("Hypersensitivity reactions\nNasopharyngitis")],
    [p("Reslizumab\n(Cinqair)"),
     p("IL-5"),
     p("Not IgE-based\nEos ≥400/µL"),
     p("Severe eosinophilic asthma\n(inadequate ICS control)"),
     p("3 mg/kg IV q4w"),
     p("Anaphylaxis (IV — higher risk)\nMuscle pain / myalgia")],
    [p("Tezepelumab\n(Tezspire)"),
     p("TSLP\n(epithelial)"),
     p("NO threshold\n(any phenotype)"),
     p("Severe asthma — broadest biologic;\nworks regardless of eosinophil level"),
     p("210 mg SC q4w"),
     p("Pharyngitis\nBack pain\nInjection site reaction")],
]
t = simple_table(rows, [W*0.11, W*0.09, W*0.12, W*0.25, W*0.19, W*0.24])
# Highlight omalizumab (row 1) and tezepelumab (row 6)
t.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREY_HDR),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",   (0,0), (-1,-1), 7.2),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID", (0,0), (-1,-1), 0.3, HexColor("#cccccc")),
    ("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"),
    ("BACKGROUND", (0,1), (-1,1), LIGHT_BLUE),   # omalizumab highlighted
    ("BACKGROUND", (0,6), (-1,6), LIGHT_AMB),    # tezepelumab highlighted
]))
story.append(t)
story.append(Spacer(1, 3*mm))

# ── Section 5: Contraindications ──────────────────────────────────────────────
story.append(sec_hdr("5.  Absolute / Important Contraindications to Biologics", bg=ORANGE))
story.append(Spacer(1, 1.5*mm))

rows = [
    [pb("Contraindication"), pb("Applies To"), pb("Rationale")],
    [p("Known hypersensitivity / anaphylaxis to the biologic"),
     p("All biologics"),
     p("Class effect — switch to alternate agent or class")],
    [p("Active helminthic / parasitic infection"),
     p("All (especially omalizumab)"),
     p("Omalizumab reduces free IgE which is protective against helminths. Treat parasite first; recheck IgE at 3 months")],
    [p("Serum IgE <30 or >700 IU/mL (asthma indication only)"),
     p("Omalizumab — asthma indication"),
     p("Outside validated dosing range; dose cannot be accurately calculated from nomogram")],
    [p("Non-allergic (intrinsic) asthma with normal IgE"),
     p("Omalizumab"),
     p("Mechanism requires allergen–IgE pathway activation; no benefit without it")],
    [p("Active serious infection (bacterial / fungal / viral)"),
     p("All biologics"),
     p("Immunomodulation may worsen active infection; treat and clear infection first")],
    [p("Live vaccines within 30 days before or after starting"),
     p("All biologics (esp. dupilumab)"),
     p("Risk of disseminated vaccine-strain infection; give all live vaccines before initiating biologic")],
    [p("Active malignancy (relative)"),
     p("All biologics"),
     p("Insufficient safety data; Th2 skewing may promote some tumours — case-by-case oncology review")],
    [p("Pregnancy (relative — insufficient data for most)"),
     p("All biologics"),
     p("Omalizumab has most pregnancy data (used for severe asthma). Shared decision-making required")],
]
t = Table(rows, colWidths=[W*0.35, W*0.22, W*0.43])
t.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), HexColor("#7b241c")),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",   (0,0), (-1,-1), 7.5),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_RED]),
    ("GRID", (0,0), (-1,-1), 0.3, HexColor("#cccccc")),
    ("TOPPADDING",  (0,0), (-1,-1), 4),
    ("BOTTOMPADDING",(0,0),(-1,-1),4),
    ("LEFTPADDING", (0,0), (-1,-1), 5),
    ("RIGHTPADDING",(0,0),(-1,-1), 5),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(t)
story.append(Spacer(1, 3*mm))

# ── Section 6: Drugs lowering IgE ────────────────────────────────────────────
story.append(sec_hdr("6.  Drugs / Interventions That Lower Serum IgE"))
story.append(Spacer(1, 1.5*mm))

rows = [
    [pb("Drug / Intervention"), pb("Effect on IgE"), pb("Mechanism"), pb("Notes")],
    [p("Omalizumab"),
     p("Dramatically lowers FREE IgE\n(total IgE paradoxically rises)"),
     p("Binds circulating free IgE; IgE–drug complexes measured as total IgE"),
     p("Measure FREE IgE on treatment. Total IgE remains elevated up to 1 year after stopping")],
    [p("Allergen Immunotherapy (AIT)"),
     p("Gradual ↓ specific + total IgE over 3–5 years"),
     p("Induces immune tolerance; shifts Th2 → Th1/Treg; increases IgG4 blocking antibodies"),
     p("Only intervention offering long-term remission. Can reduce IgE by 30–50%")],
    [p("Dupilumab"),
     p("Slow ↓ in IgE synthesis over months"),
     p("Blocks IL-4/IL-13 receptor → prevents IgE class-switch recombination in B cells"),
     p("IgE falls gradually; not primarily an IgE-lowering drug but useful in atopic disease")],
    [p("Systemic corticosteroids"),
     p("Modest, transient reduction"),
     p("Broad Th2 suppression; reduces IL-4/IL-13 driving IgE synthesis"),
     p("Not suitable for long-term IgE reduction due to side effects")],
    [p("Cyclosporine"),
     p("Reduces IgE in atopic dermatitis"),
     p("Suppresses T-cell IL-4 production, reducing IgE class switching"),
     p("Second-line for severe atopic dermatitis; renal monitoring required")],
    [p("Anti-helminthic treatment\n(albendazole / ivermectin / DEC)"),
     p("Normalises IgE if parasite was the cause"),
     p("Eliminates chronic parasitic antigen drive of polyclonal IgE synthesis"),
     p("Recheck total IgE at 3 months. If IgE falls to near-normal, allergy less likely the sole cause")],
]
story.append(simple_table(rows, [W*0.20, W*0.22, W*0.28, W*0.30]))
story.append(Spacer(1, 3*mm))

# ── Section 7: Monitoring ─────────────────────────────────────────────────────
story.append(sec_hdr("7.  Monitoring Protocol", bg=NAVY))
story.append(Spacer(1, 1.5*mm))

rows = [
    [pb("Timepoint / Scenario"), pb("What to Measure"), pb("Interpretation / Action")],
    [p("Baseline (before any biologic)"),
     p("Total IgE, specific IgE panel, CBC + eosinophils, stool exam, chest X-ray"),
     p("Establishes baseline for comparison; rules out parasites and ABPA")],
    [p("On omalizumab therapy"),
     p("FREE IgE (not total IgE)"),
     p("Total IgE unreliable — drug-IgE complexes elevate total IgE for up to 1 year. Free IgE should be near-undetectable if dose correct")],
    [p("Every 3 months on biologic"),
     p("Absolute eosinophil count, symptom score, exacerbation frequency"),
     p("Assess clinical response; eosinophil normalisation expected with anti-IL-5 agents")],
    [p("ABPA monitoring"),
     p("Total IgE every 6–8 weeks during treatment"),
     p("≥25% fall from baseline = satisfactory response to prednisolone + itraconazole")],
    [p("Post-anti-helminthic treatment"),
     p("Total IgE at 3 months"),
     p("Significant fall (>50%) confirms parasitic origin. If IgE remains elevated, consider allergic/atopic aetiology")],
    [p("Before skin-prick testing"),
     p("Last omalizumab dose"),
     p("Wait ≥8 weeks after stopping omalizumab before skin testing — drug suppresses wheal/flare response")],
    [p("Annual stable patient"),
     p("Total IgE, eosinophil count, spirometry (if asthma)"),
     p("Detect disease progression or new sensitisation")],
]
story.append(simple_table(rows, [W*0.24, W*0.30, W*0.46]))
story.append(Spacer(1, 3*mm))

# ── Section 8: Clinical Scenario ─────────────────────────────────────────────
story.append(sec_hdr("8.  Clinical Algorithm: Patient with IgE 700 IU/mL + Recurrent Pharyngitis + Runny Nose"))
story.append(Spacer(1, 1.5*mm))

rows = [
    [pb("Step"), pb("Action"), pb("Expected Finding / Decision")],
    [p("1. Clinical assessment"),
     p("Characterise: seasonal vs perennial? Dust/pollen/cockroach triggers?\nGI symptoms? Rural exposure? Eczema? Asthma?"),
     p("Perennial triggers → HDM/cockroach (most likely in India)\nSeasonal → pollen\nGI symptoms → helminth workup")],
    [p("2. CBC + differential"),
     p("Absolute eosinophil count"),
     p("Eos <500/µL → allergic rhinitis likely\nEos >1000/µL → rule out helminthic infection FIRST before any biologic")],
    [p("3. Specific IgE / SPT"),
     p("ImmunoCAP: HDM (D. pteronyssinus, D. farinae), cockroach\n(Periplaneta americana), Alternaria, Aspergillus, food panel"),
     p("Positive cockroach or HDM IgE → confirms allergic rhinitis\nAspergillus IgE positive → investigate ABPA")],
    [p("4. Stool exam + serology"),
     p("Stool microscopy ×3\nStrongyloides IgG, Toxocara IgG, Ascaris IgG ELISA"),
     p("If positive → treat parasite first\nRecheck IgE at 3 months before biologic decision")],
    [p("5. Diagnose & treat\nprimary cause"),
     p("Dx: Allergic rhinitis with post-nasal drip\n→ Intranasal fluticasone/mometasone daily\n→ Cetirizine 10 mg OD\n→ Saline nasal irrigation BD"),
     p("Post-nasal drip is the cause of recurrent 'pharyngitis'\nAntibiotic courses are NOT needed — treat rhinitis instead\nExpect sore throat to resolve with rhinitis treatment")],
    [p("6. Escalation if\nuncontrolled"),
     p("Allergen immunotherapy (AIT) — for long-term remission\nIf severe asthma develops → consider omalizumab"),
     p("IgE of 700 is at upper limit of omalizumab dosing range — still eligible\nDose calculated from weight + IgE nomogram (use Xolair calculator)")],
    [p("7. Biologic eligibility\ncheck (omalizumab)"),
     p("IgE 30–700 IU/mL ✓  |  Age ≥12 yrs ✓\nAllergic sensitisation confirmed ✓\nNo active parasites ✓\nModerate–severe persistent asthma present?"),
     p("ELIGIBLE for omalizumab IF:\n• Moderate–severe allergic asthma confirmed\n• ICS + LABA insufficient\n• No active helminthic infection\nIf asthma absent, AIT is preferred first")],
]
t = Table(rows, colWidths=[W*0.16, W*0.40, W*0.44])
t.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), GREY_HDR),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",   (0,0), (-1,-1), 7.5),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_LIGHT]),
    ("GRID", (0,0), (-1,-1), 0.3, HexColor("#cccccc")),
    ("TOPPADDING",  (0,0), (-1,-1), 4),
    ("BOTTOMPADDING",(0,0),(-1,-1),4),
    ("LEFTPADDING", (0,0), (-1,-1), 5),
    ("RIGHTPADDING",(0,0),(-1,-1), 5),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
    ("BACKGROUND", (0,6), (-1,6), LIGHT_BLUE),  # biologic eligibility row
]))
story.append(t)
story.append(Spacer(1, 3*mm))

# ── Section 9: India-specific ─────────────────────────────────────────────────
story.append(sec_hdr("9.  India-Specific Considerations — Young Adult Population", bg=AMBER))
story.append(Spacer(1, 1.5*mm))

rows = [
    [pb("Topic"), pb("Key Points")],
    [p("#1 Cause in Urban India"),
     p("Allergic rhinitis sensitised to cockroach (Periplaneta americana) — single most common aeroallergen in Indian urban adults — and house dust mite (D. pteronyssinus). IgE prevalence of atopy 20–30% in urban young adults.")],
    [p("#1 Cause in Rural/Semi-urban India"),
     p("Helminthic parasitic infection (Ascaris lumbricoides, Ancylostoma duodenale, Strongyloides stercoralis). Warm humid climate + agrarian soil contact = high transmission. Always rule out before biologic therapy.")],
    [p("Dual Cause"),
     p("Both allergy AND parasitic infection can coexist in the same patient. Treat helminth first. Total IgE may fall significantly post-treatment, potentially changing biologic eligibility status.")],
    [p("Tropical Pulmonary\nEosinophilia (TPE)"),
     p("Classic Indian condition. Filarial species (Wuchereria bancrofti / Brugia malayi). Triad: nocturnal cough + wheeze + eosinophilia >3000/µL. IgE very high. Treatment: DEC 6 mg/kg/day × 3 weeks.")],
    [p("Hygiene Hypothesis"),
     p("Rapidly urbanising India shows rising atopic disease as helminth burden falls. Young adults in metros approach Western allergy rates. Atopic march (eczema → rhinitis → asthma) increasingly recognised.")],
    [p("Biologic Access"),
     p("Omalizumab (Xolair) and dupilumab (Dupixent) are available in India but expensive. ImmunoCAP testing available at tertiary allergy centres. Allergen immunotherapy (AIT) is cost-effective long-term alternative.")],
    [p("Most Important Pitfall"),
     p("Recurrent 'pharyngitis' in young Indians with high IgE is most often ALLERGIC POST-NASAL DRIP — not recurrent streptococcal tonsillitis. Avoid repeated antibiotic courses. Diagnose and treat allergic rhinitis. Pharyngitis resolves when post-nasal drip is controlled.")],
]
t = Table(rows, colWidths=[W*0.22, W*0.78])
t.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,0), HexColor("#7d6608")),
    ("TEXTCOLOR",  (0,0), (-1,0), WHITE),
    ("FONTNAME",   (0,0), (-1,0), "Helvetica-Bold"),
    ("FONTSIZE",   (0,0), (-1,-1), 7.8),
    ("ROWBACKGROUNDS", (0,1), (-1,-1), [LIGHT_AMB, WHITE]),
    ("GRID", (0,0), (-1,-1), 0.3, HexColor("#cccccc")),
    ("TOPPADDING",  (0,0), (-1,-1), 4),
    ("BOTTOMPADDING",(0,0),(-1,-1),4),
    ("LEFTPADDING", (0,0), (-1,-1), 5),
    ("RIGHTPADDING",(0,0),(-1,-1), 5),
    ("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(t)
story.append(Spacer(1, 3*mm))

# ── Footer ────────────────────────────────────────────────────────────────────
story.append(HRFlowable(width=W, thickness=0.5, color=TEAL))
story.append(Spacer(1, 1.5*mm))
story.append(Paragraph(
    "<b>Sources:</b> Harrison's Principles of Internal Medicine 22E (2025) · Goldman-Cecil Medicine · "
    "K.J. Lee's Essential Otolaryngology · Katzung's Basic & Clinical Pharmacology 16th Ed. · "
    "Fishman's Pulmonary Diseases · Murray & Nadel's Respiratory Medicine · Fitzpatrick's Dermatology 9th Ed.  |  "
    "<b>Orris Medical AI · May 2026</b>  |  "
    "<i>Clinical guidance only. Verify doses against current product labelling and institutional protocols.</i>",
    CAP
))

# ── Build ─────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF generated successfully: {OUTPUT}")
Running Command

cat > /home/daytona/workspace/ige-protocol/generate_ige_pdf.py << 'PYEOF' #!/usr…

Running Command

cd /home/daytona/workspace/ige-protocol && python3 generate_ige_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/ige-protocol/IgE_Treatment_Algorithm.pdf

Your PDF is ready:

IgE Treatment Algorithm

PDF Document · PDF

Here's what the 9-section quick reference covers:
SectionContent
1. Normal IgE ValuesInterpretation table from <10 to >10,000 IU/mL with clinical context
2. Initial WorkupStep-by-step 8-point investigation protocol including parasite screen
3. Treatment by EtiologyThree colour-coded tables: Allergic/Atopic (teal), Parasitic/Infectious (green), Immunodeficiency/Rare (red)
4. Biologic Selection GuideAll 6 biologics with IgE thresholds, indications, doses, and adverse effects; omalizumab and tezepelumab highlighted
5. Contraindications8 absolute/relative contraindications with rationale, highlighted in red
6. Drugs That Lower IgEMechanism and monitoring notes for each agent
7. Monitoring ProtocolWhen to measure free vs total IgE, ABPA follow-up, post-parasite treatment re-check
8. Clinical ScenarioStep-by-step algorithm for the IgE 700 + pharyngitis + rhinitis patient
9. India-Specific NotesUrban vs rural causes, TPE, cockroach sensitisation, the post-nasal drip pitfall

Make a summary pdf on omalizumab dosing calculator and monitoring protocol

Finding Sources
Searching the Web

omalizumab dosing table weight IgE nomogram asthma urticaria 2024

Reading Web Page

https://www.ohsu.edu/sites/default/files/2025-03/OHSU-HS-MPS…

Finding Sources
Running Command

cat > /home/daytona/workspace/ige-protocol/omalizumab_dosing_pdf.py << 'PYEOF' #…

Running Command

cd /home/daytona/workspace/ige-protocol && python3 omalizumab_dosing_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/ige-protocol/Omalizumab_Dosing_Monitoring.pdf

Your PDF is ready:

Omalizumab Dosing Monitoring

PDF Document · PDF


Here's what's packed into the 11 sections:
Dosing Sections:
SectionContent
1. MechanismHow omalizumab binds free IgE, downregulates FcεRI, reverses airway remodelling
2. Indications & EligibilityColour-coded table: Asthma, CSU, CRSwNP, Food Allergy, ABPA (off-label) with IgE thresholds per indication
3. Dose NomogramFull q4w and q2w official dose tables for adults ≥12 yrs; "DO NOT DOSE" cells highlighted in red
4. CSU Fixed Dosing150 vs 300 mg/month; response at 12 weeks; stopping strategy
5. Paediatric DosingSimplified reference for 6–<12 years with weight bands
6. Step-by-Step CalculatorWorked example (70 kg, IgE 450) showing exactly how to look up dose and confirm it meets the 0.016 formula minimum
Monitoring Sections:
SectionContent
7. Monitoring ProtocolPre-treatment → day of injection → 4 weeks → 12–16 weeks → 3-monthly → annual → stopping
8. IgE Interpretation BoxThe IgE paradox explained: why total IgE rises on treatment and why FREE IgE is the only valid on-treatment measure
9. Adverse EffectsAnaphylaxis (mandatory 30–60 min observation rule), injection site reactions, arteriothrombotic events, helminth risk
10. Special PopulationsPregnancy, breastfeeding, renal/hepatic impairment, obesity, beta-blocker use, India-specific parasite screening
11. At-a-Glance Summary BoxOne-page cheat sheet: before starting → dose lookup → after injection → response → stopping
This is a shared conversation. Sign in to Orris to start your own chat.