anaesthesia machine checklist protocol

Your credits are exhausted. You can purchase a top-up or subscribe to a plan to continue using Orris. If you're already subscribed, your daily credits will reset tomorrow.

Please make one with flowcharts

Reading File
Finding Sources
Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Running Command

mkdir -p /tmp/workspace/anaesthesia-checklist && ls /tmp/workspace/

Writing File

~/anaesthesia-checklist/build_pptx.py

"""
Anaesthesia Machine Checklist Protocol - PowerPoint with Flowcharts
Based on ASA Recommendations for Pre-Anesthesia Checkout Procedures (2008)
Source: Miller's Anesthesia 10e & Barash Clinical Anesthesia 9e
"""

from pptx import Presentation
from pptx.util import Inches, Pt, Emu
from pptx.dml.color import RGBColor
from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
from pptx.enum.shapes import MSO_SHAPE_TYPE
from pptx.oxml.ns import qn
from pptx.oxml import parse_xml
import lxml.etree as etree
from io import BytesIO

# ── Colour Palette ──────────────────────────────────────────────────────────
DARK_BLUE   = RGBColor(0x1A, 0x3A, 0x5C)   # headings / title bg
MED_BLUE    = RGBColor(0x2E, 0x6D, 0xA8)   # section headers
LIGHT_BLUE  = RGBColor(0xD6, 0xE8, 0xF7)   # step boxes bg
TEAL        = RGBColor(0x00, 0x87, 0x8A)   # daily items
GREEN       = RGBColor(0x2A, 0x7A, 0x4B)   # per-case items
AMBER       = RGBColor(0xE8, 0x8B, 0x00)   # warnings / critical
RED         = RGBColor(0xC0, 0x39, 0x2B)   # FAIL / stop
WHITE       = RGBColor(0xFF, 0xFF, 0xFF)
LIGHT_GRAY  = RGBColor(0xF4, 0xF6, 0xF9)
MID_GRAY    = RGBColor(0x88, 0x96, 0xA7)
DARK_GRAY   = RGBColor(0x33, 0x33, 0x33)
YELLOW_BG   = RGBColor(0xFF, 0xF3, 0xCD)
GREEN_BG    = RGBColor(0xD4, 0xED, 0xDA)
RED_BG      = RGBColor(0xF8, 0xD7, 0xDA)

prs = Presentation()
prs.slide_width  = Inches(13.333)
prs.slide_height = Inches(7.5)
blank = prs.slide_layouts[6]

# ─────────────────────────────────────────────────────────────────────────────
# Helper utilities
# ─────────────────────────────────────────────────────────────────────────────

def add_rect(slide, x, y, w, h, fill_rgb, border_rgb=None, border_pt=1.5, radius=None):
    """Add a filled rectangle (optionally with rounded corners)."""
    shape = slide.shapes.add_shape(
        1,  # MSO_SHAPE_TYPE.RECTANGLE
        Inches(x), Inches(y), Inches(w), Inches(h)
    )
    shape.fill.solid()
    shape.fill.fore_color.rgb = fill_rgb
    if border_rgb:
        shape.line.color.rgb = border_rgb
        shape.line.width = Pt(border_pt)
    else:
        shape.line.fill.background()
    return shape


def add_text_box(slide, text, x, y, w, h, font_size=12, bold=False,
                 color=DARK_GRAY, align=PP_ALIGN.LEFT, wrap=True,
                 v_anchor=MSO_ANCHOR.MIDDLE, italic=False):
    tb = slide.shapes.add_textbox(Inches(x), Inches(y), Inches(w), Inches(h))
    tf = tb.text_frame
    tf.word_wrap = wrap
    tf.vertical_anchor = v_anchor
    tf.margin_left  = Pt(4)
    tf.margin_right = Pt(4)
    tf.margin_top   = Pt(2)
    tf.margin_bottom= Pt(2)
    p = tf.paragraphs[0]
    p.alignment = align
    r = p.add_run()
    r.text = text
    r.font.size   = Pt(font_size)
    r.font.bold   = bold
    r.font.italic = italic
    r.font.color.rgb = color
    r.font.name = "Calibri"
    return tb


def add_label_box(slide, text, x, y, w, h, fill, border=None,
                  font_size=11, bold=False, color=DARK_GRAY,
                  align=PP_ALIGN.CENTER, wrap=True):
    """A combined filled rect + centred text."""
    add_rect(slide, x, y, w, h, fill, border_rgb=border)
    add_text_box(slide, text, x, y, w, h,
                 font_size=font_size, bold=bold, color=color,
                 align=align, wrap=wrap)


def add_arrow_v(slide, x, y_top, length, color=MID_GRAY):
    """Vertical downward arrow."""
    cx = Inches(x)
    cy = Inches(y_top)
    cw = Inches(0.02)
    ch = Inches(length)
    conn = slide.shapes.add_connector(1, cx, cy, cx, cy + ch)  # straight
    conn.line.color.rgb = color
    conn.line.width = Pt(1.5)


def add_slide_header(slide, title, subtitle=None):
    """Standard slide header bar."""
    add_rect(slide, 0, 0, 13.333, 0.9, DARK_BLUE)
    add_text_box(slide, title, 0.3, 0.05, 10, 0.8,
                 font_size=22, bold=True, color=WHITE, align=PP_ALIGN.LEFT)
    if subtitle:
        add_text_box(slide, subtitle, 0.3, 0.6, 10, 0.35,
                     font_size=11, color=RGBColor(0xAA, 0xCC, 0xEE),
                     align=PP_ALIGN.LEFT)


def add_footer(slide, text="Source: Miller's Anesthesia 10e | ASA Pre-Anesthesia Checkout Recommendations 2008"):
    add_rect(slide, 0, 7.2, 13.333, 0.3, RGBColor(0xEC, 0xF0, 0xF5))
    add_text_box(slide, text, 0.3, 7.2, 12.7, 0.3,
                 font_size=8, color=MID_GRAY, align=PP_ALIGN.LEFT,
                 v_anchor=MSO_ANCHOR.MIDDLE)


# ═════════════════════════════════════════════════════════════════════════════
# SLIDE 1 – Title Slide
# ═════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)

# Dark gradient background
add_rect(slide, 0, 0, 13.333, 7.5, DARK_BLUE)
add_rect(slide, 0, 4.5, 13.333, 3.0, MED_BLUE)

# Accent bar
add_rect(slide, 0.4, 1.6, 0.08, 3.5, AMBER)

add_text_box(slide, "ANAESTHESIA MACHINE", 0.7, 1.3, 11, 1.0,
             font_size=36, bold=True, color=WHITE, align=PP_ALIGN.LEFT)
add_text_box(slide, "CHECKLIST PROTOCOL", 0.7, 2.15, 11, 1.0,
             font_size=36, bold=True, color=RGBColor(0xAA, 0xD4, 0xF5),
             align=PP_ALIGN.LEFT)
add_text_box(slide, "Pre-Anaesthesia Checkout (PAC) Flowchart Guide", 0.7, 3.2, 11, 0.5,
             font_size=16, color=RGBColor(0xCC, 0xE0, 0xF0), align=PP_ALIGN.LEFT)
add_text_box(slide,
    "Based on: ASA Recommendations for Pre-Anesthesia Checkout Procedures (2008)\n"
    "Miller's Anesthesia 10e  |  Barash Clinical Anesthesia 9e  |  FDA Checkout Guidelines",
    0.7, 3.8, 11, 0.7, font_size=11, color=RGBColor(0x88, 0xAA, 0xCC),
    align=PP_ALIGN.LEFT)

# Bottom legend
boxes = [
    ("DAILY", TEAL,   "Perform once\nbefore first case"),
    ("EACH CASE", GREEN,  "Repeat before\nevery case"),
    ("CRITICAL", AMBER,  "Most safety-\ncritical items"),
]
for i, (lbl, col, desc) in enumerate(boxes):
    bx = 1.0 + i * 3.8
    add_rect(slide, bx, 5.1, 1.4, 0.5, col)
    add_text_box(slide, lbl, bx, 5.1, 1.4, 0.5,
                 font_size=13, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
    add_text_box(slide, desc, bx + 1.5, 5.1, 2.1, 0.5,
                 font_size=10, color=WHITE, align=PP_ALIGN.LEFT)


# ═════════════════════════════════════════════════════════════════════════════
# SLIDE 2 – Overview Flowchart (Pre-Anaesthesia Checkout Overview)
# ═════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GRAY)
add_slide_header(slide, "Pre-Anaesthesia Checkout (PAC) – Overview Flowchart",
                 "Complete workflow from start of day to anaesthesia induction")
add_footer(slide)

# Central flowchart column (left half)
fc_items = [
    ("START OF DAY", DARK_BLUE,    WHITE,  True),
    ("Daily Checks\n(Items 1, 3, 5–10)", TEAL,  WHITE,  True),
    ("Per-Case Checks\n(Items 2, 4, 11–15)", GREEN, WHITE,  True),
    ("ANESTHESIA TIME-OUT\n(Item 15)", AMBER, WHITE,  True),
    ("COMMENCE ANESTHESIA", MED_BLUE, WHITE, True),
]

col_x = 1.0
box_w = 3.6
box_h = 0.65
gap   = 0.22
start_y = 1.1

for i, (lbl, fill, tcol, bold) in enumerate(fc_items):
    y = start_y + i * (box_h + gap)
    add_rect(slide, col_x, y, box_w, box_h, fill, border_rgb=MED_BLUE, border_pt=1)
    add_text_box(slide, lbl, col_x, y, box_w, box_h,
                 font_size=11, bold=bold, color=tcol, align=PP_ALIGN.CENTER)
    if i < len(fc_items) - 1:
        arr_y = y + box_h
        add_rect(slide, col_x + box_w/2 - 0.01, arr_y, 0.02, gap * 0.8, MID_GRAY)

# Decision diamond after each group
def draw_diamond(slide, cx, cy, w, h, fill, border, text, font_size=9, text_color=WHITE):
    """Approximate diamond with a rotated rectangle textbox + border shape."""
    shape = slide.shapes.add_shape(
        4,  # DIAMOND
        Inches(cx - w/2), Inches(cy - h/2), Inches(w), Inches(h)
    )
    shape.fill.solid()
    shape.fill.fore_color.rgb = fill
    shape.line.color.rgb = border
    shape.line.width = Pt(1.5)
    add_text_box(slide, text, cx - w/2, cy - h/2, w, h,
                 font_size=font_size, bold=True, color=text_color,
                 align=PP_ALIGN.CENTER)

# Decision diamond 1: after daily checks
d1_y = start_y + 1*(box_h + gap) + box_h + 0.05
draw_diamond(slide, col_x + box_w/2, d1_y + 0.3, 2.0, 0.55,
             AMBER, DARK_BLUE, "All daily checks\npassed?")
add_text_box(slide, "NO → Investigate & fix\nbefore proceeding",
             col_x + box_w/2 + 1.1, d1_y + 0.1, 3.0, 0.6,
             font_size=9, color=RED, bold=False)

# Decision diamond 2: after per-case checks
d2_y = start_y + 2*(box_h + gap) + box_h + 0.05
draw_diamond(slide, col_x + box_w/2, d2_y + 0.3, 2.0, 0.55,
             AMBER, DARK_BLUE, "Per-case checks\npassed?")
add_text_box(slide, "NO → Do not proceed\nAlert attending",
             col_x + box_w/2 + 1.1, d2_y + 0.1, 3.0, 0.6,
             font_size=9, color=RED, bold=False)

# Right panel – key requirements
add_rect(slide, 5.2, 1.0, 7.7, 5.9, WHITE, border_rgb=MED_BLUE, border_pt=1)
add_rect(slide, 5.2, 1.0, 7.7, 0.45, MED_BLUE)
add_text_box(slide, "7 BASIC REQUIREMENTS FOR SAFE ANESTHESIA DELIVERY  (ASA 2008)",
             5.3, 1.0, 7.5, 0.45, font_size=10, bold=True, color=WHITE, align=PP_ALIGN.CENTER)

reqs = [
    ("1", "Reliable delivery of O₂ at any appropriate concentration up to 100%"),
    ("2", "Reliable means of positive-pressure ventilation"),
    ("3", "Backup ventilation equipment available and functioning"),
    ("4", "Controlled release of positive pressure from breathing circuit"),
    ("5", "Anaesthetic vapour delivery (if part of the plan)"),
    ("6", "Adequate suction"),
    ("7", "Means to conform to standards for patient monitoring"),
]
for i, (num, txt) in enumerate(reqs):
    ry = 1.55 + i * 0.7
    add_rect(slide, 5.4, ry, 0.38, 0.5, MED_BLUE)
    add_text_box(slide, num, 5.4, ry, 0.38, 0.5,
                 font_size=14, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
    add_rect(slide, 5.82, ry, 6.85, 0.5, LIGHT_BLUE if i%2==0 else WHITE)
    add_text_box(slide, txt, 5.85, ry, 6.8, 0.5,
                 font_size=10, color=DARK_GRAY, align=PP_ALIGN.LEFT)


# ═════════════════════════════════════════════════════════════════════════════
# SLIDE 3 – Daily Checks Flowchart (Items 1, 3, 5–10)
# ═════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GRAY)
add_slide_header(slide, "DAILY CHECKS – Flowchart  (Perform Once Before First Case)",
                 "Items 1, 3, 5, 6, 7, 8, 9, 10 of ASA PAC Recommendations")
add_footer(slide)

daily_steps = [
    ("ITEM 1", "Verify Auxiliary O₂\nCylinder & Self-Inflating\nResuscitation Bag (SIRB)",
     "• Full O₂ cylinder with flowmeter & wrench\n• SIRB present & functional\n• Close valve after check",
     TEAL),
    ("ITEM 3", "Turn on Workstation;\nConfirm AC Power",
     "• Power on all machine modules\n• Verify green AC power indicator\n• Check battery backup status",
     TEAL),
    ("ITEM 5", "Spare O₂ Cylinder\nPressure Check",
     "• Cylinder gauge: FULL (≥ 2000 psi)\n• Open briefly to verify flow\n• Close valve after check",
     TEAL),
    ("ITEM 6", "Verify Pipeline\nGas Pressure",
     "• O₂: 50–55 psi\n• N₂O: 50–55 psi\n• Air: 50–55 psi\n• All connections secure (DISS fittings)",
     TEAL),
    ("ITEM 7", "Vaporiser(s)\nCheck",
     "• Vaporisers properly seated / interlocked\n• Adequate agent level in each\n• Check for leaks around filler cap",
     TEAL),
    ("ITEM 8", "Verify CO₂\nAbsorbent",
     "• Check colour – not exhausted\n• Replace if >50% colour-changed\n• Ensure no bypassing of absorber",
     TEAL),
    ("ITEM 9", "Breathing System /\nCircle System Check",
     "• Inspect hoses for damage\n• Verify unidirectional valves move freely\n• Perform low-pressure leak test (LPLT)",
     TEAL),
    ("ITEM 10", "Oxygen Analyser\nCalibration",
     "• Expose sensor to room air → calibrate to 21%\n• Reinstall; observe FiO₂ ≥ 90% on O₂ flush\n• Set low-O₂ alarm (≥ 18%)",
     TEAL),
]

# Two-column layout
for i, (num, title, detail, fill) in enumerate(daily_steps):
    col = i % 2
    row = i // 2
    bx = 0.35 + col * 6.5
    by = 1.05 + row * 1.5
    # Main box
    add_rect(slide, bx, by, 6.15, 1.35, WHITE, border_rgb=TEAL, border_pt=1.5)
    # Number tag
    add_rect(slide, bx, by, 1.0, 1.35, fill)
    add_text_box(slide, num, bx, by, 1.0, 1.35,
                 font_size=10, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
    # Title
    add_text_box(slide, title, bx + 1.05, by + 0.02, 2.1, 1.3,
                 font_size=10, bold=True, color=DARK_BLUE, align=PP_ALIGN.LEFT)
    # Detail
    add_rect(slide, bx + 3.2, by, 2.9, 1.35, LIGHT_BLUE)
    add_text_box(slide, detail, bx + 3.25, by + 0.04, 2.8, 1.27,
                 font_size=8.5, color=DARK_GRAY, align=PP_ALIGN.LEFT)

# Arrow connectors between rows
for row in range(3):
    for col in range(2):
        ax = 0.35 + col * 6.5 + 3.075
        ay = 1.05 + row * 1.5 + 1.35
        add_rect(slide, ax, ay, 0.02, 0.15, MID_GRAY)


# ═════════════════════════════════════════════════════════════════════════════
# SLIDE 4 – Per-Case Checks Flowchart (Items 2, 4, 11–15)
# ═════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GRAY)
add_slide_header(slide, "PER-CASE CHECKS – Flowchart  (Repeat Before EVERY Case)",
                 "Items 2, 4, 11, 12, 13, 14, 15 of ASA PAC Recommendations")
add_footer(slide)

per_case_steps = [
    ("ITEM 2",  "Verify Patient Suction\nIs Adequate",
     "• Suction functional & at bedside\n• Yankauer tip connected\n• Tubing of appropriate length",
     GREEN),
    ("ITEM 4",  "Verify Monitors &\nCheck Alarms",
     "• Pulse oximeter probe functional\n• Capnography waveform present\n• Alarms set to defaults",
     GREEN),
    ("ITEM 11", "Verify Breathing System\nPatency & Function",
     "• Visual inspection of circuit integrity\n• Confirm fresh gas flow connection\n• APL valve functional",
     GREEN),
    ("ITEM 12", "Check Scavenging\nSystem",
     "• Scavenging connected to breathing system\n• Positive/negative pressure relief open\n• Adequate scavenging flow",
     GREEN),
    ("ITEM 13", "Check Airway\nEquipment",
     "• Correct ETT sizes available\n• Laryngoscope blades light-tested\n• LMA / video laryngoscope ready",
     GREEN),
    ("ITEM 14", "Check & Confirm\nDrugs / IV Access",
     "• Emergency drugs drawn / labelled\n• IV access patent and secured\n• Syringe labels double-checked",
     GREEN),
    ("ITEM 15", "ANESTHESIA TIME-OUT\n(Final Pre-Induction Check)",
     "• Monitors functional?\n• Capnogram present?\n• SpO₂ measured?\n• Flowmeter/vent settings correct?\n• Manual/vent switch → MANUAL?\n• Vaporiser adequately filled?",
     AMBER),
]

# Vertical flowchart left column (items 2,4,11,12,13,14) + right box for item 15
small_h = 0.78
gap2    = 0.12
for i, (num, title, detail, fill) in enumerate(per_case_steps[:6]):
    by = 1.05 + i * (small_h + gap2)
    bx = 0.35
    add_rect(slide, bx, by, 0.9, small_h, fill)
    add_text_box(slide, num, bx, by, 0.9, small_h,
                 font_size=9, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
    add_rect(slide, bx + 0.95, by, 2.2, small_h, WHITE, border_rgb=GREEN, border_pt=1)
    add_text_box(slide, title, bx + 1.0, by, 2.1, small_h,
                 font_size=9.5, bold=True, color=DARK_BLUE, align=PP_ALIGN.LEFT)
    add_rect(slide, bx + 3.2, by, 3.1, small_h, LIGHT_BLUE)
    add_text_box(slide, detail, bx + 3.25, by, 3.0, small_h,
                 font_size=8, color=DARK_GRAY, align=PP_ALIGN.LEFT)
    # Arrow
    if i < 5:
        add_rect(slide, bx + 0.44, by + small_h, 0.02, gap2, MID_GRAY)

# Item 15 – big highlight box on right
add_rect(slide, 6.8, 1.0, 6.15, 5.8, WHITE, border_rgb=AMBER, border_pt=2.5)
add_rect(slide, 6.8, 1.0, 6.15, 0.5, AMBER)
add_text_box(slide, "⚑  ITEM 15  |  ANAESTHESIA TIME-OUT", 6.9, 1.0, 6.0, 0.5,
             font_size=13, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
add_text_box(slide, "Final Check Immediately Before Induction  (Provider ONLY)",
             6.9, 1.55, 6.0, 0.4,
             font_size=10.5, bold=False, italic=True, color=DARK_BLUE, align=PP_ALIGN.CENTER)

timeout_items = [
    ("✔", "Monitors functional?", WHITE),
    ("✔", "Capnogram present?", WHITE),
    ("✔", "SpO₂ (pulse oximetry) measured?", WHITE),
    ("✔", "Flowmeter & ventilator settings correct?", WHITE),
    ("✔", "Manual/ventilator switch set to MANUAL?", WHITE),
    ("✔", "Vaporiser(s) adequately filled?", WHITE),
]
for j, (sym, text, bg) in enumerate(timeout_items):
    ty = 2.05 + j * 0.65
    add_rect(slide, 6.9, ty, 0.55, 0.55, AMBER if j == 0 else GREEN)
    add_text_box(slide, sym, 6.9, ty, 0.55, 0.55,
                 font_size=14, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
    bg_col = LIGHT_BLUE if j % 2 == 0 else WHITE
    add_rect(slide, 7.5, ty, 5.2, 0.55, bg_col, border_rgb=MID_GRAY, border_pt=0.5)
    add_text_box(slide, text, 7.55, ty, 5.1, 0.55,
                 font_size=11, color=DARK_GRAY, align=PP_ALIGN.LEFT)

add_rect(slide, 6.9, 6.0, 5.85, 0.65, GREEN_BG, border_rgb=GREEN, border_pt=1.5)
add_text_box(slide, "✅  ALL SIX ITEMS CONFIRMED  →  PROCEED TO INDUCTION",
             6.95, 6.0, 5.75, 0.65,
             font_size=11, bold=True, color=GREEN, align=PP_ALIGN.CENTER)

# MS MAIDS mnemonic
add_rect(slide, 6.8, 6.75, 6.15, 0.4, RGBColor(0xE8, 0xF4, 0xFD))
add_text_box(slide, "Mnemonic: MS MAIDS  (Machine · Suction · Monitors · Airway · IV · Drugs · Special equipment)",
             6.85, 6.75, 6.1, 0.4,
             font_size=8.5, color=MED_BLUE, align=PP_ALIGN.CENTER, italic=True)


# ═════════════════════════════════════════════════════════════════════════════
# SLIDE 5 – Low-Pressure Leak Test (LPLT) Flowchart
# ═════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GRAY)
add_slide_header(slide, "Low-Pressure Circuit Leak Test (LPLT) – Step-by-Step Flowchart",
                 "One of the 3 most critical daily checkout steps  |  Barash Clinical Anesthesia 9e, p.2050")
add_footer(slide)

lplt_steps = [
    (TEAL,    "STEP 1",  "Turn off all vaporisers\nand flowmeters"),
    (TEAL,    "STEP 2",  "Turn oxygen flowmeter on\nto minimum flow (100–250 mL/min)"),
    (TEAL,    "STEP 3",  "Occlude the common\ngas outlet (Y-piece or patient port)"),
    (TEAL,    "STEP 4",  "Observe flowmeter bobbin:\nshould fall to zero (or near zero)"),
    (MED_BLUE,"STEP 5",  "Turn each vaporiser on\none at a time; repeat occlude test"),
    (MED_BLUE,"STEP 6",  "Assess results"),
]

box_w2 = 3.0
box_h2 = 0.7
fc_x   = 0.5

for i, (fill, num, text) in enumerate(lplt_steps):
    fx = fc_x
    fy = 1.1 + i * (box_h2 + 0.25)
    if i == 5:  # decision
        draw_diamond(slide, fx + box_w2/2, fy + box_h2/2, box_w2, box_h2 + 0.1,
                     AMBER, DARK_BLUE, text, font_size=10)
    else:
        add_rect(slide, fx, fy, box_w2, box_h2, fill, border_rgb=DARK_BLUE, border_pt=1)
        add_text_box(slide, num, fx, fy, 0.8, box_h2,
                     font_size=9, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
        add_text_box(slide, text, fx + 0.85, fy, box_w2 - 0.9, box_h2,
                     font_size=9.5, color=WHITE, align=PP_ALIGN.LEFT)
    # arrow
    if i < 5:
        add_rect(slide, fx + box_w2/2, fy + box_h2, 0.02, 0.25, MID_GRAY)

# PASS / FAIL branches
pass_x = 3.8
fail_x = 0.5
branch_y = 1.1 + 5 * (box_h2 + 0.25) + box_h2 + 0.15

add_rect(slide, pass_x, branch_y, 2.8, 0.7, GREEN_BG, border_rgb=GREEN, border_pt=1.5)
add_text_box(slide, "✅  PASS\nFlow falls to ≤ 50 mL/min\n→ Proceed with checkout",
             pass_x + 0.05, branch_y, 2.7, 0.7,
             font_size=9, color=GREEN, align=PP_ALIGN.CENTER, bold=True)

add_rect(slide, fail_x - 0.0, branch_y, 2.8, 0.7, RED_BG, border_rgb=RED, border_pt=1.5)
add_text_box(slide, "❌  FAIL\nFlow does not fall → LEAK\n→ Do NOT use machine; notify",
             fail_x, branch_y, 2.75, 0.7,
             font_size=9, color=RED, align=PP_ALIGN.CENTER, bold=True)

# Right side: circle system explanation
add_rect(slide, 7.2, 1.0, 5.8, 5.9, WHITE, border_rgb=MED_BLUE, border_pt=1)
add_rect(slide, 7.2, 1.0, 5.8, 0.5, MED_BLUE)
add_text_box(slide, "CIRCLE BREATHING SYSTEM FUNCTIONAL TEST", 7.3, 1.0, 5.6, 0.5,
             font_size=11, bold=True, color=WHITE, align=PP_ALIGN.CENTER)

circle_steps = [
    ("A", "Set APL (pop-off) valve to\nminimum (OPEN position)"),
    ("B", "Set fresh gas flow (FGF)\nto 5 L/min O₂"),
    ("C", "Occlude Y-piece with thumb;\nsqueeze reservoir bag"),
    ("D", "Pressure gauge should rise;\nAPL valve should open & vent"),
    ("E", "Release Y-piece;\nobserve bag refills freely"),
    ("F", "Perform 'To-and-Fro' test:\ncheck both one-way valves"),
    ("G", "FGF to minimal; observe\nno unintended pressure build-up"),
]
for k, (letter, desc) in enumerate(circle_steps):
    ky = 1.6 + k * 0.67
    add_rect(slide, 7.35, ky, 0.45, 0.58, GREEN)
    add_text_box(slide, letter, 7.35, ky, 0.45, 0.58,
                 font_size=12, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
    add_rect(slide, 7.85, ky, 4.95, 0.58, LIGHT_BLUE if k%2==0 else WHITE)
    add_text_box(slide, desc, 7.9, ky, 4.85, 0.58,
                 font_size=9.5, color=DARK_GRAY, align=PP_ALIGN.LEFT)


# ═════════════════════════════════════════════════════════════════════════════
# SLIDE 6 – Full 15-Item Summary Table
# ═════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GRAY)
add_slide_header(slide, "ASA Pre-Anaesthesia Checkout – All 15 Items Summary",
                 "Miller's Anesthesia 10e, Table 20.6  |  * = Before each case;  D = Daily")
add_footer(slide)

headers = ["#", "Item", "Frequency", "Responsible Party"]
col_widths = [0.5, 6.5, 1.5, 2.7]
col_x_starts = [0.25]
for w in col_widths[:-1]:
    col_x_starts.append(col_x_starts[-1] + w)

# Header row
for j, (hdr, cw, cx) in enumerate(zip(headers, col_widths, col_x_starts)):
    add_rect(slide, cx, 1.0, cw, 0.4, DARK_BLUE)
    add_text_box(slide, hdr, cx, 1.0, cw, 0.4,
                 font_size=10, bold=True, color=WHITE, align=PP_ALIGN.CENTER)

all_items = [
    ("1",  "Verify auxiliary O₂ cylinder & SIRB present",               "Daily",       "Provider + Tech", TEAL),
    ("2",  "Verify patient suction is adequate",                          "Each case",   "Provider + Tech", GREEN),
    ("3",  "Turn on workstation; confirm AC power",                       "Daily",       "Provider or Tech", TEAL),
    ("4",  "Verify availability of monitors & check alarms",              "Each case",   "Provider or Tech", GREEN),
    ("5",  "Verify spare O₂ cylinder pressure is adequate",               "Daily",       "Provider or Tech", TEAL),
    ("6",  "Verify pipeline gas pressures are ≥45 psi (O₂, N₂O, Air)",   "Daily",       "Provider or Tech", TEAL),
    ("7",  "Verify vaporisers: filled, sealed, interlocked",              "Daily",       "Provider or Tech", TEAL),
    ("8",  "Verify CO₂ absorbent is not exhausted",                       "Daily",       "Provider or Tech", TEAL),
    ("9",  "Calibrate O₂ monitor & check low-O₂ alarm",                  "Daily",       "Provider only",   TEAL),
    ("10", "Verify pressure is adequate on breathing system/vaporiser\n   (Low-Pressure Leak Test)", "Daily", "Provider only", TEAL),
    ("11", "Confirm breathing circuit integrity & patency",               "Each case",   "Provider + Tech", GREEN),
    ("12", "Verify scavenging system is functional",                      "Each case",   "Provider or Tech", GREEN),
    ("13", "Check and prepare airway management equipment",               "Each case",   "Provider only",   GREEN),
    ("14", "Check and confirm medications & IV access",                   "Each case",   "Provider only",   GREEN),
    ("15", "Anaesthesia Time-Out (final pre-induction confirmation)",     "Each case\n(immediately before)", "Provider only", AMBER),
]

row_h = 0.36
for r, (num, item, freq, party, color) in enumerate(all_items):
    ry = 1.4 + r * row_h
    bg = LIGHT_BLUE if r % 2 == 0 else WHITE
    for j, (cw, cx) in enumerate(zip(col_widths, col_x_starts)):
        add_rect(slide, cx, ry, cw, row_h, bg)
    # Number colored
    add_rect(slide, col_x_starts[0], ry, col_widths[0], row_h, color)
    add_text_box(slide, num, col_x_starts[0], ry, col_widths[0], row_h,
                 font_size=9, bold=True, color=WHITE, align=PP_ALIGN.CENTER)
    add_text_box(slide, item, col_x_starts[1], ry, col_widths[1], row_h,
                 font_size=8.5, color=DARK_GRAY, align=PP_ALIGN.LEFT)
    add_text_box(slide, freq, col_x_starts[2], ry, col_widths[2], row_h,
                 font_size=8.5, color=TEAL if "Daily" in freq else GREEN, bold=True,
                 align=PP_ALIGN.CENTER)
    add_text_box(slide, party, col_x_starts[3], ry, col_widths[3], row_h,
                 font_size=8, color=DARK_GRAY, align=PP_ALIGN.CENTER)


# ═════════════════════════════════════════════════════════════════════════════
# SLIDE 7 – Troubleshooting Flowchart
# ═════════════════════════════════════════════════════════════════════════════
slide = prs.slides.add_slide(blank)
add_rect(slide, 0, 0, 13.333, 7.5, LIGHT_GRAY)
add_slide_header(slide, "Intraoperative Anaesthesia Machine Failure – Troubleshooting Flowchart",
                 "General approach when equipment failure is suspected during anaesthesia")
add_footer(slide)

# Problem box at top
add_rect(slide, 3.5, 1.1, 6.3, 0.65, RED, border_rgb=DARK_BLUE, border_pt=2)
add_text_box(slide, "⚠  SUSPECTED ANAESTHESIA MACHINE FAILURE", 3.55, 1.1, 6.2, 0.65,
             font_size=14, bold=True, color=WHITE, align=PP_ALIGN.CENTER)

# Arrow down
add_rect(slide, 6.65, 1.75, 0.02, 0.3, MID_GRAY)

# Immediate action
add_rect(slide, 3.5, 2.05, 6.3, 0.65, AMBER, border_rgb=DARK_BLUE, border_pt=1.5)
add_text_box(slide, "IMMEDIATE ACTION:\nDISCONNECT patient from machine  |  Switch to SIRB (self-inflating bag) + O₂",
             3.55, 2.05, 6.2, 0.65,
             font_size=11, bold=True, color=WHITE, align=PP_ALIGN.CENTER)

# Arrow down
add_rect(slide, 6.65, 2.70, 0.02, 0.28, MID_GRAY)

# Stabilise patient
add_rect(slide, 3.5, 2.98, 6.3, 0.6, MED_BLUE)
add_text_box(slide, "Stabilise Patient:\nManual ventilation  |  Maintain O₂  |  Call for help",
             3.55, 2.98, 6.2, 0.6,
             font_size=11, bold=True, color=WHITE, align=PP_ALIGN.CENTER)

# Arrow down
add_rect(slide, 6.65, 3.58, 0.02, 0.28, MID_GRAY)

# Decision
draw_diamond(slide, 6.667, 4.15, 4.5, 0.7,
             AMBER, DARK_BLUE, "Can failure be\nidentified & corrected\nquickly?", font_size=10)

# YES branch
add_rect(slide, 8.5, 4.55, 0.02, 0.5, MID_GRAY)
add_rect(slide, 8.5, 5.1, 3.6, 0.65, GREEN_BG, border_rgb=GREEN, border_pt=1.5)
add_text_box(slide, "YES → Correct fault\n(e.g., reconnect circuit, replace tubing)\nResume machine ventilation",
             8.55, 5.1, 3.5, 0.65, font_size=9, color=GREEN, align=PP_ALIGN.LEFT, bold=True)

# NO branch
add_rect(slide, 4.8, 4.55, 0.02, 0.5, MID_GRAY)
add_rect(slide, 3.2, 5.1, 3.6, 0.65, RED_BG, border_rgb=RED, border_pt=1.5)
add_text_box(slide, "NO → Do NOT return to machine\nUse alternative ventilation\nNotify senior & biomedical eng.",
             3.25, 5.1, 3.5, 0.65, font_size=9, color=RED, align=PP_ALIGN.LEFT, bold=True)

# Key reminder
add_rect(slide, 2.0, 6.1, 9.3, 0.75, YELLOW_BG, border_rgb=AMBER, border_pt=2)
add_text_box(slide,
    "KEY PRINCIPLE (Miller's Anesthesia 10e): "
    '"When in doubt, ventilate and oxygenate the patient first via another method and troubleshoot later."',
    2.1, 6.1, 9.1, 0.75, font_size=10.5, italic=True, color=DARK_BLUE,
    align=PP_ALIGN.CENTER)


# ═════════════════════════════════════════════════════════════════════════════
# SAVE
# ═════════════════════════════════════════════════════════════════════════════
out_path = "/tmp/workspace/anaesthesia-checklist/Anaesthesia_Machine_Checklist_Protocol.pptx"
buf = BytesIO()
prs.save(buf)
with open(out_path, "wb") as f:
    f.write(buf.getvalue())

print(f"Saved: {out_path}")
Running Command

cd /tmp/workspace/anaesthesia-checklist && python build_pptx.py 2>&1

Running Command

python -c " from pptx import Presentation prs = Presentation('/tmp/workspace/anaesthesia-checklist/Anaesthesia_Machine_Checklist_Protocol.pptx') print(f'Slides: {len(prs.slides)}') for i, slide in enumerate(prs.slides, 1): texts = [s.text_frame.text[:60] for s in slide.shapes if s.has_text_frame and s.text_frame.text.strip()] print(f' Slide {i}: {texts[0] if texts else \"(no text)\"}') import os; print(f'File size: {os.path.getsize(\"/tmp/workspace/anaesthesia-checklist/Anaesthesia_Machine_Checklist_Protocol.pptx\"):,} bytes') "

Your Anaesthesia Machine Checklist Protocol presentation is ready:

Anaesthesia Machine Checklist Protocol

Presentation · PPTX


What's Inside (7 Slides)

SlideContent
1 - TitleCover slide with colour legend (Daily / Each Case / Critical)
2 - Overview FlowchartTop-level PAC flow: Start of Day → Daily Checks → Per-Case Checks → Time-Out → Induction, with decision diamonds and the 7 ASA Basic Requirements
3 - Daily ChecksItems 1, 3, 5–10 in a two-column card layout with step details (O₂ cylinder, AC power, pipeline pressures, vaporisers, CO₂ absorbent, circle system, O₂ analyser)
4 - Per-Case ChecksItems 2, 4, 11–15 in a vertical flowchart; Item 15 (Anaesthesia Time-Out) highlighted in a large amber panel with all 6 confirmation points and the MS MAIDS mnemonic
5 - LPLT FlowchartStep-by-step Low-Pressure Leak Test with PASS/FAIL branches + Circle System Functional Test (steps A–G)
6 - Summary TableAll 15 ASA items in one colour-coded table (frequency + responsible party)
7 - TroubleshootingIntraoperative failure response flowchart: Failure detected → Disconnect → SIRB → Stabilise → Decision diamond → Yes/No branches, with the key Miller's principle quoted

Sources: Miller's Anesthesia 10e (Table 20.6, pp. 2401–2419) | Barash Clinical Anesthesia 9e (pp. 2049–2051) | ASA Recommendations for Pre-Anesthesia Checkout Procedures (2008) | FDA Anesthesia Apparatus Checkout Recommendations (1993)

Oxygen failure protection device 5 marks short note pdf for MD anaesthesia with key points summarised

Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Writing File

~/anaesthesia-checklist/build_ofpd_pdf.py

"""
Oxygen Failure Protection Device (OFPD)
5-Mark Short Note PDF for MD Anaesthesia
"""

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, KeepTogether
)
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Polygon, Circle
from reportlab.graphics import renderPDF
from reportlab.platypus.flowables import Flowable
from reportlab.graphics.shapes import Group, Path
import io, os

# ─── Colour palette ───────────────────────────────────────────────────────────
DARK_BLUE   = colors.HexColor('#1A3A5C')
MED_BLUE    = colors.HexColor('#2E6DA8')
LIGHT_BLUE  = colors.HexColor('#D6E8F7')
TEAL        = colors.HexColor('#00878A')
GREEN       = colors.HexColor('#2A7A4B')
GREEN_BG    = colors.HexColor('#D4EDDA')
AMBER       = colors.HexColor('#E88B00')
AMBER_BG    = colors.HexColor('#FFF3CD')
RED         = colors.HexColor('#C0392B')
RED_BG      = colors.HexColor('#F8D7DA')
LIGHT_GRAY  = colors.HexColor('#F4F6F9')
MID_GRAY    = colors.HexColor('#88A0B4')
DARK_GRAY   = colors.HexColor('#333333')
WHITE       = colors.white

PAGE_W, PAGE_H = A4
MARGIN = 1.8 * cm

# ─── Document setup ──────────────────────────────────────────────────────────
out_path = "/tmp/workspace/anaesthesia-checklist/OFPD_MD_Anaesthesia_Short_Note.pdf"
doc = SimpleDocTemplate(
    out_path,
    pagesize=A4,
    leftMargin=MARGIN, rightMargin=MARGIN,
    topMargin=1.2*cm, bottomMargin=1.5*cm,
    title="Oxygen Failure Protection Device – MD Anaesthesia Short Note",
)

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

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

title_style = S('title', fontSize=17, textColor=WHITE, alignment=TA_CENTER,
                fontName='Helvetica-Bold', leading=22, spaceAfter=0)
subtitle_style = S('subtitle', fontSize=9.5, textColor=colors.HexColor('#AACCEE'),
                   alignment=TA_CENTER, fontName='Helvetica', leading=12)
section_hdr = S('sectionhdr', fontSize=11.5, textColor=WHITE,
                fontName='Helvetica-Bold', leading=14, alignment=TA_LEFT)
body = S('body', fontSize=9.5, textColor=DARK_GRAY, leading=14, alignment=TA_JUSTIFY,
         fontName='Helvetica', spaceAfter=3)
body_bold = S('bodybold', fontSize=9.5, textColor=DARK_GRAY, leading=14,
              fontName='Helvetica-Bold', spaceAfter=2)
bullet_style = S('bullet', fontSize=9.5, textColor=DARK_GRAY, leading=14,
                 fontName='Helvetica', leftIndent=12, spaceAfter=2,
                 bulletIndent=0, firstLineIndent=0)
key_point = S('kp', fontSize=9.5, textColor=DARK_GRAY, leading=14,
              fontName='Helvetica', leftIndent=16, spaceAfter=2)
small_gray = S('smgray', fontSize=8, textColor=MID_GRAY, alignment=TA_CENTER,
               fontName='Helvetica-Oblique', leading=10)
ref_style = S('ref', fontSize=8, textColor=MID_GRAY, leading=11, alignment=TA_LEFT,
              fontName='Helvetica-Oblique')

# ─── Custom Flowables ─────────────────────────────────────────────────────────

class ColorBox(Flowable):
    """Full-width coloured header box."""
    def __init__(self, text, sub=None, bg=DARK_BLUE, h=1.55*cm):
        self.text = text
        self.sub  = sub
        self.bg   = bg
        self.h    = h
        self.width = PAGE_W - 2*MARGIN
        Flowable.__init__(self)

    def wrap(self, *args):
        return (self.width, self.h)

    def draw(self):
        c = self.canv
        c.setFillColor(self.bg)
        c.rect(0, 0, self.width, self.h, fill=1, stroke=0)
        # accent bar
        c.setFillColor(AMBER)
        c.rect(0, 0, 4, self.h, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 14)
        c.drawString(12, self.h - 22, self.text)
        if self.sub:
            c.setFillColor(colors.HexColor('#AACCEE'))
            c.setFont('Helvetica-Oblique', 8.5)
            c.drawString(12, 5, self.sub)


class SectionHeader(Flowable):
    """Coloured section divider."""
    def __init__(self, text, bg=MED_BLUE, h=0.55*cm):
        self.text = text
        self.bg   = bg
        self.h    = h
        self.width = PAGE_W - 2*MARGIN
        Flowable.__init__(self)

    def wrap(self, *args):
        return (self.width, self.h)

    def draw(self):
        c = self.canv
        c.setFillColor(self.bg)
        c.rect(0, 0, self.width, self.h, fill=1, stroke=0)
        c.setFillColor(AMBER)
        c.rect(0, 0, 3.5, self.h, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 10)
        c.drawString(10, (self.h - 10)/2 + 1, self.text)


class KeyPointBox(Flowable):
    """Amber-bordered key-point highlight box."""
    def __init__(self, items, w=None, h=None):
        self.items = items
        self._w = w
        self._h = h
        Flowable.__init__(self)

    def wrap(self, availW, availH):
        self._w = availW
        line_h = 15
        self._h = 8 + len(self.items) * line_h + 8
        return (self._w, self._h)

    def draw(self):
        c = self.canv
        c.setFillColor(AMBER_BG)
        c.setStrokeColor(AMBER)
        c.setLineWidth(1.5)
        c.roundRect(0, 0, self._w, self._h, 4, fill=1, stroke=1)
        c.setFillColor(AMBER)
        c.rect(0, 0, 4, self._h, fill=1, stroke=0)
        c.setFillColor(DARK_GRAY)
        c.setFont('Helvetica', 9)
        for i, item in enumerate(reversed(self.items)):
            y = 8 + i * 15
            c.setFont('Helvetica-Bold', 9)
            c.setFillColor(AMBER)
            c.drawString(10, y, '★')
            c.setFont('Helvetica', 9)
            c.setFillColor(DARK_GRAY)
            c.drawString(22, y, item)


class FlowchartOFPD(Flowable):
    """Simple OFPD mechanism flowchart."""
    def __init__(self, w=None):
        self._fw = w
        Flowable.__init__(self)

    def wrap(self, availW, availH):
        self._fw = availW
        self._fh = 7.5 * cm
        return (self._fw, self._fh)

    def _box(self, c, x, y, w, h, fill, text, font_size=8.5, text_color=WHITE, bold=False):
        c.setFillColor(fill)
        c.setStrokeColor(colors.HexColor('#AAAAAA'))
        c.setLineWidth(0.5)
        c.roundRect(x, y, w, h, 3, fill=1, stroke=1)
        c.setFillColor(text_color)
        fn = 'Helvetica-Bold' if bold else 'Helvetica'
        c.setFont(fn, font_size)
        lines = text.split('\n')
        lh = font_size + 2
        total = len(lines) * lh
        start_y = y + (h - total)/2 + lh - 2
        for ln in lines:
            tw = c.stringWidth(ln, fn, font_size)
            c.drawString(x + (w - tw)/2, start_y, ln)
            start_y -= lh

    def _arrow(self, c, x1, y1, x2, y2):
        c.setStrokeColor(MID_GRAY)
        c.setLineWidth(1.2)
        c.line(x1, y1, x2, y2)
        # arrowhead
        c.setFillColor(MID_GRAY)
        if y2 < y1:   # going down
            c.polygon([x2-4, y2+6, x2+4, y2+6, x2, y2], fill=1, stroke=0)
        elif x2 > x1: # going right
            c.polygon([x2-6, y2-4, x2-6, y2+4, x2, y2], fill=1, stroke=0)

    def _diamond(self, c, cx, cy, w, h, fill, text, font_size=8):
        pts = [cx, cy+h/2, cx+w/2, cy, cx, cy-h/2, cx-w/2, cy]
        c.setFillColor(fill)
        c.setStrokeColor(DARK_BLUE)
        c.setLineWidth(1)
        c.polygon(pts, fill=1, stroke=1)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', font_size)
        lines = text.split('\n')
        lh = font_size + 2
        start_y = cy + (len(lines)-1)*lh/2 - 1
        for ln in lines:
            tw = c.stringWidth(ln, 'Helvetica-Bold', font_size)
            c.drawString(cx - tw/2, start_y, ln)
            start_y -= lh

    def draw(self):
        c = self.canv
        fw = self._fw
        fh = self._fh

        # Background
        c.setFillColor(LIGHT_GRAY)
        c.rect(0, 0, fw, fh, fill=1, stroke=0)

        # Title strip
        c.setFillColor(DARK_BLUE)
        c.rect(0, fh - 0.6*cm, fw, 0.6*cm, fill=1, stroke=0)
        c.setFillColor(WHITE)
        c.setFont('Helvetica-Bold', 9)
        title_txt = "OFPD / Fail-Safe Valve – Mechanism Flowchart"
        c.drawString((fw - c.stringWidth(title_txt, 'Helvetica-Bold', 9))/2,
                     fh - 0.42*cm, title_txt)

        # Node dimensions
        bw = fw * 0.28
        bh = 0.55 * cm
        col1_x = 0.3 * cm
        col2_x = fw/2 - bw/2
        col3_x = fw - bw - 0.3*cm

        # ── Left column: O₂ OK path ──────────────────────
        y_start = fh - 1.3*cm

        self._box(c, col2_x, y_start, bw, bh, DARK_BLUE,
                  'O₂ Pipeline\nSupply (50–55 psi)', font_size=7.5, bold=True)

        # Arrow down
        self._arrow(c, col2_x + bw/2, y_start, col2_x + bw/2, y_start - 0.4*cm)

        # Intermediate pressure
        self._box(c, col2_x, y_start - 0.4*cm - bh, bw, bh, MED_BLUE,
                  'Intermediate-Pressure\nSection (14–55 psi)', font_size=7.5)
        self._arrow(c, col2_x + bw/2, y_start - 0.4*cm - bh,
                    col2_x + bw/2, y_start - 0.8*cm - 2*bh)

        # Piloting pressure line
        pilot_y = y_start - 0.8*cm - 2*bh - bh/2
        c.setStrokeColor(TEAL)
        c.setLineWidth(1)
        c.setDash([3, 3])
        c.line(col2_x + bw/2, pilot_y, col2_x + bw + 0.2*cm, pilot_y)
        c.setDash([])
        c.setFillColor(TEAL)
        c.setFont('Helvetica-Oblique', 7)
        c.drawString(col2_x + bw + 0.25*cm, pilot_y - 3, 'Piloting\npressure')

        # Decision diamond
        d_cx = col2_x + bw/2
        d_cy = y_start - 1.15*cm - 2.5*bh
        self._diamond(c, d_cx, d_cy, bw + 0.3*cm, bh + 0.25*cm,
                      AMBER, 'O₂ pressure\n≥ threshold?', font_size=8)

        # YES branch (right) → valve open
        yes_y = d_cy
        yes_x = col3_x
        c.setStrokeColor(MID_GRAY)
        c.setLineWidth(1.2)
        c.line(d_cx + (bw + 0.3*cm)/2, d_cy, yes_x, d_cy)
        self._arrow(c, yes_x, d_cy, yes_x, d_cy - 0.35*cm)
        c.setFillColor(GREEN)
        c.setFont('Helvetica-Bold', 7.5)
        c.drawString(d_cx + (bw + 0.3*cm)/2 + 2, d_cy + 3, 'YES (≥20–30 psi)')
        self._box(c, yes_x, d_cy - 0.35*cm - bh, bw, bh, GREEN,
                  'Valve OPEN\nN₂O flows freely', font_size=7.5, bold=True)
        self._arrow(c, yes_x + bw/2, d_cy - 0.35*cm - bh,
                    yes_x + bw/2, d_cy - 0.7*cm - 2*bh)
        self._box(c, yes_x, d_cy - 0.7*cm - 2*bh, bw, bh,
                  colors.HexColor('#2A7A4B'),
                  'Normal gas mix\ndelivered', font_size=7.5)

        # NO branch (left) → valve closed
        no_x = col1_x
        c.setStrokeColor(MID_GRAY)
        c.setLineWidth(1.2)
        c.line(d_cx - (bw + 0.3*cm)/2, d_cy, no_x + bw, d_cy)
        self._arrow(c, no_x + bw, d_cy, no_x + bw, d_cy - 0.35*cm)
        c.setFillColor(RED)
        c.setFont('Helvetica-Bold', 7.5)
        c.drawString(no_x, d_cy + 3, 'NO (< threshold)')
        self._box(c, no_x, d_cy - 0.35*cm - bh, bw, bh, RED,
                  'Valve CLOSED\nN₂O cut off', font_size=7.5, bold=True)
        self._arrow(c, no_x + bw/2, d_cy - 0.35*cm - bh,
                    no_x + bw/2, d_cy - 0.7*cm - 2*bh)
        self._box(c, no_x, d_cy - 0.7*cm - 2*bh, bw, bh,
                  colors.HexColor('#8B0000'),
                  'Alarm sounds\nO₂ only flows', font_size=7.5, bold=False, text_color=WHITE)

        # Down arrow from diamond
        self._arrow(c, d_cx, d_cy - (bh + 0.25*cm)/2,
                    d_cx, d_cy - (bh + 0.25*cm)/2 - 0.3*cm)

        # Warning note
        note_y = 0.08 * cm
        c.setFillColor(RED_BG)
        c.setStrokeColor(RED)
        c.setLineWidth(0.8)
        c.roundRect(0.3*cm, note_y, fw - 0.6*cm, 0.55*cm, 3, fill=1, stroke=1)
        c.setFillColor(RED)
        c.setFont('Helvetica-Bold', 8)
        warn = '⚠ Limitation: Does NOT protect if O₂ pipeline is contaminated/crossed with another gas'
        c.drawString((fw - c.stringWidth(warn, 'Helvetica-Bold', 8))/2,
                     note_y + 5, warn)


class ComparisonTable(Flowable):
    """Binary vs Proportional device comparison."""
    def __init__(self, w=None):
        self._fw = w
        Flowable.__init__(self)

    def wrap(self, availW, availH):
        self._fw = availW
        self._fh = 4.8 * cm
        return (self._fw, self._fh)

    def draw(self):
        c = self.canv
        fw = self._fw
        rows = [
            ('Feature', 'Binary (Threshold)\nShutoff Valve', 'Proportional Valve\n(OFPD / Balance Regulator)'),
            ('Also called', '"Fail-safe valve"\n"Nitrous cut-off"',
             'Oxygen Failure Protection Device\n(OFPD), Balance regulator'),
            ('Mechanism', 'Open or closed (all-or-nothing)\nbased on O₂ pressure threshold',
             'Proportionally reduces N₂O\nas O₂ pressure falls'),
            ('O₂ threshold', '20–30 psig (e.g. GE machines)',
             'Completely shuts N₂O at 0.5 psig\n(other gases at 10 psig)'),
            ('Used on', 'Older GE/Datex-Ohmeda machines',
             'Modern machines – ISO standard'),
            ('Limitation', 'All gases off if O₂ drops (sudden)',
             'Does NOT prevent hypoxia if\npipeline crossover/contamination'),
        ]
        col_w = [fw * 0.22, fw * 0.38, fw * 0.38]
        row_h = self._fh / len(rows)
        y_top = self._fh

        for r, row in enumerate(rows):
            y = y_top - (r + 1) * row_h
            for ci, (cell, cw) in enumerate(zip(row, col_w)):
                x = sum(col_w[:ci])
                # Background
                if r == 0:
                    bg = DARK_BLUE
                elif ci == 0:
                    bg = LIGHT_BLUE
                elif ci == 1:
                    bg = colors.HexColor('#FFF3CD') if r % 2 == 0 else WHITE
                else:
                    bg = LIGHT_BLUE if r % 2 == 0 else colors.HexColor('#E8F4FD')
                c.setFillColor(bg)
                c.setStrokeColor(MID_GRAY)
                c.setLineWidth(0.5)
                c.rect(x, y, cw, row_h, fill=1, stroke=1)
                # Text
                fc = WHITE if r == 0 else DARK_GRAY
                fn = 'Helvetica-Bold' if r == 0 or ci == 0 else 'Helvetica'
                fs = 7.5
                c.setFillColor(fc)
                c.setFont(fn, fs)
                lines = cell.split('\n')
                lh = fs + 1.5
                start_y = y + row_h/2 + (len(lines)-1)*lh/2
                for ln in lines:
                    tw = c.stringWidth(ln, fn, fs)
                    c.drawString(x + (cw - tw)/2, start_y, ln)
                    start_y -= lh


# ─── Build content ────────────────────────────────────────────────────────────

def bullet(text, indent=12):
    return Paragraph(f'<bullet>&bull;</bullet> {text}', bullet_style)

def sub_bullet(text):
    s = S('subb', parent=bullet_style, leftIndent=24, fontSize=9)
    return Paragraph(f'  – {text}', s)

story = []

# ── Title block ──────────────────────────────────────────────────────────────
story.append(ColorBox(
    "OXYGEN FAILURE PROTECTION DEVICE (OFPD)",
    sub="MD Anaesthesia  |  5-Mark Short Note  |  Anaesthesia Machine Safety",
    bg=DARK_BLUE, h=1.6*cm
))
story.append(Spacer(1, 4*mm))

# ── Introduction ─────────────────────────────────────────────────────────────
story.append(SectionHeader("1.  DEFINITION & INTRODUCTION", bg=MED_BLUE))
story.append(Spacer(1, 2*mm))
story.append(Paragraph(
    "The <b>Oxygen Failure Protection Device (OFPD)</b>, also known as the <b>fail-safe valve</b>, "
    "<b>pressure-sensor shutoff valve</b>, or <b>balance regulator</b>, is a safety mechanism "
    "incorporated in the <b>intermediate-pressure section</b> of the anaesthesia workstation. "
    "Its primary function is to <b>reduce or cut off the supply of nitrous oxide</b> (and other "
    "gases except oxygen) when the oxygen supply pressure falls below a critical threshold, "
    "thereby minimising the risk of delivering a <b>hypoxic gas mixture</b> to the patient. "
    "It is an <b>ISO standard</b> on all modern anaesthesia machines.",
    body))
story.append(Spacer(1, 3*mm))

# ── Location ─────────────────────────────────────────────────────────────────
story.append(SectionHeader("2.  LOCATION IN THE ANAESTHESIA MACHINE", bg=MED_BLUE))
story.append(Spacer(1, 2*mm))
story.append(Paragraph(
    "The OFPD is situated in the <b>intermediate-pressure section</b> of the anaesthesia machine "
    "(pipeline pressure reduced to 45–55 psi). One device is present in the gas line supplying "
    "<b>each flowmeter except oxygen</b>. It receives a <b>'piloting pressure' signal</b> derived "
    "from the oxygen supply line (or secondary regulator).",
    body))
story.append(Spacer(1, 2*mm))
table_loc = Table(
    [
        [Paragraph('<b>Section</b>', body_bold),
         Paragraph('<b>Pressure Range</b>', body_bold),
         Paragraph('<b>Key Components</b>', body_bold)],
        ['High-pressure', '1900–2200 psi (cylinder)', 'Cylinder valves, reducing valves'],
        ['Intermediate-pressure', '45–55 psi (pipeline)', 'OFPD, flush valve, proportioning system'],
        ['Low-pressure', '≤ 16 psi (flow control)', 'Flowmeters, vaporisers, common gas outlet'],
    ],
    colWidths=[(PAGE_W - 2*MARGIN) * x for x in [0.22, 0.25, 0.53]],
)
table_loc.setStyle(TableStyle([
    ('BACKGROUND', (0, 0), (-1, 0), DARK_BLUE),
    ('TEXTCOLOR',  (0, 0), (-1, 0), WHITE),
    ('FONTNAME',   (0, 0), (-1, 0), 'Helvetica-Bold'),
    ('FONTNAME',   (0, 1), (-1, -1), 'Helvetica'),
    ('FONTSIZE',   (0, 0), (-1, -1), 8.5),
    ('BACKGROUND', (0, 2), (-1, 2), LIGHT_BLUE),
    ('ROWBACKGROUNDS', (0, 1), (-1, -1), [WHITE, LIGHT_BLUE, WHITE]),
    ('ROWHEIGHT',  (0, 0), (-1, -1), 0.55*cm),
    ('VALIGN',     (0, 0), (-1, -1), 'MIDDLE'),
    ('ALIGN',      (0, 0), (-1, -1), 'CENTER'),
    ('GRID',       (0, 0), (-1, -1), 0.5, MID_GRAY),
    ('LEFTPADDING',(0, 0), (-1, -1), 5),
]))
story.append(table_loc)
story.append(Spacer(1, 3*mm))

# ── Types ─────────────────────────────────────────────────────────────────────
story.append(SectionHeader("3.  TYPES OF OFPD", bg=MED_BLUE))
story.append(Spacer(1, 2*mm))

story.append(Paragraph("<b>A. Binary (Threshold) Shutoff Valve</b>", body_bold))
story.append(bullet("Acts in an <b>all-or-nothing</b> fashion based on a threshold O₂ pressure"))
story.append(bullet("Examples: GE/Datex-Ohmeda <i>pressure-sensor shutoff valve</i>"))
story.append(bullet("Threshold: <b>20–30 psig</b>; valve opens when O₂ pressure exceeds threshold"))
story.append(bullet("Mechanism: oxygen pressure acts on a mobile diaphragm → moves piston "
                    "upward → pin opens the N₂O valve; spring closes it when O₂ pressure is low"))
story.append(bullet("Limitation: <b>abrupt</b> cutoff; N₂O completely stops if O₂ drops even transiently"))
story.append(Spacer(1, 2*mm))

story.append(Paragraph("<b>B. Proportional Valve (Balance Regulator / OFPD)</b>", body_bold))
story.append(bullet("Modern design – <b>proportionately reduces</b> N₂O pressure as O₂ pressure falls"))
story.append(bullet("Completely shuts off N₂O only below a <b>minimum O₂ pressure</b> (e.g. <b>0.5 psig</b> "
                    "for N₂O; <b>10 psig</b> for other gases)"))
story.append(bullet("ISO standard on all contemporary workstations"))
story.append(bullet("Air flow may bypass the OFPD on some machines, allowing air administration "
                    "even with O₂ failure"))
story.append(Spacer(1, 3*mm))

# ── Flowchart ─────────────────────────────────────────────────────────────────
story.append(SectionHeader("4.  MECHANISM FLOWCHART", bg=TEAL))
story.append(Spacer(1, 2*mm))
story.append(FlowchartOFPD())
story.append(Spacer(1, 3*mm))

# ── Comparison table ──────────────────────────────────────────────────────────
story.append(SectionHeader("5.  COMPARISON: BINARY vs PROPORTIONAL DEVICE", bg=TEAL))
story.append(Spacer(1, 2*mm))
story.append(ComparisonTable())
story.append(Spacer(1, 3*mm))

# ── Proportioning systems ─────────────────────────────────────────────────────
story.append(SectionHeader("6.  RELATIONSHIP WITH PROPORTIONING SYSTEMS", bg=MED_BLUE))
story.append(Spacer(1, 2*mm))
story.append(Paragraph(
    "The OFPD works in conjunction with — but is <b>distinct from</b> — the proportioning system. "
    "While the OFPD acts upstream (at the piloting pressure level), proportioning systems control "
    "the N₂O:O₂ <b>flow ratio</b> at the flow control valve level to prevent a hypoxic mixture.",
    body))
story.append(Spacer(1, 2*mm))

prop_data = [
    [Paragraph('<b>Device</b>', body_bold), Paragraph('<b>Mechanism</b>', body_bold),
     Paragraph('<b>Minimum FiO₂ ensured</b>', body_bold)],
    ['Dräger S-ORC\n(Sensitive O₂ Ratio Controller)',
     'Pneumatic-mechanical; diaphragm-driven N₂O\nproportioning valve; needs ≥ 200 mL/min O₂',
     '≥ 25% O₂\n(max 75% N₂O)'],
    ['GE/Datex-Ohmeda\nLink-25 System',
     'Mechanical chain-link coupling of O₂\nand N₂O flow knobs',
     '≥ 25% O₂\n(3:1 max N₂O:O₂ ratio)'],
]
prop_table = Table(prop_data,
    colWidths=[(PAGE_W - 2*MARGIN)*x for x in [0.28, 0.44, 0.28]])
prop_table.setStyle(TableStyle([
    ('BACKGROUND',  (0, 0), (-1, 0), DARK_BLUE),
    ('TEXTCOLOR',   (0, 0), (-1, 0), WHITE),
    ('FONTNAME',    (0, 0), (-1, 0), 'Helvetica-Bold'),
    ('FONTNAME',    (0, 1), (-1, -1), 'Helvetica'),
    ('FONTSIZE',    (0, 0), (-1, -1), 8.5),
    ('ROWBACKGROUNDS', (0, 1), (-1, -1), [LIGHT_BLUE, WHITE]),
    ('ROWHEIGHT',   (0, 0), (-1, -1), 0.6*cm),
    ('VALIGN',      (0, 0), (-1, -1), 'MIDDLE'),
    ('ALIGN',       (0, 0), (-1, -1), 'CENTER'),
    ('GRID',        (0, 0), (-1, -1), 0.5, MID_GRAY),
    ('LEFTPADDING', (0, 0), (-1, -1), 5),
]))
story.append(prop_table)
story.append(Spacer(1, 3*mm))

# ── Limitations ───────────────────────────────────────────────────────────────
story.append(SectionHeader("7.  LIMITATIONS – WHY 'FAIL-SAFE' IS A MISNOMER", bg=RED))
story.append(Spacer(1, 2*mm))
story.append(Paragraph(
    "The term <b>'fail-safe'</b> is widely regarded as a <b>misnomer</b> because the OFPD "
    "<i>only</i> responds to <b>oxygen pressure</b>, not to oxygen <b>concentration</b>. "
    "The following situations can cause a hypoxic mixture <b>despite the OFPD being open</b>:",
    body))
story.append(Spacer(1, 2*mm))

lim_data = [
    ['Situation', 'Why OFPD Fails to Protect'],
    ['Pipeline gas crossover / contamination\n(N₂O in O₂ pipeline)',
     'O₂ pipeline pressure is maintained by N₂O → OFPD stays OPEN\nO₂ analyser is the only safeguard'],
    ['Hypoxic gas mixture at adequate pressure\n(e.g. <21% O₂ but pressure ≥ threshold)',
     'OFPD cannot distinguish O₂ from any other gas at the\npiloting line — it only senses pressure'],
    ['Air bypass (some machines)',
     'Air can be delivered even with O₂ failure if its\nline bypasses the OFPD'],
    ['Downstream leaks (low-pressure circuit)',
     'OFPD is upstream; leaks after flowmeters are\nnot detected by this device'],
    ['Flowmeter bobbin float leak\n(cracked or stuck float)',
     'N₂O may continue to flow into the common outlet\neven if OFPD is closed (gas escapes leak)'],
]
lim_table = Table(lim_data,
    colWidths=[(PAGE_W - 2*MARGIN)*x for x in [0.42, 0.58]])
lim_table.setStyle(TableStyle([
    ('BACKGROUND',  (0, 0), (-1, 0), RED),
    ('TEXTCOLOR',   (0, 0), (-1, 0), WHITE),
    ('FONTNAME',    (0, 0), (-1, 0), 'Helvetica-Bold'),
    ('FONTNAME',    (0, 1), (-1, -1), 'Helvetica'),
    ('FONTSIZE',    (0, 0), (-1, -1), 8.5),
    ('ROWBACKGROUNDS', (0, 1), (-1, -1), [RED_BG, WHITE]),
    ('ROWHEIGHT',   (0, 0), (-1, -1), 0.65*cm),
    ('VALIGN',      (0, 0), (-1, -1), 'MIDDLE'),
    ('ALIGN',       (0, 0), (0, -1), 'LEFT'),
    ('ALIGN',       (1, 0), (1, -1), 'LEFT'),
    ('GRID',        (0, 0), (-1, -1), 0.5, MID_GRAY),
    ('LEFTPADDING', (0, 0), (-1, -1), 6),
]))
story.append(lim_table)
story.append(Spacer(1, 3*mm))

# ── Additional safeguards ─────────────────────────────────────────────────────
story.append(SectionHeader("8.  ADDITIONAL SAFEGUARDS (Work with OFPD)", bg=MED_BLUE))
story.append(Spacer(1, 2*mm))
story.append(bullet("<b>Oxygen supply low-pressure alarm</b> – audible alarm when inlet O₂ "
                    "pressure drops below 20–30 psig"))
story.append(bullet("<b>Oxygen analyser (FiO₂ monitor)</b> – <i>only</i> monitor that detects "
                    "downstream problems incl. pipeline crossover; most important safeguard"))
story.append(bullet("<b>Proportioning systems</b> (SORC / Link-25) – prevent hypoxic N₂O:O₂ ratio "
                    "at flow control valve level (min FiO₂ 25%)"))
story.append(bullet("<b>Oxygen flush valve</b> – delivers 100% O₂ at 35–75 L/min directly, bypassing vaporisers"))
story.append(bullet("<b>Minimum O₂ flow requirement</b> – modern machines mandate a minimum O₂ "
                    "flow (often 200 mL/min) that cannot be turned off"))
story.append(Spacer(1, 3*mm))

# ── Key points summary ────────────────────────────────────────────────────────
story.append(SectionHeader("★  KEY POINTS SUMMARY  (For Exam)", bg=AMBER))
story.append(Spacer(1, 2*mm))
story.append(KeyPointBox([
    "OFPD is in the INTERMEDIATE-pressure section; present in every gas line EXCEPT oxygen",
    "Two types: Binary (threshold shutoff, e.g. 20 psig GE) vs Proportional (balance regulator, modern machines)",
    "Modern OFPD completely shuts N₂O only at ≤ 0.5 psig O₂; proportionally reduces above that",
    "'Fail-safe' is a MISNOMER – does NOT protect against pipeline crossover or contamination",
    "O₂ ANALYSER (FiO₂ monitor) is the ONLY safeguard against pipeline contamination/crossover",
    "OFPD ≠ Proportioning system: OFPD works at piloting pressure; proportioning at flow knob level",
    "Air may bypass OFPD on some machines (air delivery possible even in O₂ failure)",
    "Low-pressure circuit leaks are NOT detected by OFPD (it is an upstream device)",
    "Dräger S-ORC: minimum 200 mL/min O₂ required for N₂O proportioning valve to open",
    "GE Link-25: mechanical chain-link; max N₂O:O₂ ratio = 3:1 (ensures ≥25% FiO₂)",
]))
story.append(Spacer(1, 3*mm))

# ── References ────────────────────────────────────────────────────────────────
story.append(HRFlowable(width="100%", thickness=0.5, color=MID_GRAY, spaceAfter=3))
story.append(Paragraph(
    "<b>References:</b> "
    "Miller's Anesthesia 10e (Pardo & Miller), Chapter 20, pp. 2241–2258  |  "
    "Morgan & Mikhail's Clinical Anesthesiology 7e, Chapter 4, pp. 114–115  |  "
    "Barash Clinical Anesthesia 9e, Chapter 25, pp. 1943–1945  |  "
    "ISO 80601-2-13: Medical Electrical Equipment – Anaesthetic Workstations",
    ref_style))

# ── Build PDF ─────────────────────────────────────────────────────────────────
def on_first_page(canvas, doc):
    canvas.saveState()
    canvas.setFillColor(colors.HexColor('#ECF0F5'))
    canvas.rect(0, 0, PAGE_W, 0.7*cm, fill=1, stroke=0)
    canvas.setFont('Helvetica', 7.5)
    canvas.setFillColor(MID_GRAY)
    canvas.drawString(MARGIN, 0.22*cm,
        "Oxygen Failure Protection Device – MD Anaesthesia Short Note")
    canvas.drawRightString(PAGE_W - MARGIN, 0.22*cm, "Page 1")
    canvas.restoreState()

def on_later_pages(canvas, doc):
    canvas.saveState()
    canvas.setFillColor(colors.HexColor('#ECF0F5'))
    canvas.rect(0, 0, PAGE_W, 0.7*cm, fill=1, stroke=0)
    canvas.setFont('Helvetica', 7.5)
    canvas.setFillColor(MID_GRAY)
    canvas.drawString(MARGIN, 0.22*cm,
        "Oxygen Failure Protection Device – MD Anaesthesia Short Note")
    canvas.drawRightString(PAGE_W - MARGIN, 0.22*cm, f"Page {doc.page}")
    canvas.restoreState()

doc.build(story, onFirstPage=on_first_page, onLaterPages=on_later_pages)
size = os.path.getsize(out_path)
print(f"Saved: {out_path}  ({size:,} bytes)")
Running Command

cd /tmp/workspace/anaesthesia-checklist && python build_ofpd_pdf.py 2>&1

Editing File

~/anaesthesia-checklist/build_ofpd_pdf.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/anaesthesia-checklist/build_ofpd_pdf.py'
Editing File

~/anaesthesia-checklist/build_ofpd_pdf.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/anaesthesia-checklist/build_ofpd_pdf.py'
Running Command

cd /tmp/workspace/anaesthesia-checklist && python build_ofpd_pdf.py 2>&1

PDF built successfully. Here is your complete short note:

OFPD MD Anaesthesia Short Note

PDF Document · PDF


Oxygen Failure Protection Device (OFPD) - 5-Mark Short Note


Definition

The OFPD (also called fail-safe valve, pressure-sensor shutoff valve, or balance regulator) is located in the intermediate-pressure section of the anaesthesia machine. It reduces or cuts off N₂O and other gas supply when oxygen pressure falls below a threshold, preventing delivery of a hypoxic mixture. It is an ISO standard on all modern workstations.

Location

Present in the gas supply line of every gas except oxygen, between the intermediate-pressure section (45–55 psi) and the flow control valves. It receives a piloting pressure signal from the O₂ supply line.

Types

TypeMechanismThresholdUsed in
Binary (threshold) shutoffAll-or-nothing; spring closes valve20–30 psigOlder GE/Datex-Ohmeda
Proportional (balance regulator / OFPD)Proportionally reduces N₂O; fully shuts at 0.5 psig0.5 psig (N₂O) / 10 psig (others)All modern machines (ISO std)

Mechanism (Simplified)

O₂ pipeline (50–55 psi)
        ↓
Intermediate-pressure section
        ↓ [piloting pressure line] ────────→ OFPD
                                              ↓
                          O₂ ≥ threshold?
                         /              \
                       YES               NO
                        ↓                ↓
                 Valve OPEN          Valve CLOSED
              N₂O flows freely     N₂O cut off + alarm

Proportioning Systems (Work Alongside OFPD)

  • Dräger S-ORC - pneumatic-mechanical; needs ≥ 200 mL/min O₂; maintains ≥ 25% FiO₂
  • GE Link-25 - mechanical chain-link of O₂ and N₂O flow knobs; max N₂O:O₂ = 3:1

★ KEY POINTS (Exam Focus)

  1. "Fail-safe" is a MISNOMER - responds only to O₂ pressure, not O₂ concentration
  2. Pipeline crossover (N₂O in O₂ line) - O₂ pressure maintained → OFPD stays OPEN → hypoxic mixture delivered
  3. O₂ analyser (FiO₂ monitor) is the ONLY safeguard against pipeline contamination
  4. Location: intermediate-pressure section, upstream of flowmeters
  5. Air may bypass OFPD on some machines - air delivery possible even in O₂ failure
  6. Low-pressure circuit leaks are NOT detected by OFPD
  7. OFPD ≠ Proportioning system - OFPD acts at piloting pressure; proportioning acts at flow knob level
  8. Modern OFPD: complete N₂O shutoff at ≤ 0.5 psig (proportional reduction above that)

Sources: Miller's Anesthesia 10e, Ch.20, p.2241-2258 | Morgan & Mikhail's Clinical Anesthesiology 7e, Ch.4, pp.114-115 | Barash Clinical Anesthesia 9e, Ch.25, pp.1943-1945
This is a shared conversation. Sign in to Orris to start your own chat.