Expansive detailed knowledge on ante-partum fetal monitoring

Reading File
Finding Sources
Finding Sources
Finding Sources
Searching PubMed

antepartum fetal surveillance monitoring

Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Loading Image
Reading File
Loading Image
Reading File
I now have comprehensive source material. Let me compile the full, expansive response.

Ante-partum Fetal Monitoring: Comprehensive Reference

Ante-partum fetal monitoring encompasses all techniques used to assess fetal well-being before the onset of labor. The goal is to detect fetal hypoxemia and acidosis early enough to allow intervention - either in utero treatment or timely delivery - while avoiding unnecessary prematurity from false alarms.

1. Physiological Basis

Why Fetal Behavior Reflects Oxygenation

The core principle of ante-partum monitoring is that changes in fetal behavior imply changes in fetal status. The fetal CNS controls cardiovascular reflexes, movement, tone, breathing, and heart rate - all of which are sensitive to hypoxia. When the fetus is well oxygenated, it maintains normal behavioral states; as hypoxia progresses, CNS functions are suppressed in a hierarchical pattern.

Fetal Heart Rate Development

As gestation advances, the FHR becomes increasingly dominated by the parasympathetic nervous system, producing:
  • Gradual decrease in baseline heart rate toward term
  • Increasing beat-to-beat variability
  • Progressive responsiveness to fetal movement (accelerations)
The capacity to accelerate the FHR in response to movement is directly linked to fetal oxygenation and metabolic state. Preterm fetuses, growth-restricted fetuses, or those exposed to maternal medications (narcotics, magnesium sulfate) may have attenuated accelerations even without compromise - an important source of false-positive tests.

The Hierarchy of CNS Vulnerability

Under progressive hypoxia, fetal CNS centers are suppressed in a predictable order (from most sensitive to least sensitive):
  1. FHR reactivity (NST) - first to be lost
  2. Fetal breathing movements - suppressed early
  3. Gross body movements
  4. Fetal tone - last to disappear (most primitive reflex)
Amniotic fluid volume (a chronic marker) reflects cumulative renal perfusion over days to weeks. This hierarchy underpins the interpretation of the biophysical profile score (BPP).

2. Methods of Antepartum Surveillance

2.1 Fetal Movement Counting (Kick Counts)

The simplest, most accessible form of surveillance. The mother records active fetal movements daily.
Cardiff "Count to Ten" method: Count movements until 10 are felt; normal if 10 movements occur within 2 hours.
Sadovsky method: Count for 1 hour 3 times daily; normal is >4 movements per hour.
Clinical relevance:
  • Decreased fetal movement is a warning sign that may precede fetal compromise by days
  • Absence of movement for >12 hours warrants immediate evaluation
  • Limitations: subjective, affected by maternal perception, sleep states, oligohydramnios, anterior placenta, obesity

2.2 Non-Stress Test (NST)

The NST is the cornerstone of outpatient antepartum surveillance. It assesses FHR reactivity as a surrogate for intact fetal CNS-cardiovascular coupling.
Procedure:
  • External FHR monitor (cardiotocograph) placed on the maternal abdomen
  • Duration: typically 20 minutes, extended to 40 minutes if initial period is non-reactive
  • Uterine activity recorded simultaneously
  • Vibroacoustic stimulation (VAS) may be used to wake the fetus from quiet sleep and shorten testing time
Reactive NST (Normal):
  • ≥2 FHR accelerations of ≥15 bpm above baseline, lasting ≥15 seconds, within a 20-30 minute window, associated with fetal movement
  • Reassures fetal well-being for approximately 1 week in most clinical settings
Gestational age modification: For fetuses <32 weeks' gestation, accelerations of ≥10 bpm lasting ≥10 seconds are considered reactive, acknowledging the smaller accelerations typical of preterm fetuses.
Non-reactive NST:
  • Fails to meet the above criteria within the allotted time (up to 40-60 minutes depending on protocol)
  • Occurs in ~10-12% of third-trimester fetuses at 30 minutes; falls below 6% by 40 minutes
  • A non-reactive NST is NOT diagnostic of compromise - it triggers further assessment (BPP, CST)
False-negative rate (fetal death within 1 week of reactive NST): approximately 1.9 per 1000 - very low but not zero.
Causes of non-reactive NST without compromise:
  • Fetal sleep cycle (most common)
  • Prematurity (<28 weeks)
  • Fetal CNS anomalies
  • Maternal medications (narcotics, MgSO4, steroids)
  • Fetal anemia
Vibroacoustic Stimulation (VAS): Vibration sense is fully developed by 22-24 weeks; auditory response by ~26 weeks. An electromechanical device applied to the maternal abdomen produces broad-band atonal white noise (0.1-10 kHz), provokes fetal state change from quiet sleep to active sleep, reduces testing time, and converts many non-reactive NSTs to reactive without pathological significance. Its limitations include rare fetal bradycardia and unknown long-term effects.

2.3 Contraction Stress Test (CST) and Oxytocin Challenge Test (OCT)

The CST evaluates uteroplacental reserve by examining the FHR response to uterine contractions - a physiological stress that transiently reduces intervillous blood flow.
Principle: A fetus with marginal placental reserve that maintains adequate oxygenation at rest may decompensate during contractions, producing late decelerations. This detects "subclinical" placental insufficiency.
Methods of inducing contractions:
  1. Nipple stimulation CST: Patient stimulates one nipple for 2-minute intervals; endogenous oxytocin release achieves contractions
  2. Oxytocin Challenge Test (OCT): IV oxytocin infusion titrated to achieve 3 contractions in 10 minutes, each lasting 40-60 seconds
Interpretation:
ResultDefinitionClinical Action
Negative (Normal)No late or significant variable decelerationsReassuring; repeat in 1 week
Positive (Abnormal)Late decelerations following ≥50% of contractionsHigh-risk; delivery planning or intensive monitoring
Equivocal-SuspiciousIntermittent late or significant variable decelerationsRepeat test
Equivocal-HyperstimulationDecelerations with contractions >90 sec or frequency >2 in 10 minRepeat when uterine activity normalizes
Unsatisfactory<3 contractions in 10 minutes or uninterpretable tracingRepeat test
False-positive rate: relatively high (~30%), leading to unnecessary interventions - a major limitation False-negative rate: very low (~0.04%)
Contraindications:
  • Preterm labor risk (cervical incompetence, preterm PROM, multiple gestation, prior classical cesarean, placenta previa)
The CST is now used less commonly than the BPP or modified BPP in most centers due to its contraindications, inconvenience, and high false-positive rate.

2.4 Biophysical Profile (BPP)

Introduced by Manning in 1980, the BPP combines acute neurological markers (reflecting real-time CNS oxygenation) with a chronic marker (amniotic fluid volume, reflecting days-to-weeks of placental function).
The Five Variables (each scored 2 if normal, 0 if absent):
VariableNormal (Score 2)Abnormal (Score 0)
Fetal Breathing Movement (FBM)≥30 seconds of sustained breathing in 30 minutes<30 seconds in 30 minutes
Gross Body Movement (FM)≥3 separate limb/trunk movements in 30 minutes≤2 movements in 30 minutes
Fetal Tone (FT)≥1 episode of extension followed by return to flexion (limb or spine)Semi- or full extension without return; absent movement counts as absent tone
FHR Reactivity (NST)≥2 accelerations of ≥15 bpm × ≥15 sec with movement<2 qualifying accelerations during observation
Amniotic Fluid Volume (AFV)A pocket ≥2 cm in two perpendicular planes (or AFI ≥5 cm)Largest pocket <2 cm in two perpendicular planes
Maximum score: 10/10. Minimum: 0/10.
Interpretation and Management:
BPP ScoreRisk of Fetal AcidosisManagement
10/10 or 8/10 (normal AFV)Very low (<1 in 1000)Reassured; routine follow-up
8/10 (abnormal AFV)ModerateDeliver if ≥36 wks; intensive monitoring if preterm
6/10Equivocal (~variable)Deliver if ≥36 wks or mature; repeat in 4-6 hrs if preterm
4/10HighDeliver unless remote prematurity
2/10 or 0/10Very highDeliver regardless of gestational age
Key principle: Oligohydramnios constitutes an abnormal BPP regardless of the overall score.
Why combine variables? The graph below from Creasy & Resnik's Maternal-Fetal Medicine illustrates that the full "Planning Score" (all 5 variables combined) achieves the lowest rate of adverse outcomes (5-minute Apgar <7), significantly better than any single variable alone:
BPP - Combined variables outperform single variables in predicting adverse neonatal outcome
Pathophysiology of low BPP in chronic hypoxia: When the fetus experiences sustained placental insufficiency, cardiac output is redistributed - away from non-vital organs (kidneys, lungs) toward vital organs (brain, heart, adrenals). Decreased renal perfusion reduces urine output, leading to oligohydramnios. A low AFI may be the earliest chronic marker of placental insufficiency.

2.5 Modified Biophysical Profile (Modified BPP)

A practical two-component test combining:
  1. NST (acute marker of CNS/cardiovascular function)
  2. Amniotic Fluid Index (AFI) (chronic marker of placental function)
Normal modified BPP: Reactive NST + AFI ≥5 cm Abnormal modified BPP: Non-reactive NST OR AFI <5 cm → full BPP or CST warranted
The modified BPP is widely used as a first-line outpatient surveillance tool because it requires less time than the full BPP (no full 30-minute ultrasound), while combining both acute and chronic markers. It performs comparably to the full BPP for predicting fetal compromise in most high-risk populations.

2.6 Doppler Velocimetry

Doppler ultrasound assesses blood flow velocity waveforms in specific fetal and maternal vessels. It provides functional information about placental vascular resistance and circulatory adaptation to compromise.

2.6.1 Umbilical Artery (UA) Doppler

Principle: The umbilical artery supplies the placenta. As placental vascular resistance rises (due to obliterative vasculopathy in FGR/preeclampsia), diastolic flow progressively diminishes.
Waveform indices:
  • S/D ratio (systolic/diastolic): normal falls with advancing gestation as placental resistance decreases
  • Resistance Index (RI) = (S - D)/S
  • Pulsatility Index (PI) = (S - D)/mean
Abnormal findings in order of severity:
FindingSignificance
Elevated S/D ratio / high PI/RIIncreased placental resistance; ~30% of villous tree affected
Absent End-Diastolic Velocity (AEDV)~60-70% of villous tree obliterated; high risk of stillbirth and neonatal complications
Reversed End-Diastolic Velocity (REDV)>70% obliteration; very high risk; imminent fetal decompensation
AEDV and REDV are associated with substantially increased rates of neonatal complications (intraventricular hemorrhage, necrotizing enterocolitis, transfusion requirement) and perinatal mortality. The Cochrane review by Alfirevic et al. 2017 confirmed that umbilical artery Doppler in high-risk pregnancies reduces perinatal mortality.
Indications for UA Doppler: fetal growth restriction (FGR), hypertensive disorders of pregnancy, collagen vascular disease, prior stillbirth, multiple gestation with discordant growth.

2.6.2 Middle Cerebral Artery (MCA) Doppler

The MCA is short, straight, and anatomically consistent, making it ideal for Doppler measurement. Two key applications:
1. Brain sparing (cerebral redistribution): In fetal hypoxia from placental insufficiency, cardiac output is redistributed toward the brain ("brain sparing"), increasing diastolic MCA velocities and lowering the MCA PI/RI. This is detected as:
  • Low MCA PI (especially <5th percentile for gestational age)
  • Cerebro-placental ratio (CPR) = MCA PI / UA PI falls below 1.0 or <5th percentile
The CPR is a sensitive early marker of fetal circulatory compromise, detecting redistribution before overt abnormalities appear in either vessel alone.
2. Fetal anemia assessment: As fetal hematocrit falls, cardiac output increases and blood viscosity decreases, raising the MCA Peak Systolic Velocity (PSV). An MCA PSV >1.5 multiples of the median (MoM) for gestational age predicts moderate-to-severe fetal anemia with high sensitivity (~88%) and specificity (~82%), replacing the need for invasive amniocentesis for optical density measurement.
Below is a real MCA Doppler tracing from a fetus with severe anti-D isoimmune anemia, demonstrating high PSV (top), post-transfusion normalization (middle), and recurrence before the next transfusion (bottom):
MCA Doppler PSV serial measurements in fetal anemia
MCA measurement technique: 2 mm past its origin from the internal carotid artery, with the Doppler angle minimized to near zero.

2.6.3 Ductus Venosus (DV) Doppler

Location: The ductus venosus is a shunt between the umbilical vein and the inferior vena cava, bypassing the hepatic circulation. It preferentially delivers oxygenated blood to the foramen ovale and hence to the coronary and cerebral circulations.
Normal waveform: Triphasic - S wave (ventricular systole), D wave (passive ventricular filling), and a wave (atrial contraction) - all with forward flow.
Abnormal findings:
  • Absent a-wave: elevated cardiac end-diastolic pressure; early venous compromise
  • Reversed a-wave: severely elevated venous pressures; sign of cardiac decompensation - associated with very high perinatal mortality
DV Doppler is particularly useful in FGR at very preterm gestations, helping time delivery when UA AEDV/REDV is present. Progressive deterioration from abnormal UA → abnormal DV typically occurs over days to weeks, guiding the window for intervention.

2.6.4 Uterine Artery Doppler

Assesses maternal spiral artery remodeling (trophoblastic invasion).
Normal: After 24 weeks, resistance falls as trophoblasts remodel spiral arteries; notching disappears. Abnormal: Persistent bilateral uterine artery notching and/or high PI at 20-24 weeks predicts:
  • Preeclampsia (sensitivity ~40-60% for severe disease)
  • FGR
  • Placental abruption
Used primarily as a second-trimester screening tool for subsequent placental complications rather than real-time fetal surveillance.

2.7 Amniotic Fluid Assessment

Amniotic fluid volume reflects fetal urine production (renal perfusion) and swallowing. It is a "memory" of placental function over the preceding weeks.
Two measurement methods:
1. Amniotic Fluid Index (AFI):
  • Four-quadrant technique: sum of the deepest vertical pocket in each uterine quadrant (cm)
  • Normal: 5-25 cm (varies by gestational age)
  • Oligohydramnios: AFI <5 cm
  • Polyhydramnios: AFI >25 cm
2. Single Deepest Pocket (SDP) / Maximum Vertical Pocket (MVP):
  • Measures the single largest vertical pocket without cord or fetal parts
  • Normal: 2-8 cm
  • Oligohydramnios: <2 cm; polyhydramnios: >8 cm
Clinical note: The BPP uses a 2 cm in two perpendicular planes criterion (a 2×2 cm pocket), which may differ from AFI. Even when AFI is technically <5 cm, if a 2×2 cm pocket is identified, the BPP amniotic fluid component scores 2. However, oligohydramnios on any measurement is always clinically significant.
Causes of oligohydramnios:
  • Placental insufficiency (FGR) - most common
  • Fetal renal agenesis / obstructive uropathy
  • PPROM
  • Post-dates pregnancy
  • NSAID exposure (closes ductus arteriosus, also reduces renal flow)

3. Indications for Antepartum Surveillance

High-risk conditions warranting initiation of formal antepartum testing (typically from 32-34 weeks, or earlier for severe cases):
Maternal conditions:
  • Hypertensive disorders (chronic hypertension, preeclampsia)
  • Diabetes mellitus (pre-gestational or poorly controlled GDM)
  • Renal disease
  • Systemic lupus erythematosus / antiphospholipid syndrome
  • Sickle cell disease / hemoglobinopathies
  • Thyroid disease (hyperthyroidism)
  • Cardiac disease
Obstetric/fetal conditions:
  • Fetal growth restriction (FGR)
  • Decreased fetal movement
  • Post-dates pregnancy (≥41 weeks)
  • Multiple gestation with growth discordance
  • Oligohydramnios or polyhydramnios
  • Fetal anomalies requiring monitoring
  • Isoimmunization (Rh or other)
  • Prior stillbirth
  • Unexplained third-trimester bleeding
  • Preterm labor treated conservatively

4. Integrated Testing Algorithms

No single test satisfies all criteria for ideal fetal surveillance. Multiple-variable approaches are more reliable.

Typical Stepwise Algorithm (outpatient):

Weekly or twice-weekly modified BPP (NST + AFI)
         |
    Reactive NST + normal AFI
         |
    Reassuring - repeat per schedule
         |
    Non-reactive NST or abnormal AFI
         |
         V
    Full BPP (ultrasound 30 min)
         |
    BPP ≥8/10, normal AFV → Continue monitoring
    BPP 6/10 → Repeat in 4-6 hrs; if still 6, consider delivery
    BPP ≤4/10 → Deliver
         |
    Concurrent UA Doppler (FGR cases)
    AEDV/REDV → Escalate to daily monitoring + consider DV Doppler
    Reversed DV a-wave → Delivery (with corticosteroids if <34 wks)

Testing Frequency:

  • Once weekly: most high-risk conditions
  • Twice weekly: severe FGR, post-dates, multiple gestation with complications, uncontrolled diabetes, preeclampsia
  • Daily or near-daily: AEDV on UA Doppler, severe preeclampsia remote from term

5. Ideal Characteristics of a Fetal Monitoring Test

From Creasy & Resnik's Maternal-Fetal Medicine, the ideal monitoring system should:
  1. Gather a wide range of information, versatile for all conditions and gestational ages
  2. Detect fetal peril with high sensitivity, specificity, and timeliness
  3. Have a low false-positive rate (to avoid unnecessary preterm delivery)
  4. Have high sensitivity for modest degrees of compromise to permit early intervention
  5. Have a high and durable negative predictive value to define a safe testing interval
  6. Incorporate multiple variables to address the complexity of fetal behavior
  7. Detect compromise from multiple etiologies (hypoxia, infection, anemia, metabolic)
  8. Be applicable in outpatient settings, use available technology, be reproducible
  9. Demonstrate measurable benefit in reducing perinatal mortality in high-risk populations
No single test achieves all of these goals - hence the use of combined, multimodal surveillance.

6. Special Situations

Fetal Growth Restriction (FGR)

The most common indication for antepartum surveillance. UA Doppler is the primary tool. The sequence of deterioration in severe early-onset FGR typically follows:
  1. Elevated UA PI → AEDV → REDV
  2. Brain sparing (low MCA PI, low CPR)
  3. Abnormal DV (absent/reversed a-wave)
  4. Abnormal venous pulsations (umbilical vein pulsations)
  5. Abnormal NST / low BPP
The FIGO initiative on FGR (Melamed et al. 2021) provides detailed guidance on staging and delivery timing.

Post-dates Pregnancy (≥41 weeks)

  • Weekly NST + AFI (modified BPP) or twice-weekly testing
  • Oligohydramnios alone is an indication for delivery
  • NST in isolation may miss some adverse outcomes; AFI adds value

Fetal Isoimmunization

  • Serial MCA PSV measurements every 1-2 weeks to detect worsening anemia
  • MCA PSV >1.5 MoM → fetal blood sampling (cordocentesis) and possible intrauterine transfusion

Multiple Gestation

  • Monochorionic twins: surveillance from 16 weeks for twin-to-twin transfusion syndrome (TTTS) with serial ultrasound
  • Growth-discordant twins: same UA Doppler protocol as singleton FGR

7. Limitations and Test Performance

TestFalse-Negative RateFalse-Positive RateKey Limitations
NST alone~1.9/1000 (weekly)~80% of non-reactiveSleep states, medications, prematurity
CST~0.04%~30%Contraindications, inconvenience
Full BPP~0.7/1000Lower than NST aloneTime-consuming, operator-dependent
Modified BPP~0.8/1000IntermediateTwo-variable only
UA DopplerLow in FGRModerate in low-riskRequires expertise; not useful in all conditions

Summary Table

MethodWhat It MeasuresAcute or ChronicWhen Used
Kick countsGross fetal movementAcuteDaily, all at-risk patients
NSTFHR reactivity (CNS-CVS coupling)AcuteWeekly or twice-weekly
CST/OCTUteroplacental reserveAcuteAdjunct when NST non-reactive
Full BPP5 biophysical variablesAcute + ChronicWhen NST non-reactive; FGR
Modified BPPNST + AFIAcute + ChronicFirst-line outpatient surveillance
UA DopplerPlacental vascular resistanceIntermediateFGR, hypertension
MCA Doppler PSVFetal hematocrit/anemiaAcuteIsoimmunization, hydrops
MCA PI/CPRBrain sparing / redistributionIntermediateFGR, placental insufficiency
DV DopplerVenous/cardiac functionLate/severeLate-stage FGR; timing delivery
Uterine artery DopplerMaternal spiral artery remodelingChronic/predictive20-24 week screening
AFI/SDPAmniotic fluid (cumulative renal perfusion)ChronicPart of BPP; oligohydramnios workup

Sources: Creasy & Resnik's Maternal-Fetal Medicine: Principles and Practice (Chapter 32, pp. 718-730); Pfenninger and Fowler's Procedures for Primary Care, 3rd ed. (Chapter 172, pp. 1195-1197); Cochrane Review - Alfirevic Z et al. CD007529, 2017; FIGO Initiative on Fetal Growth (Melamed et al., IJGO 2021).

Build all this into a pdf

Reading File
Running Command

mkdir -p /tmp/workspace/antepartum-fetal-monitoring && ls /tmp/workspace/antepartum-fetal-monitoring/

Writing File

~/antepartum-fetal-monitoring/build_pdf.py

"""
Ante-partum Fetal Monitoring - Comprehensive PDF Generator
Using ReportLab for rich formatting with tables, headings, and images.
"""

import urllib.request
import io
import os
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, PageBreak, KeepTogether, Image
)
from reportlab.platypus.tableofcontents import TableOfContents
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

OUTPUT = "/tmp/workspace/antepartum-fetal-monitoring/Antepartum_Fetal_Monitoring.pdf"

# ── Colour palette ─────────────────────────────────────────────────────────────
NAVY      = colors.HexColor("#1a3a5c")
TEAL      = colors.HexColor("#0d7377")
LIGHT_TEAL= colors.HexColor("#e8f5f5")
ACCENT    = colors.HexColor("#c0392b")
MID_GREY  = colors.HexColor("#4a4a4a")
LIGHT_GREY= colors.HexColor("#f5f5f5")
TABLE_HDR = colors.HexColor("#1a3a5c")
TABLE_ALT = colors.HexColor("#eaf4f4")
WHITE     = colors.white
BLACK     = colors.black

# ── Styles ─────────────────────────────────────────────────────────────────────
BASE = getSampleStyleSheet()

def make_styles():
    styles = {}

    styles["cover_title"] = ParagraphStyle(
        "cover_title", fontSize=28, fontName="Helvetica-Bold",
        textColor=WHITE, alignment=TA_CENTER, leading=34, spaceAfter=8
    )
    styles["cover_sub"] = ParagraphStyle(
        "cover_sub", fontSize=14, fontName="Helvetica",
        textColor=colors.HexColor("#d0eaee"), alignment=TA_CENTER, leading=18
    )
    styles["cover_meta"] = ParagraphStyle(
        "cover_meta", fontSize=10, fontName="Helvetica",
        textColor=colors.HexColor("#a0c8d0"), alignment=TA_CENTER
    )

    styles["h1"] = ParagraphStyle(
        "h1", fontSize=18, fontName="Helvetica-Bold",
        textColor=WHITE, leading=22, spaceBefore=0, spaceAfter=0,
        leftIndent=0, borderPad=0
    )
    styles["h2"] = ParagraphStyle(
        "h2", fontSize=13, fontName="Helvetica-Bold",
        textColor=NAVY, leading=18, spaceBefore=16, spaceAfter=4,
        borderPad=2
    )
    styles["h3"] = ParagraphStyle(
        "h3", fontSize=11, fontName="Helvetica-Bold",
        textColor=TEAL, leading=15, spaceBefore=10, spaceAfter=3
    )
    styles["h4"] = ParagraphStyle(
        "h4", fontSize=10, fontName="Helvetica-BoldOblique",
        textColor=MID_GREY, leading=14, spaceBefore=8, spaceAfter=2
    )
    styles["body"] = ParagraphStyle(
        "body", fontSize=9.5, fontName="Helvetica",
        textColor=MID_GREY, leading=14, spaceBefore=3, spaceAfter=3,
        alignment=TA_JUSTIFY
    )
    styles["bullet"] = ParagraphStyle(
        "bullet", fontSize=9.5, fontName="Helvetica",
        textColor=MID_GREY, leading=14, spaceBefore=2, spaceAfter=2,
        leftIndent=14, bulletIndent=4, alignment=TA_LEFT
    )
    styles["sub_bullet"] = ParagraphStyle(
        "sub_bullet", fontSize=9, fontName="Helvetica",
        textColor=MID_GREY, leading=13, spaceBefore=1, spaceAfter=1,
        leftIndent=28, bulletIndent=18
    )
    styles["caption"] = ParagraphStyle(
        "caption", fontSize=8.5, fontName="Helvetica-Oblique",
        textColor=colors.HexColor("#666666"), leading=12,
        spaceBefore=4, spaceAfter=8, alignment=TA_CENTER
    )
    styles["note_box"] = ParagraphStyle(
        "note_box", fontSize=9, fontName="Helvetica",
        textColor=colors.HexColor("#1a3a5c"), leading=13,
        spaceBefore=2, spaceAfter=2, leftIndent=6
    )
    styles["source"] = ParagraphStyle(
        "source", fontSize=7.5, fontName="Helvetica-Oblique",
        textColor=colors.HexColor("#888888"), leading=11,
        spaceBefore=2, spaceAfter=2
    )
    return styles

S = make_styles()

# ── Helpers ────────────────────────────────────────────────────────────────────
def section_header(number, title):
    """Returns a navy banner row for a major section."""
    data = [[Paragraph(f"{number}. {title}", S["h1"])]]
    t = Table(data, colWidths=[17*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), NAVY),
        ("TOPPADDING", (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING", (0,0), (-1,-1), 12),
        ("RIGHTPADDING", (0,0), (-1,-1), 12),
        ("ROUNDEDCORNERS", [4,4,4,4]),
    ]))
    return t

def h2(text): return Paragraph(text, S["h2"])
def h3(text): return Paragraph(text, S["h3"])
def h4(text): return Paragraph(text, S["h4"])
def p(text):  return Paragraph(text, S["body"])
def sp(n=6):  return Spacer(1, n)
def hr():     return HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#cccccc"), spaceAfter=4, spaceBefore=4)

def bullets(items, style="bullet"):
    return [Paragraph(f"• {item}", S[style]) for item in items]

def sub_bullets(items):
    return [Paragraph(f"  ◦ {item}", S["sub_bullet"]) for item in items]

def note_box(lines):
    """A teal-background callout box."""
    content = [Paragraph(l, S["note_box"]) for l in lines]
    t = Table([[content]], colWidths=[17*cm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), LIGHT_TEAL),
        ("BOX", (0,0), (-1,-1), 1, TEAL),
        ("LEFTPADDING", (0,0), (-1,-1), 10),
        ("RIGHTPADDING", (0,0), (-1,-1), 10),
        ("TOPPADDING", (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
    ]))
    return t

def make_table(header_row, data_rows, col_widths, alternate=True):
    all_rows = [header_row] + data_rows
    t = Table(all_rows, colWidths=col_widths, repeatRows=1)
    style_cmds = [
        ("BACKGROUND", (0,0), (-1,0), TABLE_HDR),
        ("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"),
        ("FONTNAME", (0,1), (-1,-1), "Helvetica"),
        ("FONTSIZE", (0,1), (-1,-1), 8.5),
        ("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#b0c8c8")),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, TABLE_ALT] if alternate else [WHITE]),
        ("TOPPADDING", (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING", (0,0), (-1,-1), 6),
        ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ]
    t.setStyle(TableStyle(style_cmds))
    return t

def fetch_image_to_file(url, filename):
    """Download image URL to local file; return path or None."""
    try:
        path = f"/tmp/workspace/antepartum-fetal-monitoring/{filename}"
        urllib.request.urlretrieve(url, path)
        return path
    except Exception as e:
        print(f"  [warn] Could not fetch {url}: {e}")
        return None

def embed_image(path, width_cm=13, caption=None):
    """Return list of flowables for an image + optional caption."""
    if path is None:
        return []
    try:
        img = Image(path, width=width_cm*cm, kind="proportional")
        items = [sp(4), img]
        if caption:
            items.append(Paragraph(caption, S["caption"]))
        items.append(sp(4))
        return items
    except Exception as e:
        print(f"  [warn] Could not embed image {path}: {e}")
        return []

# ── Page template callbacks ────────────────────────────────────────────────────
def on_first_page(canvas, doc):
    canvas.saveState()
    w, h = A4
    # Full-page gradient background (navy to teal)
    canvas.setFillColor(NAVY)
    canvas.rect(0, 0, w, h, fill=1, stroke=0)
    canvas.setFillColor(TEAL)
    canvas.rect(0, 0, w, h*0.42, fill=1, stroke=0)
    # Decorative top stripe
    canvas.setFillColor(colors.HexColor("#0a5c6b"))
    canvas.rect(0, h-6, w, 6, fill=1, stroke=0)
    canvas.restoreState()

def on_later_pages(canvas, doc):
    canvas.saveState()
    w, h = A4
    # Header bar
    canvas.setFillColor(NAVY)
    canvas.rect(0, h-22, w, 22, fill=1, stroke=0)
    canvas.setFont("Helvetica-Bold", 8)
    canvas.setFillColor(WHITE)
    canvas.drawString(1.5*cm, h-14, "Ante-partum Fetal Monitoring — Comprehensive Reference")
    canvas.drawRightString(w-1.5*cm, h-14, f"Page {doc.page}")
    # Footer line
    canvas.setStrokeColor(colors.HexColor("#cccccc"))
    canvas.setLineWidth(0.5)
    canvas.line(1.5*cm, 1.5*cm, w-1.5*cm, 1.5*cm)
    canvas.setFont("Helvetica", 7)
    canvas.setFillColor(colors.HexColor("#999999"))
    canvas.drawCentredString(w/2, 0.9*cm, "Sources: Creasy & Resnik's Maternal-Fetal Medicine | Pfenninger & Fowler's Procedures for Primary Care | Cochrane Reviews")
    canvas.restoreState()

# ── Build document ─────────────────────────────────────────────────────────────
def build():
    doc = SimpleDocTemplate(
        OUTPUT,
        pagesize=A4,
        leftMargin=2*cm, rightMargin=2*cm,
        topMargin=2.8*cm, bottomMargin=2.5*cm,
        title="Ante-partum Fetal Monitoring",
        author="Orris Medical Reference",
        subject="Obstetrics – Antepartum Surveillance",
    )

    story = []

    # ── Pre-fetch images ──────────────────────────────────────────────────────
    print("Fetching images...")
    img_bpp = fetch_image_to_file(
        "https://cdn.orris.care/cdss_images/ba407a1db3b165de80a1c1caec35548e3164dbe25555ac344cd4bbf8805aead7.png",
        "bpp_graph.png"
    )
    img_mca = fetch_image_to_file(
        "https://cdn.orris.care/cdss_images/b198b293f52e244f0d7d1bfe71b2e2f0401aa1f60d05afe57c272bbb74c7676b.png",
        "mca_doppler.png"
    )
    print(f"  BPP graph: {img_bpp}")
    print(f"  MCA Doppler: {img_mca}")

    # ══════════════════════════════════════════════════════════════════════════
    # COVER PAGE
    # ══════════════════════════════════════════════════════════════════════════
    story.append(Spacer(1, 5.5*cm))
    story.append(Paragraph("ANTE-PARTUM", S["cover_title"]))
    story.append(Paragraph("FETAL MONITORING", S["cover_title"]))
    story.append(Spacer(1, 0.6*cm))
    story.append(HRFlowable(width="60%", thickness=2, color=TEAL, hAlign="CENTER", spaceAfter=12))
    story.append(Paragraph("Comprehensive Clinical Reference", S["cover_sub"]))
    story.append(Spacer(1, 0.4*cm))
    story.append(Paragraph("Physiology · Tests · Doppler Velocimetry · Algorithms · Special Situations", S["cover_sub"]))
    story.append(Spacer(1, 5.5*cm))
    story.append(Paragraph("Sources: Creasy & Resnik's Maternal-Fetal Medicine (9e) · Pfenninger & Fowler's Procedures for Primary Care (3e)", S["cover_meta"]))
    story.append(Paragraph("Cochrane Database of Systematic Reviews · FIGO Fetal Growth Initiative 2021", S["cover_meta"]))
    story.append(Spacer(1, 0.3*cm))
    story.append(Paragraph("July 2026", S["cover_meta"]))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 1 — Physiological Basis
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("1", "Physiological Basis of Ante-partum Monitoring"))
    story.append(sp(10))

    story.append(h2("Core Principle"))
    story.append(p(
        "Any fetal monitoring technology should be thought of as a <b>screening test for fetal hypoxemia and acidosis</b>, "
        "with the ultimate goals of reducing stillbirth and improving neonatal outcome. Fetal assessment assumes that a "
        "change in fetal behavior implies a change in fetal status. Maternal evaluation of fetal activity, nonstress "
        "testing, and the biophysical profile (BPP) all rely on this principle."
    ))
    story.append(sp())

    story.append(h2("Fetal Heart Rate (FHR) Development"))
    story.append(p(
        "As gestation advances, the FHR is increasingly dominated by the <b>parasympathetic nervous system</b>, "
        "resulting in:"
    ))
    story += bullets([
        "A gradual decrease in baseline heart rate toward term",
        "Increasing beat-to-beat variability",
        "Progressive responsiveness to fetal movement (accelerations)",
        "Increasing coupling of CNS neurological status to cardiovascular reflex responses",
    ])
    story.append(p(
        "The capacity to accelerate the FHR in response to movement is directly linked to fetal oxygenation and "
        "metabolic state. Preterm fetuses, growth-restricted fetuses, or those exposed to maternal medications "
        "(narcotics, magnesium sulfate) may have attenuated accelerations without true compromise — an important "
        "source of false-positive tests."
    ))
    story.append(sp())

    story.append(h2("Hierarchy of CNS Vulnerability Under Hypoxia"))
    story.append(p(
        "Under progressive hypoxia, fetal CNS centres are suppressed in a predictable order from most sensitive "
        "to least sensitive. This hierarchy underpins BPP interpretation:"
    ))
    hier_data = [
        [Paragraph("<b>Order</b>", S["body"]), Paragraph("<b>Function Lost</b>", S["body"]), Paragraph("<b>Test Affected</b>", S["body"]), Paragraph("<b>CNS Centre</b>", S["body"])],
        ["1st (most sensitive)", "FHR reactivity", "Non-stress test (NST)", "Cortical / higher centres"],
        ["2nd", "Fetal breathing movements", "BPP — FBM component", "Respiratory centre"],
        ["3rd", "Gross body movements", "BPP — FM component", "Motor cortex"],
        ["4th (least sensitive)", "Fetal tone", "BPP — tone component", "Primitive brainstem reflex"],
        ["Chronic marker", "Amniotic fluid volume", "BPP — AFV / AFI", "Renal perfusion (cumulative)"],
    ]
    story.append(make_table(hier_data[0], hier_data[1:], [2.5*cm, 4*cm, 4.5*cm, 6*cm]))
    story.append(sp(6))

    story.append(note_box([
        "⚕ Key point: Amniotic fluid volume reflects cumulative placental function over days-to-weeks "
        "(analogous to HbA1c for glucose). It is the last variable to normalise and a late sign of chronic insufficiency.",
    ]))
    story.append(sp(8))

    story.append(h2("Ideal Characteristics of a Fetal Monitoring Test"))
    story.append(p("From Creasy & Resnik's Maternal-Fetal Medicine, an ideal monitoring system should:"))
    story += bullets([
        "Gather a wide range of information — versatile for all maternal/fetal conditions and gestational ages",
        "Detect fetal peril with high sensitivity, specificity, and timeliness to allow preventive intervention",
        "Have a <b>low false-positive rate</b>, especially at earlier gestational ages when prematurity risk is highest",
        "Have <b>high sensitivity</b> for modest compromise to permit early enough intervention to prevent injury",
        "Have a high and durable <b>negative predictive value</b> — reliably excludes stillbirth over a predictable interval",
        "Incorporate <b>multiple variables</b> to address the complexity of normal fetal behavior",
        "Detect compromise from multiple causes: asphyxia, infection, metabolic abnormalities, anemia",
        "Be applicable in outpatient and inpatient settings, use available technology, and be reproducible",
        "Demonstrate measurable benefits in reducing perinatal mortality and morbidity in high-risk populations",
    ])
    story.append(p(
        "<i>No single test satisfies all these objectives. In balancing the risks of stillbirth from intrauterine "
        "decompensation against neonatal morbidity from prematurity, the use of multiple methods of assessment "
        "is more likely to yield reliable results.</i>"
    ))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 2 — Methods of Surveillance
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("2", "Methods of Antepartum Surveillance"))
    story.append(sp(10))

    # ── 2.1 Kick Counts
    story.append(h2("2.1  Fetal Movement Counting (Kick Counts)"))
    story.append(p(
        "The simplest and most accessible form of surveillance. The mother records active fetal movements daily. "
        "Decreased fetal movement may precede fetal compromise by days and warrants immediate clinical evaluation."
    ))
    story += bullets([
        "<b>Cardiff 'Count to Ten' method:</b> Count movements until 10 are felt; normal if 10 occur within 2 hours",
        "<b>Sadovsky method:</b> Count for 1 hour three times daily; normal is &gt;4 movements per hour",
        "<b>Absence of movement for &gt;12 hours:</b> warrants immediate assessment",
    ])
    story.append(p("Limitations: subjective, affected by maternal perception, sleep states, oligohydramnios, anterior placenta, maternal obesity."))
    story.append(sp(8))

    # ── 2.2 NST
    story.append(h2("2.2  Non-Stress Test (NST)"))
    story.append(p(
        "The NST is the cornerstone of outpatient antepartum surveillance. It assesses FHR reactivity as a "
        "surrogate for intact fetal CNS-cardiovascular coupling — the most sensitive short-term predictor of "
        "worsening hypoxaemia or acidosis."
    ))

    story.append(h3("Procedure"))
    story += bullets([
        "External FHR monitor (cardiotocograph) placed on the maternal abdomen",
        "Standard duration: 20 minutes; extended to 40 minutes if initial period is non-reactive",
        "Uterine activity recorded simultaneously",
        "Vibroacoustic stimulation (VAS) may be used to convert quiet sleep state and shorten testing time",
    ])

    story.append(h3("Reactive NST (Normal)"))
    story.append(note_box([
        "≥2 FHR accelerations of ≥15 bpm above baseline, lasting ≥15 seconds, within a 20–30 min window, associated with fetal movement",
        "Reassures fetal well-being for approximately 1 week in most clinical settings",
        "False-negative rate (fetal death within 1 week): ~1.9 per 1,000",
    ]))

    story.append(h3("Gestational Age Modification (<32 weeks)"))
    story.append(p(
        "Accelerations of ≥10 bpm lasting ≥10 seconds are accepted as reactive in the context of normal FHR "
        "variability for fetuses &lt;32 weeks' gestation, acknowledging that younger fetuses produce smaller accelerations."
    ))

    story.append(h3("Non-Reactive NST"))
    story.append(p(
        "Defined by failure to meet reactivity criteria within the allotted time (up to 40–60 minutes depending "
        "on protocol). Approximately 10–12% of third-trimester fetuses are non-reactive at 30 minutes; this "
        "falls below 6% by 40 minutes. A non-reactive NST is <b>not diagnostic of compromise</b> — it triggers "
        "further assessment (full BPP or CST)."
    ))
    story.append(h4("Common causes of non-reactive NST without true compromise:"))
    story += bullets([
        "Fetal sleep cycle (most common cause)",
        "Prematurity (&lt;28 weeks)",
        "Fetal CNS anomalies",
        "Maternal medications (narcotics, magnesium sulfate, steroids)",
        "Fetal anaemia",
    ])

    story.append(h3("Vibroacoustic Stimulation (VAS)"))
    story.append(p(
        "Vibration sense is fully developed by 22–24 weeks; auditory response by ~26 weeks. An electromechanical "
        "device applied to the maternal abdomen produces broad-band atonal white noise (0.1–10 kHz), provoking "
        "fetal state change from quiet sleep to active sleep. VAS shortens monitoring time, converts many "
        "non-reactive NSTs without pathological significance, but carries rare risk of fetal bradycardia and "
        "has limited long-term safety data."
    ))
    story.append(sp(8))

    # ── 2.3 CST / OCT
    story.append(h2("2.3  Contraction Stress Test (CST) and Oxytocin Challenge Test (OCT)"))
    story.append(p(
        "The CST evaluates <b>uteroplacental reserve</b> by examining the FHR response to uterine contractions, "
        "which transiently reduce intervillous blood flow. A fetus with marginal placental reserve may maintain "
        "adequate oxygenation at rest but decompensate during contractions, producing late decelerations."
    ))

    story.append(h3("Methods of Inducing Contractions"))
    story += bullets([
        "<b>Nipple stimulation CST:</b> Patient stimulates one nipple for 2-minute intervals, harnessing endogenous oxytocin release",
        "<b>Oxytocin Challenge Test (OCT):</b> IV oxytocin infusion titrated to achieve 3 contractions in 10 minutes, each lasting 40–60 seconds",
    ])

    story.append(h3("Interpretation"))
    cst_data = [
        [Paragraph("<b>Result</b>", S["body"]), Paragraph("<b>Definition</b>", S["body"]), Paragraph("<b>Clinical Action</b>", S["body"])],
        ["Negative (Normal)", "No late or significant variable decelerations", "Reassuring — repeat in 1 week"],
        ["Positive (Abnormal)", "Late decelerations following ≥50% of contractions", "High-risk — delivery planning or intensive monitoring"],
        ["Equivocal-Suspicious", "Intermittent late or significant variable decelerations", "Repeat test"],
        ["Equivocal-Hyperstimulation", "Decelerations with contractions >90 sec or >2 in 10 min", "Repeat when uterine activity normalises"],
        ["Unsatisfactory", "<3 contractions in 10 min or uninterpretable tracing", "Repeat test"],
    ]
    story.append(make_table(cst_data[0], cst_data[1:], [4*cm, 7*cm, 6*cm]))

    story.append(h3("Performance and Limitations"))
    story += bullets([
        "False-positive rate: <b>~30%</b> — leading to unnecessary interventions",
        "False-negative rate: <b>~0.04%</b> — very low",
        "Now used less commonly than the BPP or modified BPP due to contraindications and high false-positive rate",
    ])
    story.append(h4("Contraindications:"))
    story += bullets([
        "Preterm labour risk (cervical incompetence, prior preterm labour)",
        "Preterm premature rupture of membranes (PPROM)",
        "Multiple gestation with complications",
        "Prior classical (vertical) uterine incision",
        "Placenta praevia or vasa praevia",
    ], style="sub_bullet")
    story.append(PageBreak())

    # ── 2.4 BPP
    story.append(section_header("2", "Methods of Surveillance (continued)"))
    story.append(sp(10))
    story.append(h2("2.4  Biophysical Profile (BPP)"))
    story.append(p(
        "Introduced by Manning in 1980, the BPP combines <b>four acute neurological markers</b> (reflecting "
        "real-time CNS oxygenation) with <b>one chronic marker</b> (amniotic fluid volume, reflecting days-to-weeks "
        "of cumulative placental function). It is conceptually similar to performing an in utero neurological "
        "examination of the infant."
    ))

    story.append(h3("The Five BPP Variables"))
    bpp_data = [
        [Paragraph("<b>Variable</b>", S["body"]), Paragraph("<b>Score 2 (Normal)</b>", S["body"]), Paragraph("<b>Score 0 (Abnormal)</b>", S["body"]), Paragraph("<b>Marker Type</b>", S["body"])],
        ["Fetal Breathing Movement (FBM)",
         "≥30 sec of sustained FBM in 30 min of observation",
         "<30 sec of FBM in 30 min",
         "Acute"],
        ["Fetal Body Movement (FM)",
         "≥3 gross body movements in 30 min (simultaneous limb+trunk = 1 movement)",
         "≤2 gross movements in 30 min",
         "Acute"],
        ["Fetal Tone (FT)",
         "≥1 episode of limb extension → rapid return to flexion; or spine extension/flexion",
         "Fetus in semi/full extension; no return to flexion; absent movement = absent tone",
         "Acute"],
        ["FHR Reactivity (NST)",
         "≥2 accelerations ≥15 bpm × ≥15 sec with movement in 30 min",
         "<2 qualifying accelerations during observation",
         "Acute"],
        ["Amniotic Fluid Volume (AFV)",
         "Pocket ≥2 cm in two perpendicular planes (or AFI ≥5 cm)",
         "Largest pocket <2 cm in two perpendicular planes",
         "Chronic"],
    ]
    story.append(make_table(bpp_data[0], bpp_data[1:], [3.5*cm, 5.5*cm, 4.5*cm, 3.5*cm]))
    story.append(p("<b>Maximum score: 10/10 &nbsp;|&nbsp; Minimum: 0/10</b>"))
    story.append(sp(6))

    story.append(h3("BPP Score Interpretation and Management"))
    mgmt_data = [
        [Paragraph("<b>Score</b>", S["body"]), Paragraph("<b>Risk of Fetal Acidosis</b>", S["body"]), Paragraph("<b>Management</b>", S["body"])],
        ["10/10 or 8/10 (normal AFV)", "Very low (<1 in 1,000)", "Reassured — routine follow-up per risk profile"],
        ["8/10 (abnormal AFV)", "Moderate", "Deliver if ≥36 weeks; intensive monitoring if preterm"],
        ["6/10", "Equivocal (variable)", "Deliver if ≥36 wks or mature; repeat in 4–6 hrs if preterm"],
        ["4/10", "High", "Deliver unless remote from viability"],
        ["2/10 or 0/10", "Very high", "Deliver regardless of gestational age"],
    ]
    story.append(make_table(mgmt_data[0], mgmt_data[1:], [4*cm, 5*cm, 8*cm]))

    story.append(sp(6))
    story.append(note_box([
        "⚠ Oligohydramnios constitutes an abnormal BPP regardless of the overall score.",
        "Even if all 4 acute markers are normal (score 8), the presence of oligohydramnios mandates further evaluation and often delivery.",
    ]))
    story.append(sp(8))

    story.append(h3("Why Combine Variables? (Manning's Planning Score)"))
    story.append(p(
        "The figure below shows that the full five-variable BPP (the 'Planning Score') achieves the lowest rate "
        "of adverse neonatal outcomes — statistically significantly better than any single variable alone."
    ))
    story += embed_image(img_bpp, width_cm=14,
        caption="Figure: Prediction of adverse outcome (5-min Apgar <7) by individual BPP variables (left) vs. combined variables (right). "
                "The full Planning Score (all 5 variables) achieves the lowest adverse outcome rate. "
                "AFV, Amniotic fluid volume; FBM, fetal breathing movement; FM, fetal movement; FT, fetal tone; NST, nonstress test. "
                "(Source: Creasy & Resnik's Maternal-Fetal Medicine)")

    story.append(h3("Pathophysiology of Low BPP in Chronic Hypoxia"))
    story.append(p(
        "When the fetus experiences sustained placental insufficiency, cardiac output is redistributed away from "
        "non-vital organs (kidneys, lungs) toward vital organs (brain, heart, adrenals). Decreased renal perfusion "
        "reduces urine production, leading to oligohydramnios. A low AFI may be the <b>earliest chronic marker</b> "
        "of placental insufficiency."
    ))
    story.append(sp(8))

    # ── 2.5 Modified BPP
    story.append(h2("2.5  Modified Biophysical Profile (Modified BPP)"))
    story.append(p(
        "A practical two-component test combining:"
    ))
    story += bullets([
        "<b>NST</b> — acute marker of CNS/cardiovascular function",
        "<b>Amniotic Fluid Index (AFI)</b> — chronic marker of placental function",
    ])
    story.append(note_box([
        "Normal modified BPP: Reactive NST + AFI ≥5 cm",
        "Abnormal modified BPP: Non-reactive NST OR AFI <5 cm → proceed to full BPP or CST",
    ]))
    story.append(p(
        "The modified BPP is the most widely used first-line outpatient surveillance tool. It requires less time "
        "than the full BPP, while combining both acute and chronic markers. It performs comparably to the full "
        "BPP for predicting fetal compromise in most high-risk populations."
    ))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 3 — Doppler Velocimetry
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("3", "Doppler Velocimetry"))
    story.append(sp(10))
    story.append(p(
        "Doppler ultrasound assesses blood flow velocity waveforms in specific fetal and maternal vessels. "
        "It provides functional information about placental vascular resistance and the fetal circulatory "
        "adaptation to compromise. The Cochrane systematic review (Alfirevic et al. 2017, CD007529) confirmed "
        "that umbilical artery Doppler in high-risk pregnancies reduces perinatal mortality."
    ))
    story.append(sp(4))

    story.append(h2("3.1  Umbilical Artery (UA) Doppler"))
    story.append(p(
        "The umbilical artery supplies the placenta. As placental vascular resistance rises due to obliterative "
        "vasculopathy (e.g., in FGR or preeclampsia), diastolic flow progressively diminishes."
    ))

    story.append(h3("Waveform Indices"))
    story += bullets([
        "<b>S/D ratio</b> (systolic:diastolic): normally falls with advancing gestation as placental resistance decreases",
        "<b>Resistance Index (RI)</b> = (S − D) / S",
        "<b>Pulsatility Index (PI)</b> = (S − D) / mean velocity",
    ])

    story.append(h3("Spectrum of Abnormality — in order of severity"))
    ua_data = [
        [Paragraph("<b>Finding</b>", S["body"]), Paragraph("<b>Pathological Significance</b>", S["body"]), Paragraph("<b>Clinical Implication</b>", S["body"])],
        ["Elevated S/D ratio / high PI or RI", "Increased placental resistance; ~30% of villous tree obliterated", "Intensify surveillance; serial Doppler"],
        ["Absent End-Diastolic Velocity (AEDV)", "~60–70% of villous tree obliterated", "High risk — daily monitoring; consider DV Doppler; plan delivery timing"],
        ["Reversed End-Diastolic Velocity (REDV)", ">70% obliteration; imminent cardiac decompensation", "Very high risk — hospitalise; REDV + abnormal DV = near-immediate delivery"],
    ]
    story.append(make_table(ua_data[0], ua_data[1:], [5.5*cm, 6*cm, 5.5*cm]))
    story.append(p(
        "AEDV and REDV are independently associated with substantially increased rates of intraventricular "
        "haemorrhage, necrotising enterocolitis, need for transfusion, and perinatal mortality. The frequency "
        "of all these outcomes rises progressively from elevated indices → AEDV → REDV."
    ))
    story.append(sp(6))

    story.append(h2("3.2  Middle Cerebral Artery (MCA) Doppler"))
    story.append(p(
        "The MCA is short, straight, and anatomically consistent, making it ideal for Doppler measurement. "
        "The Doppler angle can be minimised, enabling direct interpretation of peak systolic velocity (PSV). "
        "Ideal sampling location: 2 mm past the origin of the MCA from the internal carotid artery."
    ))

    story.append(h3("Application 1 — Fetal Anemia Assessment"))
    story.append(p(
        "As fetal haematocrit falls and oxygen-carrying capacity decreases, cardiac output increases and blood "
        "viscosity decreases, raising the MCA PSV. An <b>MCA PSV &gt;1.5 multiples of the median (MoM)</b> for "
        "gestational age predicts moderate-to-severe fetal anaemia with high sensitivity (~88%) and specificity "
        "(~82%), replacing the need for invasive amniocentesis for optical density measurement."
    ))

    story.append(h3("Application 2 — Brain Sparing (Cerebral Redistribution)"))
    story.append(p(
        "In fetal hypoxia from placental insufficiency, cardiac output is redistributed toward the brain, "
        "increasing diastolic MCA velocities and <b>lowering</b> the MCA PI/RI. Key abnormalities:"
    ))
    story += bullets([
        "<b>Low MCA PI</b> (especially &lt;5th percentile for gestational age): indicates increased cerebral perfusion",
        "<b>Cerebro-placental ratio (CPR)</b> = MCA PI / UA PI: falls below 1.0 (or &lt;5th percentile) in redistribution",
        "CPR is a sensitive early marker of circulatory compromise, detecting redistribution before overt changes appear in either vessel alone",
    ])
    story.append(p(
        "Cerebral blood flow (MCA) is also responsive to maternal oxygen administration (increases resistance), "
        "CO₂ (decreases resistance), and nicotine (increases resistance with reduced responsiveness)."
    ))

    story.append(sp(4))
    story += embed_image(img_mca, width_cm=13,
        caption="Figure: Serial MCA Doppler PSV measurements in a fetus with severe anti-D isoimmune anaemia. "
                "Top (pre-transfusion): PSV 60 cm/s → haematocrit 19. "
                "Middle (post-transfusion): PSV fell to 41 cm/s → haematocrit 44. "
                "Bottom (recurrence): PSV rose to 62 cm/s → haematocrit 20. "
                "(Source: Creasy & Resnik's Maternal-Fetal Medicine)")

    story.append(h2("3.3  Ductus Venosus (DV) Doppler"))
    story.append(p(
        "The ductus venosus is a shunt between the umbilical vein and the inferior vena cava, bypassing "
        "hepatic circulation. It preferentially delivers oxygenated blood to the foramen ovale and hence "
        "to the coronary and cerebral circulations."
    ))
    story.append(h3("Normal Waveform"))
    story.append(p("Triphasic: S wave (ventricular systole), D wave (passive ventricular filling), a wave (atrial contraction) — all with <b>forward flow</b>."))
    story.append(h3("Abnormal Findings"))
    story += bullets([
        "<b>Absent a-wave:</b> elevated cardiac end-diastolic pressure — early venous compromise",
        "<b>Reversed a-wave:</b> severely elevated venous pressures, cardiac decompensation — associated with very high perinatal mortality",
    ])
    story.append(p(
        "DV Doppler is particularly useful in severe FGR at very preterm gestations, guiding the timing of "
        "delivery. Progressive deterioration from abnormal UA → abnormal DV typically occurs over days to "
        "weeks, providing a window for corticosteroid administration and optimised delivery planning."
    ))
    story.append(sp(8))

    story.append(h2("3.4  Uterine Artery Doppler"))
    story.append(p(
        "Assesses maternal spiral artery remodelling by trophoblastic invasion. After 24 weeks, resistance "
        "normally falls as trophoblasts remodel spiral arteries and notching disappears."
    ))
    story += bullets([
        "<b>Persistent bilateral uterine artery notching</b> and/or high PI at 20–24 weeks predicts subsequent preeclampsia (sensitivity ~40–60% for severe disease), FGR, and placental abruption",
        "Used primarily as a <b>second-trimester screening tool</b> for placental complications rather than real-time fetal surveillance",
    ])
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 4 — Amniotic Fluid Assessment
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("4", "Amniotic Fluid Assessment"))
    story.append(sp(10))
    story.append(p(
        "Amniotic fluid volume reflects fetal urine production (renal perfusion) and swallowing. It is a "
        "'memory' of placental function over the preceding weeks — a chronic marker of fetal oxygenation. "
        "A low AFI may be the earliest chronic marker of placental insufficiency."
    ))

    story.append(h2("Measurement Methods"))

    story.append(h3("1. Amniotic Fluid Index (AFI) — Four-Quadrant Technique"))
    story += bullets([
        "Sum of the deepest vertical pocket in each of four uterine quadrants (cm)",
        "Normal range: 5–25 cm (varies by gestational age, peaks ~32–34 weeks)",
        "<b>Oligohydramnios:</b> AFI &lt;5 cm",
        "<b>Borderline:</b> AFI 5–8 cm",
        "<b>Polyhydramnios:</b> AFI &gt;25 cm",
    ])

    story.append(h3("2. Single Deepest Pocket (SDP) / Maximum Vertical Pocket (MVP)"))
    story += bullets([
        "Measures the single largest vertical pocket without cord or fetal parts",
        "Normal: 2–8 cm",
        "<b>Oligohydramnios:</b> SDP &lt;2 cm; <b>Polyhydramnios:</b> SDP &gt;8 cm",
        "Preferred by ISUOG and many European centres as it reduces unnecessary intervention rate",
    ])

    story.append(note_box([
        "BPP uses a 2 cm in two perpendicular planes criterion (a 2×2 cm pocket). Even if AFI <5 cm technically, "
        "if a 2×2 cm pocket is identified, the BPP AFV component scores 2. However, oligohydramnios on any "
        "measurement remains clinically significant and warrants evaluation.",
    ]))

    story.append(h2("Causes of Oligohydramnios"))
    story += bullets([
        "Placental insufficiency (FGR) — most common in the third trimester",
        "Fetal renal agenesis or obstructive uropathy (bilateral renal pathology)",
        "Preterm premature rupture of membranes (PPROM)",
        "Post-dates pregnancy (≥42 weeks)",
        "NSAID exposure (prostaglandin inhibition closes ductus arteriosus; also reduces renal flow)",
        "Uteroplacental insufficiency from any cause",
    ])
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 5 — Indications
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("5", "Indications for Antepartum Surveillance"))
    story.append(sp(10))
    story.append(p(
        "Formal antepartum testing is typically initiated from 32–34 weeks, or earlier in severe cases. "
        "The onset timing is individualised based on the severity of the condition and the anticipated "
        "balance of risks from fetal compromise vs. prematurity."
    ))

    ind_data = [
        [Paragraph("<b>Category</b>", S["body"]), Paragraph("<b>Indications</b>", S["body"])],
        ["Maternal Conditions",
         "• Hypertensive disorders (chronic HTN, preeclampsia)\n• Pre-gestational diabetes or poorly controlled GDM\n"
         "• Renal disease (chronic or acute)\n• Systemic lupus erythematosus / antiphospholipid syndrome\n"
         "• Sickle cell disease / haemoglobinopathies\n• Hyperthyroidism / significant cardiac disease"],
        ["Obstetric / Fetal Conditions",
         "• Fetal growth restriction (FGR) — primary indication\n• Decreased fetal movement\n"
         "• Post-dates pregnancy (≥41 weeks)\n• Multiple gestation with growth discordance\n"
         "• Oligohydramnios or polyhydramnios\n• Fetal anomalies requiring monitoring\n"
         "• Isoimmunisation (Rh or other blood group antibodies)\n• Prior stillbirth\n"
         "• Unexplained third-trimester bleeding\n• Conservatively managed preterm labour"],
    ]
    t = Table(ind_data, colWidths=[5*cm, 12*cm], repeatRows=1)
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,0), TABLE_HDR),
        ("TEXTCOLOR", (0,0), (-1,0), WHITE),
        ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE", (0,0), (-1,-1), 9),
        ("VALIGN", (0,0), (-1,-1), "TOP"),
        ("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#b0c8c8")),
        ("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, TABLE_ALT]),
        ("TOPPADDING", (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING", (0,0), (-1,-1), 8),
        ("RIGHTPADDING", (0,0), (-1,-1), 8),
    ]))
    story.append(t)
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 6 — Integrated Algorithm
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("6", "Integrated Testing Algorithms"))
    story.append(sp(10))
    story.append(p(
        "No single test satisfies all criteria for ideal fetal surveillance. Multiple-variable approaches are "
        "more reliable. The following represents a standard stepwise approach used in most high-risk obstetric centres."
    ))

    story.append(h2("Stepwise Algorithm — Outpatient High-Risk Surveillance"))

    alg_data = [
        [Paragraph("<b>Step</b>", S["body"]), Paragraph("<b>Test</b>", S["body"]), Paragraph("<b>Result</b>", S["body"]), Paragraph("<b>Next Action</b>", S["body"])],
        ["1", "Modified BPP\n(NST + AFI)\nWeekly or twice-weekly",
         "Reactive NST + AFI ≥5 cm",
         "Reassuring — repeat per schedule"],
        ["1 (abnormal)", "Modified BPP",
         "Non-reactive NST OR AFI <5 cm",
         "Proceed to full BPP"],
        ["2", "Full BPP\n(5 variables, 30-min US)",
         "≥8/10 with normal AFV",
         "Continue monitoring schedule"],
        ["2 (equivocal)", "Full BPP",
         "6/10",
         "Repeat in 4–6 hrs; if still 6/10 → deliver if ≥36 wks"],
        ["2 (abnormal)", "Full BPP",
         "≤4/10",
         "Deliver (unless extremely preterm — weigh carefully)"],
        ["3 (FGR)", "UA Doppler",
         "AEDV",
         "Daily monitoring; corticosteroids if <34 wks; add DV Doppler"],
        ["3 (FGR)", "UA Doppler",
         "REDV",
         "Hospitalise; near-immediate delivery with steroids if <34 wks"],
        ["4 (FGR)", "DV Doppler",
         "Reversed DV a-wave",
         "Immediate delivery (give steroids if <34 wks, time allowing)"],
        ["Anaemia", "MCA PSV",
         ">1.5 MoM",
         "Fetal blood sampling (cordocentesis) ± intrauterine transfusion"],
    ]
    story.append(make_table(alg_data[0], alg_data[1:], [3*cm, 4*cm, 4.5*cm, 5.5*cm]))

    story.append(sp(8))
    story.append(h2("Testing Frequency"))
    freq_data = [
        [Paragraph("<b>Frequency</b>", S["body"]), Paragraph("<b>Indication</b>", S["body"])],
        ["Once weekly", "Most high-risk conditions (controlled diabetes, mild FGR, prior stillbirth)"],
        ["Twice weekly", "Severe FGR, post-dates ≥41 wks, multiple gestation with complications, uncontrolled diabetes, preeclampsia"],
        ["Daily or near-daily", "AEDV on UA Doppler, severe preeclampsia remote from term, severe FGR with unstable status"],
    ]
    story.append(make_table(freq_data[0], freq_data[1:], [4.5*cm, 12.5*cm]))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 7 — Special Situations
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("7", "Special Clinical Situations"))
    story.append(sp(10))

    story.append(h2("7.1  Fetal Growth Restriction (FGR)"))
    story.append(p(
        "The most common indication for antepartum surveillance. UA Doppler is the primary tool. "
        "Early-onset severe FGR (&lt;32 weeks) typically follows a predictable deterioration sequence:"
    ))
    fgr_data = [
        [Paragraph("<b>Stage</b>", S["body"]), Paragraph("<b>Finding</b>", S["body"]), Paragraph("<b>Typical Timing</b>", S["body"])],
        ["Early compromise", "Elevated UA PI / abnormal UA S/D ratio", "Weeks before delivery"],
        ["Brain sparing", "Low MCA PI; CPR <1.0; redistribution", "Weeks before delivery"],
        ["Advanced", "AEDV (absent end-diastolic velocity) on UA", "Days to 2 weeks before delivery"],
        ["Late/critical", "REDV on UA; abnormal DV (absent/reversed a-wave)", "Hours to days before delivery"],
        ["Terminal", "Reversed DV a-wave; umbilical vein pulsations; abnormal NST/BPP", "Immediate"],
    ]
    story.append(make_table(fgr_data[0], fgr_data[1:], [4*cm, 7*cm, 6*cm]))
    story.append(p(
        "The FIGO initiative on FGR (Melamed et al. 2021, IJGO) provides detailed guidance on staging and "
        "delivery timing based on Doppler findings and gestational age."
    ))
    story.append(sp(8))

    story.append(h2("7.2  Post-dates Pregnancy (≥41 Weeks)"))
    story += bullets([
        "Weekly NST + AFI (modified BPP) or twice-weekly testing recommended",
        "Oligohydramnios alone (AFI &lt;5 cm or SDP &lt;2 cm) is an indication for delivery at ≥41 weeks",
        "NST in isolation may miss some adverse outcomes; AFI adds important value",
        "Most guidelines recommend delivery by 41–42 weeks regardless of surveillance results",
    ])
    story.append(sp(8))

    story.append(h2("7.3  Fetal Isoimmunisation"))
    story += bullets([
        "Serial MCA PSV measurements every 1–2 weeks to detect worsening anaemia",
        "MCA PSV &gt;1.5 MoM for gestational age → proceed to fetal blood sampling (cordocentesis)",
        "If anaemia confirmed (Hb &lt;2 SD below mean for gestation), intrauterine transfusion (IUT) performed",
        "Post-transfusion PSV normalises; rise again indicates recurrence — tracked serially",
    ])
    story.append(sp(8))

    story.append(h2("7.4  Multiple Gestation"))
    story += bullets([
        "<b>Monochorionic twins:</b> surveillance from 16 weeks for twin-to-twin transfusion syndrome (TTTS) with serial ultrasound every 2 weeks",
        "<b>Growth-discordant twins:</b> same UA Doppler protocol as singleton FGR, applied to the smaller twin",
        "<b>TTTS:</b> staging by Quintero criteria; UA, DV, and MCA Doppler all contribute to management",
        "Dichorionic twins: routine growth ultrasound every 4 weeks; more frequent if discordance &gt;20%",
    ])
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 8 — Performance Summary
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("8", "Test Performance and Limitations"))
    story.append(sp(10))

    perf_data = [
        [Paragraph("<b>Test</b>", S["body"]), Paragraph("<b>False-Negative Rate</b>", S["body"]),
         Paragraph("<b>False-Positive Rate</b>", S["body"]), Paragraph("<b>Key Limitations</b>", S["body"])],
        ["Kick counts", "Not well quantified", "Variable", "Subjective; does not identify cause; affected by maternal perception"],
        ["NST alone", "~1.9 per 1,000/week", "~80% of non-reactive results", "Sleep states, medications, prematurity, CNS anomalies"],
        ["CST / OCT", "~0.04%", "~30%", "Contraindications, time-consuming, high false-positive rate"],
        ["Full BPP", "~0.7 per 1,000/week", "Lower than NST alone", "Time-consuming (~30 min); operator-dependent; sleep states"],
        ["Modified BPP", "~0.8 per 1,000/week", "Intermediate", "Only two variables; still affected by sleep/medications"],
        ["UA Doppler", "Low in high-risk (FGR)", "Moderate in low-risk populations", "Not useful for all conditions; requires expertise"],
        ["MCA PSV", "~12% for severe anaemia", "~18%", "Angle-dependent; not useful outside anaemia/redistribution contexts"],
        ["DV Doppler", "Very low for imminent compromise", "Low", "Technically demanding; requires expertise"],
    ]
    story.append(make_table(perf_data[0], perf_data[1:], [3*cm, 3.5*cm, 4*cm, 6.5*cm]))
    story.append(PageBreak())

    # ══════════════════════════════════════════════════════════════════════════
    # SECTION 9 — Summary Reference Table
    # ══════════════════════════════════════════════════════════════════════════
    story.append(section_header("9", "Master Summary Reference Table"))
    story.append(sp(10))

    summary_data = [
        [Paragraph("<b>Method</b>", S["body"]), Paragraph("<b>What It Measures</b>", S["body"]),
         Paragraph("<b>Acute / Chronic</b>", S["body"]), Paragraph("<b>Primary Use</b>", S["body"])],
        ["Kick counts", "Gross fetal movement", "Acute", "Daily, all at-risk patients"],
        ["NST", "FHR reactivity (CNS-CVS coupling)", "Acute", "Weekly/twice-weekly first-line screening"],
        ["CST / OCT", "Uteroplacental reserve", "Acute", "Adjunct when NST non-reactive; less used now"],
        ["Full BPP", "5 biophysical variables", "Acute + Chronic", "Non-reactive NST; FGR; abnormal modified BPP"],
        ["Modified BPP", "NST + AFI", "Acute + Chronic", "First-line outpatient surveillance; most practical"],
        ["UA Doppler", "Placental vascular resistance", "Intermediate", "FGR, hypertension, collagen vascular disease"],
        ["MCA PSV", "Fetal haematocrit/anaemia risk", "Acute", "Isoimmunisation, hydrops, suspected anaemia"],
        ["MCA PI / CPR", "Brain sparing / redistribution", "Intermediate", "FGR with placental insufficiency"],
        ["DV Doppler", "Venous/cardiac function", "Late/severe", "Late-stage FGR; timing delivery decision"],
        ["Uterine artery Doppler", "Maternal spiral artery remodelling", "Chronic/predictive", "20–24 week screening for placental complications"],
        ["AFI / SDP", "Amniotic fluid (cumulative renal perfusion)", "Chronic", "Part of BPP; oligohydramnios workup"],
    ]
    story.append(make_table(summary_data[0], summary_data[1:], [4*cm, 5*cm, 3.5*cm, 4.5*cm]))
    story.append(sp(12))

    # Sources
    story.append(hr())
    story.append(Paragraph("<b>Sources and References</b>", S["h3"]))
    story += [
        Paragraph("1. Creasy & Resnik's Maternal-Fetal Medicine: Principles and Practice, 9th edition — Chapter 32 (Antepartum Fetal Assessment), Chapter 35 (Haemolytic Disease)", S["source"]),
        Paragraph("2. Pfenninger and Fowler's Procedures for Primary Care, 3rd edition — Chapter 172 (Fetal Assessment: Biophysical Profile)", S["source"]),
        Paragraph("3. Alfirevic Z, Stampalija T, Dowsell T. Fetal and umbilical Doppler ultrasound in high-risk pregnancies. Cochrane Database Syst Rev. 2017;6(6):CD007529. PMID: 28613398", S["source"]),
        Paragraph("4. Melamed N, Baschat A, Yinon Y, et al. FIGO initiative on fetal growth: best practice advice for screening, diagnosis, and management of fetal growth restriction. Int J Gynaecol Obstet. 2021;152(Suppl 1):3–57. PMID: 33740264", S["source"]),
        Paragraph("5. Manning FA, Platt LD. Antepartum fetal evaluation: Development of a fetal biophysical profile. Am J Obstet Gynecol. 1980;136:787–795.", S["source"]),
    ]

    # ── Build ──────────────────────────────────────────────────────────────────
    print("Building PDF...")
    doc.build(
        story,
        onFirstPage=on_first_page,
        onLaterPages=on_later_pages,
    )
    print(f"Done → {OUTPUT}")

if __name__ == "__main__":
    build()
Running Command

cd /tmp/workspace/antepartum-fetal-monitoring && python build_pdf.py 2>&1

Editing File

~/antepartum-fetal-monitoring/build_pdf.py

Successfully replaced 1 instance(s) of the string in '/tmp/workspace/antepartum-fetal-monitoring/build_pdf.py'
Running Command

cd /tmp/workspace/antepartum-fetal-monitoring && python build_pdf.py 2>&1

Running Command

ls -lh /tmp/workspace/antepartum-fetal-monitoring/Antepartum_Fetal_Monitoring.pdf

Your PDF is ready — 2.9 MB, fully formatted:

Antepartum Fetal Monitoring

PDF Document · PDF

What's inside (9 sections across ~14 pages):
SectionContent
Cover pageNavy/teal gradient with title, subtitle, source credits
1. Physiological BasisCNS hierarchy table, ideal monitoring criteria, FHR development
2. Surveillance MethodsKick counts, NST (with VAS), CST/OCT interpretation table, Full BPP variable table + management table, Modified BPP
3. Doppler VelocimetryUA Doppler severity spectrum, MCA PSV/CPR/brain sparing, DV waveform, Uterine artery
4. Amniotic FluidAFI vs SDP, oligohydramnios causes
5. IndicationsMaternal and obstetric/fetal conditions table
6. AlgorithmsStepwise decision algorithm table, testing frequency table
7. Special SituationsFGR deterioration sequence, post-dates, isoimmunisation, multiples
8. Test PerformanceFalse-positive/negative rates and limitations per test
9. Master SummaryAll 11 methods in one reference table
Both textbook figures (BPP outcome graph and MCA Doppler PSV serial tracings) are embedded with captions. Running headers on every page show title and page number, with source citations in the footer.
This is a shared conversation. Sign in to Orris to start your own chat.