attachment
attachment

Explain this

analyse_media
Reading File

Plain Chest X-Ray - PA View: Radiological Explanation

This is a posteroanterior (PA) chest radiograph, one of the most common imaging studies in medicine. Here is a full breakdown:

Technical Assessment

ParameterFinding
ProjectionPA (patient faces the film; X-ray beam enters from behind)
RotationNone - clavicle heads symmetric around the spine
InspirationAdequate (~9 posterior ribs visible)
PenetrationAdequate - spine faintly visible through cardiac shadow

Normal Structures (Present in This Film)

  • Trachea: Midline, no deviation - rules out tension pneumothorax or large mass
  • Cardiac silhouette: Normal size; cardiothoracic ratio < 50% (no cardiomegaly)
  • Mediastinum: Normal width; aortic knob is normal
  • Diaphragm: Both hemidiaphragms dome-shaped and at normal positions; right is slightly higher than left (normal). Gastric air bubble visible under the left hemidiaphragm
  • Costophrenic angles: Sharp and clear bilaterally - no pleural effusion
  • Bones: No fractures, lytic, or blastic lesions visible in ribs, clavicles, or scapulae

Abnormal Findings

Key finding: Bilateral diffuse reticulonodular opacities
  • These are increased interstitial markings seen in both lung fields
  • Distribution is predominantly perihilar (around the lung roots) and in the mid-to-lower lung zones
  • There is also mild bilateral hilar prominence (slightly enlarged/full hilum on both sides)

Differential Diagnosis

The bilateral reticulonodular (interstitial) pattern with perihilar distribution raises several possibilities:
DiagnosisSupporting Feature
SarcoidosisPerihilar distribution + bilateral hilar prominence is classic (BHL - bilateral hilar lymphadenopathy)
Atypical/Viral PneumoniaBilateral diffuse interstitial pattern (Mycoplasma, COVID-19, influenza)
Miliary TuberculosisFine uniform nodules throughout; consider in endemic areas
PneumoconiosisOccupational exposure history; upper/mid-zone nodular pattern
Interstitial Lung Disease (ILD)Chronic course; check for fibrotic changes on HRCT

What This X-Ray Does NOT Show

  • No consolidation (no lobar/segmental pneumonia)
  • No pneumothorax (no collapsed lung edge)
  • No pleural effusion (angles are clear)
  • No cardiomegaly

Next Steps

  1. HRCT chest - gold standard to characterize the interstitial pattern further
  2. Clinical correlation - symptoms (dry cough, dyspnea, fever?), occupational history, travel history
  3. ACE levels + LDH if sarcoidosis is suspected
  4. Sputum/BAL if infection (TB, atypical pneumonia) is high on the differential
Bottom line: This PA chest X-ray shows bilateral interstitial opacities with perihilar predominance. The most classic pattern here fits sarcoidosis with bilateral hilar lymphadenopathy (BHL), but atypical infection (viral/Mycoplasma) and other ILDs must be excluded with clinical context and HRCT.

Create a quick reference PDF on chest X-ray interpretation

Reading File
Running Command

mkdir -p /tmp/workspace/cxr-reference && ls /tmp/workspace/cxr-reference/

Writing File

~/cxr-reference/make_cxr_pdf.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm, cm
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

OUTPUT = "/tmp/workspace/cxr-reference/CXR_Quick_Reference.pdf"

# ── Colours ──────────────────────────────────────────────────────────────────
DARK_BLUE   = colors.HexColor("#1A3A5C")
MID_BLUE    = colors.HexColor("#2E6DA4")
LIGHT_BLUE  = colors.HexColor("#D6E8F7")
TEAL        = colors.HexColor("#1B7A6E")
LIGHT_TEAL  = colors.HexColor("#D0EFEB")
ORANGE      = colors.HexColor("#D4500A")
LIGHT_ORANGE= colors.HexColor("#FDE9DC")
YELLOW_BG   = colors.HexColor("#FFF8DC")
WHITE       = colors.white
GREY_LINE   = colors.HexColor("#CCCCCC")
DARK_TEXT   = colors.HexColor("#1A1A1A")
LIGHT_GREY  = colors.HexColor("#F5F5F5")
RED_ERR     = colors.HexColor("#C0392B")
GREEN_OK    = colors.HexColor("#1E8449")

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

def S(name, **kw):
    return ParagraphStyle(name, **kw)

TITLE   = S("Title2",   fontName="Helvetica-Bold",   fontSize=22, textColor=WHITE,    alignment=TA_CENTER, spaceAfter=4)
SUBTITLE= S("Sub",      fontName="Helvetica",        fontSize=11, textColor=LIGHT_BLUE, alignment=TA_CENTER, spaceAfter=2)
H1      = S("H1",       fontName="Helvetica-Bold",   fontSize=13, textColor=WHITE,    alignment=TA_LEFT,   spaceAfter=2, spaceBefore=4)
H2      = S("H2",       fontName="Helvetica-Bold",   fontSize=11, textColor=DARK_BLUE, alignment=TA_LEFT,  spaceAfter=3, spaceBefore=6)
H3      = S("H3",       fontName="Helvetica-BoldOblique", fontSize=10, textColor=TEAL, alignment=TA_LEFT,  spaceAfter=2, spaceBefore=4)
BODY    = S("Body2",    fontName="Helvetica",        fontSize=9,  textColor=DARK_TEXT, alignment=TA_JUSTIFY, spaceAfter=2, leading=13)
BULLET  = S("Bullet2",  fontName="Helvetica",        fontSize=9,  textColor=DARK_TEXT, alignment=TA_LEFT,   spaceAfter=2, leftIndent=12, leading=13)
SMALL   = S("Small",    fontName="Helvetica",        fontSize=8,  textColor=colors.grey, alignment=TA_CENTER)
TABLE_H = S("TblH",     fontName="Helvetica-Bold",   fontSize=9,  textColor=WHITE,    alignment=TA_CENTER)
TABLE_B = S("TblB",     fontName="Helvetica",        fontSize=8.5,textColor=DARK_TEXT, alignment=TA_LEFT,  leading=12)
TABLE_BC= S("TblBC",    fontName="Helvetica",        fontSize=8.5,textColor=DARK_TEXT, alignment=TA_CENTER,leading=12)
WARN    = S("Warn",     fontName="Helvetica-Bold",   fontSize=9,  textColor=RED_ERR,  alignment=TA_LEFT,   spaceAfter=2)
NOTE    = S("Note",     fontName="Helvetica-Oblique",fontSize=8.5,textColor=DARK_BLUE,alignment=TA_LEFT,   spaceAfter=2, leading=12)

def section_header(text, colour=DARK_BLUE):
    """Full-width coloured section header bar."""
    data = [[Paragraph(text, H1)]]
    t = Table(data, colWidths=[175*mm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), colour),
        ("TOPPADDING",    (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING",   (0,0), (-1,-1), 8),
        ("RIGHTPADDING",  (0,0), (-1,-1), 8),
        ("ROWBACKGROUNDS",(0,0), (-1,-1), [colour]),
    ]))
    return t

def box_table(data_rows, col_widths, header_colour=MID_BLUE, stripe=True):
    """Generic styled table."""
    t = Table(data_rows, colWidths=col_widths, repeatRows=1)
    style_cmds = [
        ("BACKGROUND",    (0,0), (-1,0),  header_colour),
        ("TEXTCOLOR",     (0,0), (-1,0),  WHITE),
        ("FONTNAME",      (0,0), (-1,0),  "Helvetica-Bold"),
        ("FONTSIZE",      (0,0), (-1,0),  9),
        ("ALIGN",         (0,0), (-1,0),  "CENTER"),
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
        ("GRID",          (0,0), (-1,-1), 0.4, GREY_LINE),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING",   (0,0), (-1,-1), 5),
        ("RIGHTPADDING",  (0,0), (-1,-1), 5),
    ]
    if stripe:
        for r in range(1, len(data_rows)):
            bg = LIGHT_GREY if r % 2 == 1 else WHITE
            style_cmds.append(("BACKGROUND", (0,r), (-1,r), bg))
    t.setStyle(TableStyle(style_cmds))
    return t

# ── Document ──────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT, pagesize=A4,
    leftMargin=18*mm, rightMargin=18*mm,
    topMargin=15*mm,  bottomMargin=15*mm,
    title="Chest X-Ray Quick Reference",
    author="Orris Medical Reference"
)

story = []
W = 174*mm   # usable width

# ════════════════════════════════════════════════════════════════════════════
# COVER BANNER
# ════════════════════════════════════════════════════════════════════════════
cover_data = [[
    Paragraph("CHEST X-RAY", TITLE),
    Paragraph("Quick Reference Guide", SUBTITLE),
    Paragraph("Systematic Interpretation · Patterns · Differentials · Key Measurements", SMALL),
]]
cover_t = Table([[
    Paragraph("CHEST X-RAY", TITLE),
]], colWidths=[W])
cover_t.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
    ("TOPPADDING",    (0,0), (-1,-1), 14),
    ("BOTTOMPADDING", (0,0), (-1,-1), 2),
    ("LEFTPADDING",   (0,0), (-1,-1), 10),
]))
story.append(cover_t)

sub_t = Table([[Paragraph("Quick Reference Guide for Clinical Practice", SUBTITLE)]], colWidths=[W])
sub_t.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
    ("TOPPADDING",    (0,0), (-1,-1), 0),
    ("BOTTOMPADDING", (0,0), (-1,-1), 14),
    ("LEFTPADDING",   (0,0), (-1,-1), 10),
]))
story.append(sub_t)
story.append(Spacer(1, 6*mm))

# ════════════════════════════════════════════════════════════════════════════
# SECTION 1 — TECHNICAL ADEQUACY (RIPE)
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header("1.  TECHNICAL ADEQUACY — The RIPE Checklist"))
story.append(Spacer(1, 3*mm))

ripe_data = [
    [Paragraph("Letter", TABLE_H), Paragraph("Parameter", TABLE_H),
     Paragraph("How to Assess", TABLE_H), Paragraph("Adequate When…", TABLE_H)],
    [Paragraph("<b>R</b>", TABLE_BC), Paragraph("Rotation", TABLE_B),
     Paragraph("Medial clavicle ends equidistant from spinous processes", TABLE_B),
     Paragraph("Symmetric clavicle-spine gaps", TABLE_B)],
    [Paragraph("<b>I</b>", TABLE_BC), Paragraph("Inspiration", TABLE_B),
     Paragraph("Count posterior ribs above right hemidiaphragm", TABLE_B),
     Paragraph("≥ 6 anterior / ≥ 9–10 posterior ribs visible", TABLE_B)],
    [Paragraph("<b>P</b>", TABLE_BC), Paragraph("Projection", TABLE_B),
     Paragraph("PA: scapulae lateral to lung fields; AP: scapulae overlap lungs", TABLE_B),
     Paragraph("PA preferred — heart appears smaller than AP", TABLE_B)],
    [Paragraph("<b>E</b>", TABLE_BC), Paragraph("Exposure / Penetration", TABLE_B),
     Paragraph("Look for vertebrae through cardiac shadow", TABLE_B),
     Paragraph("Vertebrae just visible; vessels visible in lungs", TABLE_B)],
]
story.append(box_table(ripe_data, [10*mm, 28*mm, 70*mm, 62*mm]))
story.append(Spacer(1, 5*mm))

# ════════════════════════════════════════════════════════════════════════════
# SECTION 2 — SYSTEMATIC APPROACH (ABCDE)
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header("2.  SYSTEMATIC APPROACH — ABCDE"))
story.append(Spacer(1, 3*mm))

abcde_data = [
    [Paragraph("Letter", TABLE_H), Paragraph("Stands For", TABLE_H),
     Paragraph("What to Look For", TABLE_H)],
    [Paragraph("<b>A</b>", TABLE_BC), Paragraph("Airway", TABLE_B),
     Paragraph("Trachea midline? Any deviation? Carina angle ≤ 70°. Check for foreign bodies, subglottic narrowing.", TABLE_B)],
    [Paragraph("<b>B</b>", TABLE_BC), Paragraph("Breathing (Lungs)", TABLE_B),
     Paragraph("Compare both lung fields: opacities, consolidation, collapse, pneumothorax, interstitial markings, nodules, masses.", TABLE_B)],
    [Paragraph("<b>C</b>", TABLE_BC), Paragraph("Cardiac / Mediastinum", TABLE_B),
     Paragraph("Cardiothoracic ratio < 0.5 on PA. Check cardiac borders (silhouette sign), mediastinal width < 8 cm, aortic knob.", TABLE_B)],
    [Paragraph("<b>D</b>", TABLE_BC), Paragraph("Diaphragm / Below", TABLE_B),
     Paragraph("Right hemidiaphragm higher than left (by 1.5–2.5 cm). Sharp costophrenic angles. Free air under diaphragm?", TABLE_B)],
    [Paragraph("<b>E</b>", TABLE_BC), Paragraph("Everything Else", TABLE_B),
     Paragraph("Bones (ribs, clavicles, spine): fractures, lytic/blastic lesions. Soft tissues: emphysema, foreign bodies, lines/tubes.", TABLE_B)],
]
story.append(box_table(abcde_data, [10*mm, 35*mm, 125*mm]))
story.append(Spacer(1, 5*mm))

# ════════════════════════════════════════════════════════════════════════════
# SECTION 3 — KEY MEASUREMENTS
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header("3.  KEY MEASUREMENTS & NORMAL VALUES", TEAL))
story.append(Spacer(1, 3*mm))

meas_data = [
    [Paragraph("Measurement", TABLE_H), Paragraph("Normal Value", TABLE_H),
     Paragraph("Significance if Abnormal", TABLE_H)],
    [Paragraph("Cardiothoracic (CT) ratio", TABLE_B),
     Paragraph("< 0.5 on PA view", TABLE_B),
     Paragraph("≥ 0.5 = cardiomegaly (CCF, pericardial effusion, dilated cardiomyopathy)", TABLE_B)],
    [Paragraph("Mediastinal width", TABLE_B),
     Paragraph("< 8 cm at aortic arch level", TABLE_B),
     Paragraph("> 8 cm = consider aortic dissection, lymphoma, thymoma", TABLE_B)],
    [Paragraph("Carina angle", TABLE_B),
     Paragraph("≤ 70°", TABLE_B),
     Paragraph("> 70° = left atrial enlargement (widened carina / 'splayed' carina)", TABLE_B)],
    [Paragraph("Tracheal position", TABLE_B),
     Paragraph("Midline, slight right deviation at aortic arch is normal", TABLE_B),
     Paragraph("Deviation away from opacity = tension pneumothorax or large effusion; toward = collapse", TABLE_B)],
    [Paragraph("Diaphragm height", TABLE_B),
     Paragraph("Right 1.5–2.5 cm higher than left", TABLE_B),
     Paragraph("Elevated = paralysis, subphrenic abscess, hepatomegaly, collapse; Flattened = hyperinflation (COPD)", TABLE_B)],
    [Paragraph("Costophrenic angles", TABLE_B),
     Paragraph("Acute, sharp", TABLE_B),
     Paragraph("Blunting = ≥ 200–300 mL pleural fluid; obliteration = larger effusion", TABLE_B)],
    [Paragraph("Hilum position", TABLE_B),
     Paragraph("Left hilum 0.5–1.5 cm higher than right", TABLE_B),
     Paragraph("Bilateral enlargement (BHL): sarcoidosis, lymphoma, TB; Unilateral: malignancy, infection", TABLE_B)],
]
story.append(box_table(meas_data, [48*mm, 42*mm, 80*mm], header_colour=TEAL))
story.append(Spacer(1, 5*mm))

# ════════════════════════════════════════════════════════════════════════════
# SECTION 4 — LUNG OPACITY PATTERNS
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header("4.  LUNG OPACITY PATTERNS & DIFFERENTIALS"))
story.append(Spacer(1, 3*mm))

pattern_data = [
    [Paragraph("Pattern", TABLE_H), Paragraph("Appearance on CXR", TABLE_H),
     Paragraph("Key Differentials", TABLE_H), Paragraph("Clue", TABLE_H)],
    [Paragraph("Consolidation", TABLE_B),
     Paragraph("Homogeneous opacity, air bronchogram, no volume loss", TABLE_B),
     Paragraph("Pneumonia, pulmonary oedema, infarction, haemorrhage, aspiration", TABLE_B),
     Paragraph("Air bronchogram = airspace disease", TABLE_B)],
    [Paragraph("Collapse / Atelectasis", TABLE_B),
     Paragraph("Opacity with volume loss: shifted fissures, trachea/mediastinum pulled toward lesion", TABLE_B),
     Paragraph("Mucus plug, endobronchial tumour, foreign body", TABLE_B),
     Paragraph("Volume loss is key distinguishing feature", TABLE_B)],
    [Paragraph("Pleural Effusion", TABLE_B),
     Paragraph("Homogeneous opacity with meniscus; blunted costophrenic angle; opacifies base", TABLE_B),
     Paragraph("CCF, malignancy, infection (empyema), TB, PE, trauma, hypoalbuminaemia", TABLE_B),
     Paragraph("Blunts CP angle; > 500 mL shifts mediastinum away", TABLE_B)],
    [Paragraph("Pneumothorax", TABLE_B),
     Paragraph("Visible lung edge with absent lung markings beyond it", TABLE_B),
     Paragraph("Spontaneous (tall thin male), trauma, iatrogenic, COPD, asthma", TABLE_B),
     Paragraph("Check for tension: tracheal deviation, collapsed lung", TABLE_B)],
    [Paragraph("Interstitial Pattern", TABLE_B),
     Paragraph("Reticular, nodular, or reticulonodular; Kerley B lines (septal lines)", TABLE_B),
     Paragraph("Pulmonary oedema (Kerley B), ILD, sarcoidosis, viral/atypical pneumonia, lymphangitis", TABLE_B),
     Paragraph("Kerley B lines at periphery → pulmonary oedema", TABLE_B)],
    [Paragraph("Miliary Pattern", TABLE_B),
     Paragraph("Fine 1–3 mm nodules uniformly throughout both lungs", TABLE_B),
     Paragraph("Miliary TB, haematogenous metastases, sarcoidosis, fungal infection", TABLE_B),
     Paragraph("'Snow storm' appearance", TABLE_B)],
    [Paragraph("Cavitation", TABLE_B),
     Paragraph("Opacity with central lucency (air-fluid level if infected)", TABLE_B),
     Paragraph("TB, lung abscess, Klebsiella, squamous cell carcinoma, Wegener's, fungal", TABLE_B),
     Paragraph("Thick wall = malignancy/abscess; thin wall = hydatid/bulla", TABLE_B)],
    [Paragraph("Mass / Nodule", TABLE_B),
     Paragraph("Rounded opacity; > 3 cm = mass; ≤ 3 cm = nodule; ≤ 1 cm = micronodule", TABLE_B),
     Paragraph("Primary lung cancer, metastasis, carcinoid, hamartoma, abscess, granuloma", TABLE_B),
     Paragraph("Spiculated margins → malignancy; calcified smooth → benign", TABLE_B)],
    [Paragraph("Pulmonary Oedema", TABLE_B),
     Paragraph("'Bat-wing' / 'butterfly' perihilar haze, Kerley B lines, cephalization", TABLE_B),
     Paragraph("Cardiogenic (CCF, MI), ARDS, fluid overload, neurogenic oedema", TABLE_B),
     Paragraph("Cardiomegaly + effusions → cardiogenic", TABLE_B)],
    [Paragraph("Hyperinflation", TABLE_B),
     Paragraph("Flat diaphragms, barrel chest, > 10 posterior ribs, increased AP diameter", TABLE_B),
     Paragraph("COPD (emphysema), severe asthma attack", TABLE_B),
     Paragraph("Bullae may be visible in emphysema", TABLE_B)],
]
story.append(box_table(pattern_data, [30*mm, 43*mm, 60*mm, 37*mm]))
story.append(Spacer(1, 5*mm))

# ════════════════════════════════════════════════════════════════════════════
# SECTION 5 — SILHOUETTE SIGN
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header("5.  THE SILHOUETTE SIGN", TEAL))
story.append(Spacer(1, 3*mm))

story.append(Paragraph(
    "The silhouette sign occurs when an opacity lies in the <b>same plane</b> as a cardiac/mediastinal border, "
    "causing that border to disappear. It localises the lesion to a specific lobe or segment.",
    BODY))
story.append(Spacer(1, 2*mm))

sil_data = [
    [Paragraph("Border Lost", TABLE_H), Paragraph("Structure Touching It", TABLE_H),
     Paragraph("Lobe / Segment Involved", TABLE_H), Paragraph("Common Cause", TABLE_H)],
    [Paragraph("Right heart border", TABLE_B), Paragraph("Right heart", TABLE_B),
     Paragraph("Right middle lobe (RML)", TABLE_B),
     Paragraph("RML pneumonia / collapse", TABLE_B)],
    [Paragraph("Left heart border", TABLE_B), Paragraph("Left ventricle", TABLE_B),
     Paragraph("Lingula (left upper lobe)", TABLE_B),
     Paragraph("Lingular pneumonia", TABLE_B)],
    [Paragraph("Right hemidiaphragm", TABLE_B), Paragraph("Diaphragm", TABLE_B),
     Paragraph("Right lower lobe (RLL)", TABLE_B),
     Paragraph("RLL consolidation / effusion", TABLE_B)],
    [Paragraph("Left hemidiaphragm", TABLE_B), Paragraph("Diaphragm", TABLE_B),
     Paragraph("Left lower lobe (LLL)", TABLE_B),
     Paragraph("LLL consolidation", TABLE_B)],
    [Paragraph("Aortic knob", TABLE_B), Paragraph("Aorta", TABLE_B),
     Paragraph("Apical left upper lobe", TABLE_B),
     Paragraph("LUL apical consolidation", TABLE_B)],
]
story.append(box_table(sil_data, [42*mm, 38*mm, 50*mm, 40*mm], header_colour=TEAL))
story.append(Spacer(1, 5*mm))

# ════════════════════════════════════════════════════════════════════════════
# SECTION 6 — LOBAR COLLAPSE PATTERNS
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header("6.  LOBAR COLLAPSE PATTERNS"))
story.append(Spacer(1, 3*mm))

collapse_data = [
    [Paragraph("Lobe", TABLE_H), Paragraph("Trachea / Mediastinum", TABLE_H),
     Paragraph("Fissure Movement", TABLE_H), Paragraph("Opacity Location", TABLE_H)],
    [Paragraph("Right Upper Lobe (RUL)", TABLE_B),
     Paragraph("Trachea deviated right; elevated right hilum", TABLE_B),
     Paragraph("Minor fissure moves up; major fissure moves up", TABLE_B),
     Paragraph("Right upper zone — 'S-sign of Golden' if mass", TABLE_B)],
    [Paragraph("Right Middle Lobe (RML)", TABLE_B),
     Paragraph("Minimal shift", TABLE_B),
     Paragraph("Minor fissure moves down", TABLE_B),
     Paragraph("Triangular opacity at right heart border; loses right heart border (silhouette sign)", TABLE_B)],
    [Paragraph("Right Lower Lobe (RLL)", TABLE_B),
     Paragraph("Mediastinum may shift right", TABLE_B),
     Paragraph("Major fissure moves posteriorly / inferiorly", TABLE_B),
     Paragraph("Triangular opacity behind right heart, obscures right hemidiaphragm", TABLE_B)],
    [Paragraph("Left Upper Lobe (LUL)", TABLE_B),
     Paragraph("Trachea may shift left", TABLE_B),
     Paragraph("Major fissure moves anteriorly", TABLE_B),
     Paragraph("Veil-like haze over left hemithorax; 'Luftsichel' sign (air crescent around aortic knob)", TABLE_B)],
    [Paragraph("Left Lower Lobe (LLL)", TABLE_B),
     Paragraph("Mediastinum may shift left", TABLE_B),
     Paragraph("Major fissure moves posteriorly", TABLE_B),
     Paragraph("Triangular opacity behind the heart; 'sail sign'; obscures left hemidiaphragm", TABLE_B)],
]
story.append(box_table(collapse_data, [32*mm, 42*mm, 45*mm, 51*mm]))
story.append(Spacer(1, 5*mm))

# PAGE BREAK
story.append(PageBreak())

# ════════════════════════════════════════════════════════════════════════════
# SECTION 7 — LINES & TUBES
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header("7.  LINES, TUBES & DEVICES — CORRECT POSITIONS", TEAL))
story.append(Spacer(1, 3*mm))

tubes_data = [
    [Paragraph("Device", TABLE_H), Paragraph("Correct Position", TABLE_H),
     Paragraph("Malposition Signs", TABLE_H)],
    [Paragraph("Endotracheal Tube (ETT)", TABLE_B),
     Paragraph("Tip 3–5 cm above carina; at level of T3–T4 with head neutral", TABLE_B),
     Paragraph("Too low → right mainstem intubation (right lung hyperinflated, left collapsed). Too high → extubation risk.", TABLE_B)],
    [Paragraph("Central Venous Catheter (CVC)", TABLE_B),
     Paragraph("Tip at cavoatrial junction or distal SVC (T4–T6 level)", TABLE_B),
     Paragraph("Too far → into right ventricle (arrhythmia risk). Pneumothorax on ipsilateral side.", TABLE_B)],
    [Paragraph("Chest Drain / Intercostal Drain", TABLE_B),
     Paragraph("Apical for pneumothorax; basal for effusion. Tip in pleural space", TABLE_B),
     Paragraph("Tip in fissure → poor drainage. Kinked tube. Subcutaneous emphysema.", TABLE_B)],
    [Paragraph("Nasogastric Tube (NGT)", TABLE_B),
     Paragraph("Tip in stomach, below left hemidiaphragm, on the left side of midline", TABLE_B),
     Paragraph("Coiling in oesophagus. Tip in right lung → risk of pulmonary instillation.", TABLE_B)],
    [Paragraph("Pacemaker / AICD leads", TABLE_B),
     Paragraph("RA lead in right atrial appendage; RV lead at RV apex; LV lead via coronary sinus", TABLE_B),
     Paragraph("Lead fracture, displacement, perforation into pericardium.", TABLE_B)],
    [Paragraph("PICC Line", TABLE_B),
     Paragraph("Tip at cavoatrial junction (same as CVC)", TABLE_B),
     Paragraph("Tip in axillary/subclavian vein is malpositioned. Tip too far into RV.", TABLE_B)],
]
story.append(box_table(tubes_data, [38*mm, 64*mm, 68*mm], header_colour=TEAL))
story.append(Spacer(1, 5*mm))

# ════════════════════════════════════════════════════════════════════════════
# SECTION 8 — SPECIFIC DIAGNOSES AT A GLANCE
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header("8.  SPECIFIC DIAGNOSES AT A GLANCE"))
story.append(Spacer(1, 3*mm))

diag_data = [
    [Paragraph("Diagnosis", TABLE_H), Paragraph("Classic CXR Features", TABLE_H),
     Paragraph("Key Differentiating Point", TABLE_H)],
    [Paragraph("Community-acquired Pneumonia", TABLE_B),
     Paragraph("Lobar / segmental consolidation with air bronchogram; unilateral", TABLE_B),
     Paragraph("Silhouette sign localises lobe; Strep. pneumoniae = lobar, Mycoplasma = bilateral interstitial", TABLE_B)],
    [Paragraph("Pulmonary Oedema (CCF)", TABLE_B),
     Paragraph("Cardiomegaly, perihilar haze, Kerley B lines, pleural effusions (bilateral), upper lobe blood diversion (cephalization)", TABLE_B),
     Paragraph("'ABCDE' of CCF: Alveolar oedema, Kerley B lines, Cardiomegaly, Dilated upper lobes, Effusions", TABLE_B)],
    [Paragraph("ARDS", TABLE_B),
     Paragraph("Bilateral diffuse alveolar infiltrates (ground-glass); no cardiomegaly; no Kerley B lines", TABLE_B),
     Paragraph("Unlike CCF: no cardiomegaly, no Kerley B, history of sepsis/trauma", TABLE_B)],
    [Paragraph("Pulmonary Embolism (PE)", TABLE_B),
     Paragraph("Often normal. Hampton's hump (wedge-shaped pleural opacity). Westermark sign (oligaemia). Palla's sign (dilated PA).", TABLE_B),
     Paragraph("CXR cannot exclude PE — CTPA is required", TABLE_B)],
    [Paragraph("Sarcoidosis", TABLE_B),
     Paragraph("Bilateral hilar lymphadenopathy (BHL) ± parenchymal infiltrates; Stage I = BHL only", TABLE_B),
     Paragraph("Symmetrical BHL is almost pathognomonic; ACE level elevated", TABLE_B)],
    [Paragraph("Tuberculosis (Primary)", TABLE_B),
     Paragraph("Ghon focus (lower/mid zone) + hilar node = Ranke complex; pleural effusion; no cavitation", TABLE_B),
     Paragraph("Primary TB: lower zone opacity + unilateral hilar LN", TABLE_B)],
    [Paragraph("Tuberculosis (Post-primary)", TABLE_B),
     Paragraph("Upper lobe cavitation, fibrosis, patchy consolidation; bilateral; old calcified nodules", TABLE_B),
     Paragraph("Upper lobe cavity: always think post-primary TB until proven otherwise", TABLE_B)],
    [Paragraph("Tension Pneumothorax", TABLE_B),
     Paragraph("Tracheal deviation away from affected side; complete lung collapse; depressed ipsilateral diaphragm", TABLE_B),
     Paragraph("Medical emergency — do NOT wait for CT; needle decompression first", TABLE_B)],
    [Paragraph("Aortic Dissection", TABLE_B),
     Paragraph("Widened mediastinum > 8 cm; indistinct aortic knob; left pleural effusion; tracheal deviation right", TABLE_B),
     Paragraph("Any mediastinal widening in chest pain → urgent CT aortogram", TABLE_B)],
    [Paragraph("Mesothelioma", TABLE_B),
     Paragraph("Unilateral pleural thickening / lobulated pleural mass; pleural effusion; volume loss on affected side", TABLE_B),
     Paragraph("Unlike effusion: pleural thickening persists after drainage; asbestos history", TABLE_B)],
    [Paragraph("Lung Cancer", TABLE_B),
     Paragraph("Hilar mass, peripheral nodule/mass, mediastinal widening, collapse, unilateral effusion, rib destruction", TABLE_B),
     Paragraph("Any new mass > 3 cm, cavitating lesion, or Pancoast (apical) tumour → urgent CT + bronchoscopy", TABLE_B)],
]
story.append(box_table(diag_data, [40*mm, 74*mm, 56*mm]))
story.append(Spacer(1, 5*mm))

# ════════════════════════════════════════════════════════════════════════════
# SECTION 9 — QUICK PATTERN MATCHING MNEMONICS
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header("9.  QUICK MNEMONICS", TEAL))
story.append(Spacer(1, 3*mm))

mnem_left = [
    ["RIPE", "Technical Adequacy", "Rotation, Inspiration, Projection, Exposure"],
    ["ABCDE", "Systematic Review", "Airway, Breathing (Lungs), Cardiac/Mediastinum, Diaphragm, Everything Else"],
    ["5 T's", "Superior Mediastinal Mass", "Thymoma, Teratoma, Terrible lymphoma, Thyroid, Thoracic aortic aneurysm"],
    ["CT ratio", "Cardiomegaly", "≥ 0.5 on PA = cardiomegaly"],
    ["Hampton's Hump", "PE", "Wedge-shaped pleural-based opacity in PE"],
    ["Luftsichel", "LUL Collapse", "Air crescent around aortic knob in left upper lobe collapse"],
    ["S-sign of Golden", "RUL Collapse + Mass", "S-shaped minor fissure — hilar mass causing RUL collapse"],
    ["Westermark sign", "PE", "Focal oligaemia (reduced vascular markings) distal to PE"],
]

mnem_data = [[Paragraph("Mnemonic / Sign", TABLE_H), Paragraph("Used For", TABLE_H), Paragraph("Meaning", TABLE_H)]]
for row in mnem_left:
    mnem_data.append([Paragraph(f"<b>{row[0]}</b>", TABLE_B), Paragraph(row[1], TABLE_B), Paragraph(row[2], TABLE_B)])

story.append(box_table(mnem_data, [38*mm, 40*mm, 92*mm], header_colour=TEAL))
story.append(Spacer(1, 5*mm))

# ════════════════════════════════════════════════════════════════════════════
# SECTION 10 — EMERGENCY FINDINGS
# ════════════════════════════════════════════════════════════════════════════
story.append(section_header("10.  DO NOT MISS — EMERGENCY CXR FINDINGS", colors.HexColor("#8B0000")))
story.append(Spacer(1, 3*mm))

emerg_data = [
    [Paragraph("Finding", TABLE_H), Paragraph("CXR Sign", TABLE_H),
     Paragraph("Immediate Action", TABLE_H)],
    [Paragraph("Tension Pneumothorax", TABLE_B),
     Paragraph("Tracheal deviation away, absent lung markings, depressed diaphragm", TABLE_B),
     Paragraph("Needle decompression 2nd ICS MCL immediately", TABLE_B)],
    [Paragraph("Massive Haemothorax", TABLE_B),
     Paragraph("Unilateral complete opacification, trachea deviates away", TABLE_B),
     Paragraph("Large-bore chest drain, cross-match, surgical review", TABLE_B)],
    [Paragraph("Aortic Dissection", TABLE_B),
     Paragraph("Widened mediastinum, blurred aortic knob, left haemothorax", TABLE_B),
     Paragraph("Urgent CT aortogram, cardiothoracic surgery consult", TABLE_B)],
    [Paragraph("ETT in Right Mainstem", TABLE_B),
     Paragraph("Tip below carina level, left lung collapse", TABLE_B),
     Paragraph("Withdraw ETT, recheck position", TABLE_B)],
    [Paragraph("Free Air Under Diaphragm", TABLE_B),
     Paragraph("Crescentic lucency below right hemidiaphragm (erect film)", TABLE_B),
     Paragraph("Perforated viscus — urgent surgical review", TABLE_B)],
    [Paragraph("Malpositioned NGT", TABLE_B),
     Paragraph("Tip in lung, or coiling in oesophagus", TABLE_B),
     Paragraph("Do NOT feed — resite tube", TABLE_B)],
]
t_emerg = Table(emerg_data, colWidths=[40*mm, 70*mm, 60*mm], repeatRows=1)
t_emerg.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0),  colors.HexColor("#8B0000")),
    ("TEXTCOLOR",     (0,0), (-1,0),  WHITE),
    ("FONTNAME",      (0,0), (-1,0),  "Helvetica-Bold"),
    ("FONTSIZE",      (0,0), (-1,0),  9),
    ("ALIGN",         (0,0), (-1,0),  "CENTER"),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ("GRID",          (0,0), (-1,-1), 0.4, GREY_LINE),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("RIGHTPADDING",  (0,0), (-1,-1), 5),
    ("BACKGROUND",    (0,1), (-1,-1), LIGHT_ORANGE),
    ("FONTNAME",      (0,1), (-1,-1), "Helvetica"),
    ("FONTSIZE",      (0,1), (-1,-1), 8.5),
]))
story.append(t_emerg)
story.append(Spacer(1, 5*mm))

# ════════════════════════════════════════════════════════════════════════════
# FOOTER NOTE
# ════════════════════════════════════════════════════════════════════════════
story.append(HRFlowable(width=W, thickness=0.5, color=GREY_LINE))
story.append(Spacer(1, 2*mm))
story.append(Paragraph(
    "This quick reference is intended as a clinical aide-mémoire for healthcare professionals. "
    "All radiological findings must be interpreted in clinical context. "
    "Always correlate with patient history, examination, and additional investigations. "
    "This document does not replace formal radiological reporting.",
    SMALL))

# ── Build ─────────────────────────────────────────────────────────────────────
def add_page_number(canvas, doc):
    canvas.saveState()
    canvas.setFont("Helvetica", 8)
    canvas.setFillColor(colors.grey)
    page_num = canvas.getPageNumber()
    canvas.drawCentredString(A4[0]/2, 8*mm, f"CXR Quick Reference  ·  Page {page_num}")
    canvas.restoreState()

doc.build(story, onFirstPage=add_page_number, onLaterPages=add_page_number)
print(f"PDF created: {OUTPUT}")
Running Command

cd /tmp/workspace/cxr-reference && python make_cxr_pdf.py 2>&1

Running Command

ls -lh /tmp/workspace/cxr-reference/CXR_Quick_Reference.pdf

Your PDF is ready! Here's the download link:

CXR Quick Reference

PDF Document · PDF


What's Inside (10 Sections)

SectionContent
1. RIPE ChecklistTechnical adequacy - Rotation, Inspiration, Projection, Exposure
2. ABCDE ApproachSystematic review framework for every CXR
3. Key MeasurementsCT ratio, mediastinal width, carina angle, diaphragm heights with normal values
4. Opacity PatternsConsolidation, collapse, effusion, pneumothorax, interstitial, miliary, cavitation, mass, pulmonary oedema, hyperinflation
5. Silhouette SignWhich border loss localises which lobe
6. Lobar CollapseTrachea shift, fissure movement, and opacity location for all 5 lobes
7. Lines & TubesCorrect positions and malposition signs for ETT, CVC, NGT, chest drain, pacemaker, PICC
8. Specific DiagnosesClassic features of 11 conditions (pneumonia, CCF, ARDS, PE, sarcoidosis, TB, tension pneumothorax, aortic dissection, mesothelioma, lung cancer)
9. MnemonicsRIPE, ABCDE, Hampton's Hump, Luftsichel, S-sign of Golden, Westermark, and more
10. Don't MissEmergency findings requiring immediate action (highlighted in red)

Histology slides Of thyroid Duodenum pancreas hyaline

Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Loading Image
Loading Image
Loading Image
Loading Image
Loading Image
Reading File
Reading File
Reading File
Loading Image
Reading File
Reading File
Loading Image
Loading Image
Reading File
Loading Image
I now have all the images and content needed. Here is the comprehensive histology explanation:

Histology Slides: Thyroid, Duodenum, Pancreas & Hyaline


1. THYROID GLAND

Histology Slide

Thyroid follicles - H&E stained, showing follicular cells and colloid
Normal thyroid parenchyma (H&E). Large pale-pink colloid-filled follicles lined by a single layer of cuboidal follicular cells. Blood vessels run in the interfollicular stroma. - Sabiston Textbook of Surgery

What You See on the Slide

StructureAppearanceFunction
FolliclesSpherical spaces ~30 µm diameter; ~20-40 per lobuleStructural unit of the thyroid
ColloidHomogeneous, pale eosinophilic (pink) material filling the follicle lumenStorage form of thyroglobulin (inactive T3/T4)
Follicular cells (thyrocytes)Single layer of cuboidal to low columnar cells lining each follicleSynthesise T3 and T4
Parafollicular (C) cellsLarger pale cells scattered in interfollicular stroma, especially upper polesSecrete calcitonin (calcium regulation)
Fibrous septaThin connective tissue dividing the gland into lobulesSupport and vascularity

Key Functional Points

  • Active gland: follicular cells become taller (columnar), colloid appears vacuolated at edges ("resorption vacuoles")
  • Inactive/suppressed gland: follicular cells flatten (squamous), colloid is dense and abundant
  • Hormone synthesis: TSH → cAMP → follicular cells take up iodide → iodinate thyroglobulin in colloid → resorb it back → release T3/T4 into blood

2. DUODENUM

Histology Slide

Duodenum H&E showing villi, crypts, and Brunner glands in submucosa
Duodenal wall H&E. Top: tall finger-like villi lined by absorptive epithelium. Middle (dashed line): base of villi / crypts of Lieberkühn. Bottom: submucosa containing the hallmark Brunner glands. - Histology: A Text and Atlas (Pawlina)

What You See on the Slide

LayerStructureAppearanceSignificance
MucosaVilliTall finger-like projections lined by columnar absorptive cells + goblet cellsMassively increases surface area for absorption
MucosaCrypts of LieberkühnTubular glands at base of villiContain stem cells, Paneth cells, enteroendocrine cells
MucosaMuscularis mucosaeThin smooth muscle layerSeparates mucosa from submucosa
SubmucosaBrunner glandsBranched tubular mucous glands - UNIQUE TO DUODENUMSecrete alkaline (pH 8.1-9.3) mucus + bicarbonate - neutralise gastric acid chyme
Muscularis externaInner circular + outer longitudinal smooth muscleTwo muscle layersPeristalsis + segmentation

Key Distinguishing Feature

Brunner glands in the submucosa = hallmark of duodenum. No other part of the GI tract has submucosal glands (except the oesophagus). Their alkaline secretion protects the duodenal mucosa from acid and activates pancreatic enzymes.

3. PANCREAS

The pancreas is a dual gland - exocrine and endocrine components side by side.

Exocrine Pancreas: Acinar Cells

Pancreatic acinus H&E and diagram - acinar cells, centroacinar cells, intercalated duct
Pancreatic acinus - H&E (top) and schematic (bottom). Pyramidal acinar cells with zymogen granules (red apical dots), centroacinar cells at the duct opening, and the intercalated duct. - Histology: A Text and Atlas (Pawlina)
Electron micrograph of pancreatic acinar cells - Z = zymogen granules, rER, G = Golgi
EM of pancreatic acinar cells. Z = large round zymogen granules at apical pole; rER = abundant rough ER at basal pole (basophilia on H&E); G = Golgi; M = mitochondria; L = lumen of acinus; JC = junctional complex. - Histology: A Text and Atlas (Pawlina)

Endocrine Pancreas: Islets of Langerhans

Pancreas H&E - arrows pointing to islets of Langerhans scattered among acini
Pancreas low-power H&E. The dark purple background = densely packed exocrine acini. Arrows point to islets of Langerhans - paler, less densely staining rounded clusters of endocrine cells amid the acini. - Histology: A Text and Atlas (Pawlina)

What You See on the Slide

ComponentAppearanceCell TypesFunction
Exocrine aciniRounded clusters of pyramidal cells; basophilic basal cytoplasm (rER), eosinophilic apical zymogen granulesAcinar cells (serous); centroacinar cellsDigest proteins, fats, carbohydrates, nucleic acids
Centroacinar cellsSmall pale cells at the centre of acinus where duct beginsSpecial to pancreasLine intercalated ducts; secrete HCO₃⁻
Intercalated ductsVery thin ducts originating inside the acinus - unique to pancreasDuct epitheliumDrain acini; add bicarbonate
Islets of LangerhansPale, rounded clusters 1-3 million throughout pancreas (~1-2% volume); well-vascularised by fenestrated capillariesα cells (glucagon), β cells (insulin), δ cells (somatostatin), PP cellsBlood glucose regulation

Zymogen Granules (Exam Favourite)

  • Located at the apical pole of acinar cells
  • Appear bright red/eosinophilic on H&E
  • Most numerous in fasting individuals
  • Contain inactive proenzymes (trypsinogen, chymotrypsinogen, lipase, amylase) - activated only in duodenum

4. HYALINE (Histological Term)

"Hyaline" (from Greek hyalos = glass) is a descriptive histological term - not one specific substance. It means any tissue that appears homogeneous, glassy, and pink (eosinophilic) on H&E stain.

Hyaline Cartilage (Most Common Type)

Hyaline cartilage, elastic cartilage, fibrocartilage comparison with distribution diagram
Three types of cartilage: (b) Hyaline cartilage - glassy matrix with chondrocytes in lacunae, dense perichondrium. (c) Elastic cartilage - visible elastic fibres in matrix. (d) Fibrocartilage - parallel collagen bundles, no perichondrium. - Junqueira's Basic Histology

What You See in Hyaline Cartilage

StructureAppearanceSignificance
MatrixHomogeneous, glassy blue-purple (H&E) - appears "hyaline"Type II collagen + proteoglycans + water - shock absorption
ChondrocytesRound cells in lacunae (spaces); may appear in isogenous groupsProduce and maintain matrix
PerichondriumDense fibrous layer surrounding cartilageAppositional growth, blood supply (cartilage is avascular)
LacunaeEmpty-appearing spaces around chondrocytesShrinkage artifact from fixation

Other Contexts Where "Hyaline" Appears

LocationWhat it MeansAssociated Condition
Arteriole wallsHyaline arteriolosclerosisHypertension, diabetes mellitus
Intracellular (hepatocytes)Alcoholic (Mallory) hyalineAlcoholic liver disease
Renal tubular dropletsReabsorption dropletsNephrotic syndrome
Russell bodies (plasma cells)Immunoglobulin accumulationChronic inflammation
Old scars/tendonsHyalinised collagen fibersPost-scar remodelling
AmyloidCongo red + apple-green birefringenceAmyloidosis
According to Robbins Pathologic Basis of Disease: "The term hyaline usually refers to an alteration within cells or in the extracellular space that gives a homogeneous, glassy, pink appearance in routine H&E sections. It is widely used as a descriptive histologic term rather than a specific marker for cell injury."
This is a shared conversation. Sign in to Orris to start your own chat.