~/psm-notes/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.lib import colors
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
OUTPUT = "/home/daytona/workspace/psm-notes/Parks_PSM_Ch5_Notes.pdf"
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=2*cm,
leftMargin=2*cm,
topMargin=2.2*cm,
bottomMargin=2.2*cm,
)
W = A4[0] - 4*cm # usable width
styles = getSampleStyleSheet()
# ── Custom styles ──────────────────────────────────────────────────────────────
NAVY = colors.HexColor("#1a3a5c")
TEAL = colors.HexColor("#0d7377")
GOLD = colors.HexColor("#f5a623")
LGRAY = colors.HexColor("#f4f6f9")
DGRAY = colors.HexColor("#555555")
RED = colors.HexColor("#c0392b")
GREEN = colors.HexColor("#27ae60")
title_style = ParagraphStyle(
"DocTitle", parent=styles["Title"],
fontSize=20, textColor=NAVY, spaceAfter=4,
fontName="Helvetica-Bold", alignment=TA_CENTER,
)
subtitle_style = ParagraphStyle(
"DocSubtitle", parent=styles["Normal"],
fontSize=11, textColor=TEAL, spaceAfter=2,
fontName="Helvetica-Oblique", alignment=TA_CENTER,
)
chapter_style = ParagraphStyle(
"ChapterHead", parent=styles["Heading1"],
fontSize=15, textColor=colors.white, spaceBefore=14, spaceAfter=6,
fontName="Helvetica-Bold", backColor=NAVY,
leftIndent=-0.5*cm, rightIndent=-0.5*cm,
borderPad=6,
)
topic_style = ParagraphStyle(
"TopicHead", parent=styles["Heading2"],
fontSize=13, textColor=colors.white, spaceBefore=10, spaceAfter=4,
fontName="Helvetica-Bold", backColor=TEAL,
leftIndent=-0.3*cm, rightIndent=-0.3*cm,
borderPad=5,
)
h3_style = ParagraphStyle(
"H3", parent=styles["Heading3"],
fontSize=11, textColor=NAVY, spaceBefore=8, spaceAfter=3,
fontName="Helvetica-Bold",
)
h4_style = ParagraphStyle(
"H4", parent=styles["Heading4"],
fontSize=10, textColor=TEAL, spaceBefore=5, spaceAfter=2,
fontName="Helvetica-Bold",
)
body_style = ParagraphStyle(
"Body", parent=styles["Normal"],
fontSize=9.5, leading=14, spaceAfter=4,
fontName="Helvetica", alignment=TA_JUSTIFY,
)
bullet_style = ParagraphStyle(
"Bullet", parent=styles["Normal"],
fontSize=9.5, leading=13, spaceAfter=2,
fontName="Helvetica", leftIndent=16, bulletIndent=4,
bulletFontName="Helvetica", bulletFontSize=9.5,
)
subbullet_style = ParagraphStyle(
"SubBullet", parent=styles["Normal"],
fontSize=9, leading=12, spaceAfter=1,
fontName="Helvetica", leftIndent=30, bulletIndent=18,
)
defn_style = ParagraphStyle(
"Defn", parent=styles["Normal"],
fontSize=9.5, leading=14, spaceAfter=4,
fontName="Helvetica-BoldOblique",
textColor=NAVY, leftIndent=10, rightIndent=10,
borderPad=4,
)
note_style = ParagraphStyle(
"Note", parent=styles["Normal"],
fontSize=9, leading=13, spaceAfter=4,
fontName="Helvetica-Oblique", textColor=DGRAY,
leftIndent=10, rightIndent=10,
borderColor=GOLD, borderPad=4, borderWidth=0,
backColor=colors.HexColor("#fffbf0"),
)
formula_style = ParagraphStyle(
"Formula", parent=styles["Normal"],
fontSize=9.5, leading=14, spaceAfter=4,
fontName="Courier-Bold", textColor=NAVY,
alignment=TA_CENTER, spaceBefore=4,
)
# ── Helpers ───────────────────────────────────────────────────────────────────
def H(text, style=h3_style):
return Paragraph(text, style)
def P(text):
return Paragraph(text, body_style)
def B(text, sub=False):
s = subbullet_style if sub else bullet_style
return Paragraph(f"• {text}", s)
def Defn(text):
return Paragraph(f'<i>"{text}"</i>', defn_style)
def Note(text):
return Paragraph(f"<b>Note:</b> {text}", note_style)
def Spacer1(h=0.15):
return Spacer(1, h*cm)
def HR():
return HRFlowable(width="100%", thickness=0.5, color=TEAL, spaceAfter=4)
def topic_header(num, title):
return Paragraph(f" TOPIC {num}: {title}", topic_style)
def make_table(data, col_widths=None, header=True):
if col_widths is None:
n = len(data[0])
col_widths = [W / n] * n
t = Table(data, colWidths=col_widths, repeatRows=1 if header else 0)
ts = [
("BACKGROUND", (0, 0), (-1, 0), NAVY),
("TEXTCOLOR", (0, 0), (-1, 0), colors.white),
("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
("FONTSIZE", (0, 0), (-1, 0), 9),
("ALIGN", (0, 0), (-1, -1), "LEFT"),
("VALIGN", (0, 0), (-1, -1), "TOP"),
("FONTNAME", (0, 1), (-1, -1), "Helvetica"),
("FONTSIZE", (0, 1), (-1, -1), 8.5),
("ROWBACKGROUNDS", (0, 1), (-1, -1), [colors.white, LGRAY]),
("GRID", (0, 0), (-1, -1), 0.4, colors.HexColor("#c8d0da")),
("LEFTPADDING", (0, 0), (-1, -1), 5),
("RIGHTPADDING", (0, 0), (-1, -1), 5),
("TOPPADDING", (0, 0), (-1, -1), 4),
("BOTTOMPADDING",(0, 0), (-1, -1), 4),
]
t.setStyle(TableStyle(ts))
return t
def cell(text, bold=False):
f = "Helvetica-Bold" if bold else "Helvetica"
return Paragraph(text, ParagraphStyle("tc", fontName=f, fontSize=8.5, leading=12))
# ═══════════════════════════════════════════════════════════════════════════════
# BUILD CONTENT
# ═══════════════════════════════════════════════════════════════════════════════
story = []
# ── Title page block ──────────────────────────────────────────────────────────
story += [
Spacer(1, 1*cm),
Paragraph("Chapter 5 – Infectious Disease Epidemiology", title_style),
Paragraph("Detailed Notes based on Park's Textbook of Preventive & Social Medicine", subtitle_style),
Spacer1(0.3),
HRFlowable(width="80%", thickness=2, color=GOLD, spaceAfter=2),
Spacer1(0.4),
]
# ═══════════════════════════════════════════════════════════════════════════════
# TOPIC 1 – CARRIERS
# ═══════════════════════════════════════════════════════════════════════════════
story += [
topic_header(1, "CARRIERS"),
Spacer1(),
H("Definition"),
Defn("An infected person or animal that harbours a specific infectious agent in the absence of discernible clinical disease and serves as a potential source of infection for others."),
Spacer1(),
H("Why Carriers are More Dangerous than Cases"),
B("Carriers are generally <b>less infectious</b> than cases"),
B("But <b>epidemiologically MORE dangerous</b> because:"),
B("They escape recognition", sub=True),
B("Continue normal life in the community", sub=True),
B("Infect susceptibles over a wider area and longer period", sub=True),
B("Classic example: <b>\"Typhoid Mary\"</b>"),
Spacer1(),
H("Elements of Carrier State"),
B("Presence of the disease agent in the body"),
B("Absence of recognizable symptoms and signs"),
B("Shedding of disease agent in discharges/excretions"),
Spacer1(),
H("Classification of Carriers"),
H("A. By Type", h4_style),
make_table([
[cell("Type", True), cell("Description", True), cell("Examples", True)],
[cell("Incubatory"), cell("Shed agent during incubation period — infect others BEFORE onset of illness"), cell("Measles, mumps, polio, pertussis, influenza, diphtheria, Hepatitis B")],
[cell("Convalescent"), cell("Continue to shed disease agent after clinical recovery"), cell("Typhoid, cholera, dysentery")],
[cell("Healthy"), cell("Never develop manifest illness despite harbouring the agent"), cell("Meningococcal meningitis, diphtheria, polio")],
], col_widths=[3.2*cm, 8*cm, 5.8*cm]),
Spacer1(),
H("B. By Duration", h4_style),
B("<b>Temporary/Transient:</b> Carry organism for a short time only"),
B("<b>Chronic:</b> Carry organism for months or years (>3 months = chronic)"),
Spacer1(),
H("C. By Portal of Exit", h4_style),
B("Urinary carriers — <i>e.g., typhoid: urinary carrier MORE dangerous than intestinal</i>"),
B("Intestinal carriers"),
B("Respiratory/Nasal carriers"),
Spacer1(),
Note("Pseudo-carriers = carriers of avirulent organisms; NOT important epidemiologically."),
Spacer1(0.3),
HR(),
]
# ═══════════════════════════════════════════════════════════════════════════════
# TOPIC 2 – MODES OF TRANSMISSION
# ═══════════════════════════════════════════════════════════════════════════════
story += [
topic_header(2, "MODES OF TRANSMISSION"),
Spacer1(),
P("Communicable diseases may be transmitted from the reservoir to a susceptible individual in many ways, depending on the infectious agent, portal of entry and local ecological conditions. Most diseases are transmitted by <b>one route</b>; some by multiple routes (AIDS, salmonellosis, hepatitis B, brucellosis, Q fever, tularemia) — multiple routes enhance survival of the agent."),
Spacer1(),
H("A. DIRECT TRANSMISSION"),
make_table([
[cell("Route", True), cell("Description", True), cell("Examples", True)],
[cell("1. Direct contact"), cell("Skin-to-skin, mucosa-to-mucosa; touching, kissing, sexual intercourse"), cell("STDs, AIDS, leprosy, leptospirosis")],
[cell("2. Droplet infection"), cell("Spray of droplets from coughing/sneezing (range 30–60 cm). Particles <5 µm reach alveoli"), cell("Measles, diphtheria, whooping cough, TB, COVID-19, meningococcal meningitis")],
[cell("3. Contact with soil"), cell("Exposure of susceptible tissue to disease agent in soil/decaying matter"), cell("Hookworm, tetanus, mycosis")],
[cell("4. Inoculation"), cell("Direct inoculation into skin or mucosa"), cell("Rabies (dog bite), Hepatitis B (contaminated needle)")],
[cell("5. Transplacental (Vertical)"), cell("Disease agents transmitted across placenta"), cell("TORCH (Toxoplasma, Rubella, CMV, Herpes), syphilis, Hepatitis B, varicella, AIDS")],
], col_widths=[3.5*cm, 8*cm, 5.5*cm]),
Spacer1(),
H("B. INDIRECT TRANSMISSION"),
make_table([
[cell("Route", True), cell("Description", True), cell("Examples", True)],
[cell("1. Vehicle-borne"), cell("Contaminated inanimate materials: water, food, milk, blood/serum products"), cell("Cholera (water), typhoid (food), hepatitis B (blood)")],
[cell("2. Vector-borne\n(Mechanical)"), cell("Arthropod mechanically transports agent via feet/proboscis/GIT. No development of agent in vector"), cell("Housefly + cholera, dysentery")],
[cell("2. Vector-borne\n(Biological)"), cell("Agent replicates/develops in vector; requires extrinsic incubation period (See Topic 3)"), cell("Malaria, dengue, plague")],
[cell("3. Airborne –\nDroplet nuclei"), cell("Tiny dried residue of droplets (1–10 µm); remain airborne for long periods; can reach alveoli"), cell("TB, influenza, chickenpox, measles, Q fever, COVID-19")],
[cell("3. Airborne – Dust"), cell("Settled droplets on floors/furniture become part of dust; some agents survive long periods"), cell("TB bacilli, streptococci, fungal spores")],
[cell("4. Fomite-borne"), cell("Inanimate objects (clothes, towels, cups, bedding)"), cell("Skin/eye infections")],
[cell("5. Unclean hands\n& fingers"), cell("Hand-to-mouth transmission; favoured by poor personal hygiene and poor sanitation"), cell("Typhoid, hepatitis A, dysentery, intestinal parasites")],
], col_widths=[3.5*cm, 8*cm, 5.5*cm]),
Spacer1(0.3),
HR(),
]
# ═══════════════════════════════════════════════════════════════════════════════
# TOPIC 3 – BIOLOGICAL TRANSMISSION
# ═══════════════════════════════════════════════════════════════════════════════
story += [
topic_header(3, "BIOLOGICAL TRANSMISSION"),
Spacer1(),
P("Biological transmission is a sub-type of vector-borne indirect transmission where the infectious agent undergoes <b>replication or development (or both)</b> in the vector. It requires an <b>extrinsic incubation period</b> before the vector can transmit."),
Spacer1(),
H("Three Types of Biological Transmission"),
make_table([
[cell("Type", True), cell("What Happens in Vector", True), cell("Example", True)],
[cell("Propagative"), cell("Agent MULTIPLIES only — no change in form"), cell("Plague bacilli in rat fleas")],
[cell("Cyclo-propagative"), cell("Agent CHANGES IN FORM AND NUMBER"), cell("Malaria parasites in mosquito")],
[cell("Cyclo-developmental"), cell("Agent undergoes DEVELOPMENT ONLY — no multiplication"), cell("Microfilaria in mosquito")],
], col_widths=[4*cm, 8.5*cm, 4.5*cm]),
Spacer1(),
H("Special Transmission Types in Vectors"),
B("<b>Transovarial:</b> Agent transmitted vertically from infected female vector to her progeny"),
B("<b>Transstadial:</b> Transmission from one stage of life cycle to another (e.g., nymph → adult)"),
Spacer1(),
H("Factors Influencing Vector Ability to Transmit Disease"),
B("Host feeding preferences"),
B("Infectivity — ability to transmit the disease agent"),
B("Susceptibility — ability to become infected"),
B("Survival rate of vectors in the environment"),
B("Domesticity — degree of association with man"),
B("Suitable environmental factors (temperature, humidity)"),
Spacer1(0.3),
HR(),
]
# ═══════════════════════════════════════════════════════════════════════════════
# TOPIC 4 – INCUBATION PERIOD
# ═══════════════════════════════════════════════════════════════════════════════
story += [
topic_header(4, "INCUBATION PERIOD"),
Spacer1(),
H("Definition"),
Defn("The time interval between invasion by an infectious agent and appearance of the first sign or symptom of the disease in question."),
Spacer1(),
P("During incubation period: agent undergoes multiplication until a sufficient density disturbs the health equilibrium. <b>Median incubation period</b> = time for 50% of cases to occur following exposure."),
Note("As a rule, diseases are NOT communicable during incubation period. EXCEPTIONS: Measles, chickenpox, whooping cough, Hepatitis A (communicable in LATER part of incubation period)."),
Spacer1(),
H("Factors Determining Incubation Period"),
B("Generation time of the pathogen"),
B("Infective dose"),
B("Portal of entry"),
B("Individual susceptibility"),
Spacer1(),
H("Length of Incubation Period — Classification"),
make_table([
[cell("Category", True), cell("Duration", True), cell("Examples", True)],
[cell("Short"), cell("Few hours to 2–3 days"), cell("Staphylococcal food poisoning, cholera, bacillary dysentery")],
[cell("Medium"), cell("10 days to 3 weeks"), cell("Typhoid, chickenpox, measles, mumps, COVID-19")],
[cell("Long"), cell("Weeks to months/years"), cell("Hepatitis A & B, rabies, leprosy, slow virus diseases")],
], col_widths=[3*cm, 5.5*cm, 8.5*cm]),
Spacer1(),
H("Importance of Incubation Period"),
B("<b>(a) Tracing source of infection:</b> Short incubation = easy to trace. Long incubation = cause-effect relationship becomes 'diluted'"),
B("<b>(b) Surveillance/Quarantine period:</b> Quarantine duration = maximum incubation period of disease"),
B("<b>(c) Immunization:</b> Helps prevent clinical illness using human immunoglobulins and antisera"),
B("<b>(d) Identify epidemic type:</b> Point source = all cases within ONE incubation period; Propagated = cases occur BEYOND known incubation period"),
B("<b>(e) Prognosis:</b> In tetanus and rabies, shorter incubation period → WORSE prognosis"),
Note("Latent period = equivalent of incubation period in non-infectious/chronic diseases. Defined as 'period from disease initiation to disease detection'."),
Spacer1(0.3),
HR(),
]
# ═══════════════════════════════════════════════════════════════════════════════
# TOPIC 5 – GENERATION TIME
# ═══════════════════════════════════════════════════════════════════════════════
story += [
topic_header(5, "GENERATION TIME"),
Spacer1(),
H("Serial Interval (Related Concept)"),
P("The <b>serial interval</b> = gap in time between the onset of the primary case and the onset of the secondary case in a family/closed group. Used to estimate the incubation period when exact timing is unknown."),
Spacer1(),
H("Definition of Generation Time"),
Defn("The interval of time between receipt of infection by a host and maximal infectivity of that host."),
Spacer1(),
H("Generation Time vs. Incubation Period"),
make_table([
[cell("Feature", True), cell("Incubation Period", True), cell("Generation Time", True)],
[cell("Definition"), cell("Time from invasion to first symptoms"), cell("Time from receipt of infection to maximal infectivity")],
[cell("Scope"), cell("Only manifest (clinical) disease"), cell("Clinical AND subclinical infections")],
[cell("Relationship"), cell("Roughly equal to generation time but may precede or follow it"), cell("Roughly equal to incubation period")],
[cell("Interval between cases"), cell("Not directly used"), cell("Determined by generation time")],
], col_widths=[3.5*cm, 7*cm, 6.5*cm]),
Spacer1(),
Note("In mumps, communicability reaches its height about 48 hours BEFORE onset of salivary gland swelling — maximum communicability precedes the incubation period."),
Spacer1(0.3),
HR(),
]
# ═══════════════════════════════════════════════════════════════════════════════
# TOPIC 6 – SECONDARY ATTACK RATE
# ═══════════════════════════════════════════════════════════════════════════════
story += [
topic_header(6, "SECONDARY ATTACK RATE (SAR)"),
Spacer1(),
H("Definition"),
Defn("The number of exposed persons developing the disease within the range of the incubation period, following exposure to the primary case."),
Spacer1(),
H("Formula"),
Paragraph(
"SAR = (No. of exposed persons developing disease within incubation period) / "
"(Total no. of exposed / susceptible contacts) × 100",
formula_style
),
Spacer1(),
B("Primary case is <b>EXCLUDED</b> from both numerator and denominator"),
B("Denominator may be restricted to 'susceptible' contacts only, if distinguishable from immune"),
Spacer1(),
H("Example"),
P("Family of 6: 2 parents (immune) + 4 children (susceptible). Primary case occurs. 2 secondary cases develop. SAR = 2/3 = <b>66.6%</b>"),
Spacer1(),
H("For Long Communicable Period (e.g., TB)"),
Paragraph(
"SAR = (No. of contacts developing TB) / (No. of person-weeks/months/years of exposure) × 100",
formula_style
),
Spacer1(),
H("Limitations"),
B("Limited to diseases where primary case is infective for only a SHORT time (measles, chickenpox)"),
B("NOT suitable when primary case is infective over long period (TB)"),
B("Difficult to identify 'susceptibles' in many diseases (e.g., influenza)"),
Spacer1(),
H("Uses of SAR"),
B("Measures spread of infection within a family/household/closed group"),
B("Determines if a disease of unknown aetiology (e.g., Hodgkin's disease) is communicable"),
B("Evaluates effectiveness of control measures (isolation, immunization)"),
B("Can be pooled across families to compare attack rates in vaccinees vs. non-vaccinees"),
Spacer1(0.3),
HR(),
]
# ═══════════════════════════════════════════════════════════════════════════════
# TOPIC 7 – HERD IMMUNITY
# ═══════════════════════════════════════════════════════════════════════════════
story += [
topic_header(7, "HERD IMMUNITY"),
Spacer1(),
H("Definition"),
Defn("A type of immunity that occurs when the vaccination of a portion of the population (or herd) provides protection to unprotected individuals. Also called COMMUNITY IMMUNITY."),
Spacer1(),
P("When large numbers of a population are immune, it is difficult to maintain a chain of infection. Higher the number of immune individuals → lower likelihood that a susceptible person comes in contact with an infectious agent."),
Spacer1(),
H("Classic Example"),
P("Measles epidemic in <b>Faroe Islands, 1854</b> — 'virgin' population with no prior immunity. Very high attack and case fatality rates. Epidemic declined as herd immunity built up following natural infection."),
Spacer1(),
H("Elements Contributing to Herd Immunity"),
B("(a) Occurrence of clinical and subclinical infections in the herd"),
B("(b) Immunization of the herd"),
B("(c) Herd structure (hosts, alternative animal hosts, insect vectors, environment)"),
Note("Herd structure is NEVER constant — varies due to new births, deaths and population mobility."),
Spacer1(),
H("Herd Immunity Threshold"),
P("The proportion of immune individuals above which a disease may no longer persist. Varies with:"),
B("Virulence of the disease"),
B("Efficacy of the vaccine"),
B("Contact parameter for the population"),
Spacer1(),
H("Implications"),
B("Sufficiently high herd immunity → epidemic is highly unlikely"),
B("Maintained high immunity → susceptibles reduced to small proportion → possible elimination (diphtheria, poliomyelitis)"),
B("Smallpox eradication = not herd immunity alone, but also surveillance and containment (elimination of source)"),
Note("In TETANUS — herd immunity does NOT protect the individual (not person-to-person spread)."),
B("It is neither possible nor necessary to achieve 100% herd immunity"),
B("Determined by <b>serological surveys</b> (serological epidemiology)"),
Spacer1(0.3),
HR(),
]
# ═══════════════════════════════════════════════════════════════════════════════
# TOPIC 8 – COLD CHAIN + VVM
# ═══════════════════════════════════════════════════════════════════════════════
story += [
topic_header(8, "COLD CHAIN + VACCINE VIAL MONITOR (VVM)"),
Spacer1(),
H("The Cold Chain — Definition"),
Defn("A system of storage and transport of vaccines at low temperature from the manufacturer to the actual vaccination site."),
Spacer1(),
H("The 6 Rights of Supply Chain"),
Paragraph(
"Right Vaccine | Right Quantity | Right Place | Right Time | Right Condition | Right Cost",
ParagraphStyle("rights", fontName="Helvetica-Bold", fontSize=9.5, leading=14,
alignment=TA_CENTER, textColor=NAVY, spaceAfter=6)
),
Spacer1(),
H("Temperature Requirements"),
B("Recommended storage for most vaccines: <b>+2°C to +8°C</b>"),
B("OPV stored at <b>−15°C to −25°C</b> (deep freezer)"),
B("Once vaccine potency is lost, it <b>CANNOT be regained</b>"),
Spacer1(),
H("Vaccines Sensitive to FREEZING (must NOT be frozen)"),
P("Cholera, DTaP-HepB-Hib-IPV (hexavalent), DTwP/pentavalent, Hepatitis B, Hib (liquid), HPV, IPV, liquid meningococcal, PCV, liquid Rotavirus, TT/Td, Yellow fever"),
Spacer1(),
H("Cold Chain Equipment"),
make_table([
[cell("Equipment", True), cell("Temperature", True), cell("Level", True), cell("Key Points", True)],
[cell("Deep Freezer (DF)"), cell("−15°C to −25°C"), cell("District & above"), cell("For OPV storage and making ice packs. Limited hold-over time")],
[cell("Ice Lined Refrigerator (ILR)"), cell("+2°C to +8°C"), cell("District & sub-district"), cell("MOST IMPORTANT link. Top-opening. Safe with min. 8 hr electricity/day. Ice lining maintains temp during power failure")],
[cell("Vaccine Carrier"), cell("+2°C to +8°C"), cell("Session site"), cell("Carries vaccines from cold chain point to session. Conditioned ice packs used")],
[cell("Cold Box"), cell("+2°C to +8°C"), cell("Transport"), cell("Insulated box for bulk transport")],
], col_widths=[3.5*cm, 3*cm, 3*cm, 7.5*cm]),
Spacer1(),
H("ILR — Key Details"),
B("Lower part of ILR is cooler → <b>upper basket</b> preferred for freeze-sensitive vaccines (DPT, TT, Hep B, IPV, pentavalent)"),
B("Lower basket: OPV, BCG, measles, JE (at sub-district level)"),
B("NEVER keep vaccines directly on ILR floor — risk of freezing"),
Spacer1(),
H("Hold-Over Time"),
P("Time taken for equipment to raise inside cabinet temperature from its temperature at the time of power failure to +10°C. ILR has longer hold-over time than DF."),
Spacer1(),
H("Shake Test — Detecting Freeze-Damaged Vaccines"),
B("Take 'Test vial' (suspect) + 'Control vial' (same antigen, manufacturer, batch)"),
B("Freeze control vial at −20°C overnight; let it thaw — do NOT heat"),
B("Shake both vigorously for 10–15 seconds"),
B("Place both on flat surface; observe for 30 minutes"),
B("If sedimentation in test vial is <b>SLOWER</b> than control → NOT damaged (safe to use)"),
B("If <b>SAME or FASTER</b> sedimentation → vaccine is damaged → DISCARD"),
Spacer1(),
H("Open Vial Policy"),
make_table([
[cell("Applies to", True), cell("Duration", True)],
[cell("DPT, TT, Hep B, OPV, Liquid Pentavalent, PCV, IPV"), cell("Up to 4 WEEKS (if conditions met)")],
[cell("BCG, Measles/MR, JE, Rotavirus"), cell("NOT applicable — discard after 48 hours or before next session (whichever earlier)")],
], col_widths=[10*cm, 7*cm]),
Spacer1(),
P("Conditions to reuse an open vial: (1) Expiry date not passed (2) Proper temperature maintained (3) Vial septum not submerged/contaminated (4) Aseptic technique used (5) VVM has not reached discard point (6) Not exposed to direct sunlight"),
Note("If any AEFI is reported — ALL open vials must be preserved under proper cold chain until investigation is complete."),
Spacer1(),
H("VACCINE VIAL MONITOR (VVM)"),
Defn("A chemical indicator label attached to the vaccine container by the manufacturer that records cumulative heat exposure through gradual colour change."),
Spacer1(),
H("Reading the VVM", h4_style),
B("<b>Inner square SAME or DARKER than outer circle</b> → Too much heat exposure → <b>DISCARD</b>"),
B("Inner square LIGHTER than outer circle → Vaccine is safe to use"),
Spacer1(),
H("Four Types of VVM", h4_style),
make_table([
[cell("Type", True), cell("Meaning", True)],
[cell("VVM2"), cell("Inner square reaches discard point in 2 days at constant 37°C")],
[cell("VVM7"), cell("7 days at constant 37°C")],
[cell("VVM14"), cell("14 days at constant 37°C")],
[cell("VVM30"), cell("30 days at constant 37°C")],
], col_widths=[3*cm, 14*cm]),
Spacer1(),
H("Purposes of VVM", h4_style),
B("Ensure heat-damaged vaccines are not administered"),
B("Decide which vaccines can be safely kept after a cold chain break (minimize wastage)"),
B("Decide priority of use: significant heat exposure → use FIRST, even if longer expiry date"),
Note("VVMs do NOT measure exposure to FREEZING temperature."),
Spacer1(),
H("VVM Location and Open Vial Rules", h4_style),
make_table([
[cell("VVM Location", True), cell("Open Vial Rule", True)],
[cell("On the vaccine label"), cell("Can be kept for up to 28 days in subsequent sessions")],
[cell("NOT on the label (cap/neck of ampoule)"), cell("Must be discarded at end of session or within 6 hours of opening — whichever comes first")],
], col_widths=[7*cm, 10*cm]),
Spacer1(0.3),
HR(),
]
# ═══════════════════════════════════════════════════════════════════════════════
# TOPIC 9 – AEFI
# ═══════════════════════════════════════════════════════════════════════════════
story += [
topic_header(9, "ADVERSE EFFECTS FOLLOWING IMMUNIZATION (AEFI)"),
Spacer1(),
H("Types of Vaccine Reactions"),
B("<b>Local reactions</b> — at the injection site: pain, swelling, redness"),
B("<b>Systemic reactions</b> — fever, irritability, malaise, 'off-colour', loss of appetite"),
B("<b>Severe/rare reactions</b> — anaphylaxis, seizures, vaccine-associated paralytic polio (VAPP)"),
Spacer1(),
H("Common Minor Vaccine Reactions by Vaccine"),
make_table([
[cell("Vaccine", True), cell("Common Minor Adverse Reaction", True), cell("Expected Frequency", True)],
[cell("BCG"), cell("Local reaction (pain, swelling, redness)"), cell("Common")],
[cell("DTP"), cell("Local reaction + Fever"), cell("Up to 50% each")],
[cell("Hepatitis A"), cell("Local reaction"), cell("Up to 50%")],
[cell("Hepatitis B"), cell("Local reaction; Fever"), cell("Adults up to 30%, Children up to 5%; Fever 1–6%")],
[cell("Hib"), cell("Local reaction; Fever"), cell("5–15%; 2–10%")],
[cell("Japanese Encephalitis"), cell("Local reaction, low-grade fever, myalgia, GI upset"), cell("Up to 20%")],
[cell("Measles/MMR"), cell("Fever, rash, conjunctivitis (from vaccine virus)"), cell("5–15% (very mild vs. wild measles)")],
[cell("Mumps (MMR)"), cell("Swollen parotid gland"), cell("<1% of children")],
[cell("Rubella (MMR)"), cell("Joint pains, swollen lymph nodes"), cell("<1% children; 15% adults (joint pain)")],
[cell("OPV"), cell("Diarrhoea, headache, muscle pain"), cell("<1%")],
[cell("IPV"), cell("None"), cell("—")],
[cell("Tetanus/Td"), cell("Local reaction; Malaise"), cell("Up to 10%; Up to 25%")],
[cell("Meningococcal"), cell("Mild local reactions"), cell("Up to 71%")],
[cell("Pneumococcal"), cell("Local reaction"), cell("30–50%")],
[cell("Rabies"), cell("Local and/or general reaction (depends on vaccine type)"), cell("15–25%")],
[cell("Cholera (oral)"), cell("None"), cell("—")],
], col_widths=[3.5*cm, 8.5*cm, 5*cm]),
Spacer1(),
H("Key Points on AEFI"),
B("For <b>measles/MMR and OPV</b>: systemic reactions arise from vaccine virus infection itself"),
B("Measles vaccine can be <b>severe/fatal in severely immunocompromised individuals</b>"),
B("Rubella causes symptoms more frequently in <b>adults than children</b>"),
B("All severe AEFI require investigation — open vials must be preserved under cold chain"),
Spacer1(0.3),
HR(),
]
# ═══════════════════════════════════════════════════════════════════════════════
# TOPIC 10 – PREVENTION AND CONTROL
# ═══════════════════════════════════════════════════════════════════════════════
story += [
topic_header(10, "PREVENTION AND CONTROL OF COMMUNICABLE DISEASES"),
Spacer1(),
P("Prevention and control are achieved by acting on one or more components of the epidemiological triad: <b>Agent – Host – Environment</b>."),
Spacer1(),
H("I. Acting on the SOURCE OF INFECTION"),
B("<b>Early diagnosis and treatment:</b> Reduces communicability, complications and mortality"),
B("<b>Notification:</b> Mandatory reporting of notifiable diseases to health authorities; enables rapid public health response"),
B("<b>Isolation:</b> Separation of infected individual from susceptible persons; duration = communicable period"),
B("<b>Quarantine:</b> Restriction of movement of exposed contacts; duration = maximum incubation period"),
B("<b>Disinfection:</b> Concurrent (immediate) and Terminal (after source ceases to be infectious)"),
B("<b>Epidemiological investigation:</b> Identifying source, mode of transmission, contacts"),
Spacer1(),
H("II. Acting on the MODE OF TRANSMISSION (Environmental Measures)"),
B("<b>Safe water supply:</b> Chlorination, filtration, purification"),
B("<b>Sanitary disposal of excreta:</b> Prevents fecal-oral transmission"),
B("<b>Food sanitation:</b> Safe food handling, pasteurization of milk, meat inspection"),
B("<b>Vector control:</b> Insecticides, larvicides, environmental management, biological control"),
B("<b>Personal hygiene:</b> Hand washing, safe sexual practices"),
Spacer1(),
H("III. Acting on the HOST (Increasing Resistance)"),
H("1. Active Immunization (Vaccination)", h4_style),
B("Stimulates specific protective antibodies and cellular immunity"),
B("<b>Live vaccines</b> (BCG, measles, OPV, mumps, rubella, yellow fever, varicella) — generally MORE potent than killed vaccines"),
B("<b>Killed/inactivated vaccines</b> (DPT, Hepatitis B, IPV, typhoid, cholera, rabies)"),
B("Live vaccines are more potent because: (1) multiply in host → larger antigenic dose; (2) all major and minor antigenic components; (3) engage tissues (e.g., intestinal mucosa - OPV)"),
Note("Live vaccines CONTRAINDICATED in: immune deficiency diseases, leukaemia/lymphoma/malignancy, therapy with corticosteroids/alkylating/antimetabolic agents or radiation, pregnancy (some)."),
Spacer1(),
H("2. Passive Immunization", h4_style),
B("Administration of antibody-containing preparation (immune globulin or antiserum)"),
B("Transfer of maternal antibodies across placenta and in breast milk (IgA)"),
B("<b>Rapidly established</b> but <b>temporary only</b> (days to months)"),
B("No 'education' of reticuloendothelial system"),
B("Useful when: individual cannot form antibodies, or when active immunity takes time to develop"),
Spacer1(),
H("3. Chemoprophylaxis", h4_style),
B("Use of drugs to prevent infection or disease in exposed individuals"),
B("Examples: malaria prophylaxis (chloroquine/doxycycline), post-exposure prophylaxis for rabies, meningococcal meningitis (rifampicin), HIV (ARVs)"),
Spacer1(),
H("Levels of Prevention"),
make_table([
[cell("Level", True), cell("Action", True), cell("Examples", True)],
[cell("Primordial"), cell("Reduce risk factors in population before disease develops"), cell("Sanitation, health education, improving living standards")],
[cell("Primary"), cell("Prevent disease before it occurs"), cell("Vaccination, chemoprophylaxis, vector control, health promotion")],
[cell("Secondary"), cell("Early detection and treatment to halt progression"), cell("Case finding, screening, notification, isolation")],
[cell("Tertiary"), cell("Reduce complications, disabilities and death"), cell("Rehabilitation, specific treatment")],
], col_widths=[3*cm, 7.5*cm, 6.5*cm]),
Spacer1(0.5),
HR(),
Spacer1(),
Paragraph(
"Source: Park's Textbook of Preventive and Social Medicine, Chapter 5 — Infectious Disease Epidemiology",
ParagraphStyle("source", fontName="Helvetica-Oblique", fontSize=9, textColor=DGRAY, alignment=TA_CENTER)
),
]
# ── Build PDF ─────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF saved to: {OUTPUT}")