POLYMERASE CHAIN REACTION PCR was invented by Kary B. Mullis in 1983. PCR The PCR is an in-vitro, enzymatic amplification of a desired sequence of DNA using a pair of oligonucleotide primers. These primers are complementary to one end of the DNA target sequence. These are extended towards each other by a thermostable DNA polymerase in a reaction cycle of three steps; denaturation, primer annealing and polymerization (extension). Components of PCR A. Template PCR can amplify as little as one molecule of starting template. Therefore, any source of DNA that provides one or more target molecules can in principle be used as a template for PCR. This includes DNA prepared from blood, sperm or any other tissue, from older forensic specimens, from ancient biological samples or in the laboratory from bacterial colonies or plaques as well as purified DNA. B. Primers Oligonucleotides used for priming, should be atleast 16 nts and preferably 20-24 nts in length. They should have similar G+C contents so that they anneal to their complementary sequences at similar temperatures. They are designed to anneal on opposite strands of the target sequence so that they will be extended towards each other by addition of nucleotides to their 3’ ends. If the DNA sequence being amplified is known, then primer design is relatively easy. C. dNTPs The 4 dNTPs, dATP, dGTP, dCTP and dTTP, used at saturating concentration (200 m M each). D. Enzymes Thermostable DNA polymerases from a number of thermophilic bacteria are used for PCR. The most common is Taq polymerase from Thermusaquaticus. It survives the denaturation step of 95º C for 1-2 min, having a half-life of more than 2hr at this temperature. It carries a 5’-3’ polymerization dependant exonuclease activity, but lack in 3’-5’ exonuclease activity (proof reading). Hence, it is more prone for introducing errors. There are high-fiedalitythermostable enzymes with 3’-5’ exonuclease activity. e.g., Vent polymerase, pfu polymerase. E. Buffer The standard buffer for PCR contains 50 mM KCl, 10 mM Tris.Cl and 1.5 mM MgCl2. pH is approximately 7.2. The presence of divalent cations is critical (Mg2+). PCR cycle PCR involves a repetitive series of temperature cycles. Each reaction cycle comprises of three stages o Denaturation o Primer annealing and o Extension. In the first cycle, the target DNA is separated into two strands by heating to 95º C- denaturation. The temperature is reduced to around 55º C to allow the primers to anneal. The actual temperature depends on the primer lengths and sequences- primer annealing. After annealing, the temperature is increased to 72º C for optimal polymerization which uses up dNTPs in the reaction mix and requires Mg2+ and new strand of DNA is synthesized. If PCR was 100% efficient, one target molecule would become 2n after ‘n’ cycles. In practice, 20- 40 cycles are commonly used. Types of PCR There are several types of PCR used. The below mentioned are the most commonly used types of PCR. RT-PCR Reverse transcriptase polymerase chain reaction (RT-PCR) is used to convert the RNA template into complementary DNA (cDNA) by using the enzyme reverse transcriptase and then the target is amplified into many copies through PCR steps. RT-PCR is applied to diagnose RNA viruses, mRNA expression etc. Nested PCR Nested PCR is a conventional PCR with a second round of amplification using a different set of primers. This second set of primers is specific to a sequence found within the DNA of the initial conventional PCR amplicon. The use of a second amplification step with the "nested" primer set results in a reduced background from products amplified during the initial PCR due to the nested primers’ additional specificity to the region. The amount of amplicon produced is increased as a result of the second round of amplification. Multiplex PCR Multiplex PCR is the term used when more than one pair of primers is used in a PCR. The goal of multiplex PCR is to amplify several segments of target DNA simultaneously and thereby to conserve template DNA, save time, and minimize expense. It is a PCR strategy that enables the amplification of multiple DNA targets in one run. Real time PCR Real-Time PCR, also called quantitative (real-time) PCR or Real-Time Quantitative PCR (RTQ-PCR), is a method of simultaneous DNA quantification and amplification. Applications Gene cloning. Generating template for sequencing. In-vitro mutagenesis. Analysis of biological materials for forensic applications. To study the evolutionary history in the field of molecular palaeontology. Medical applications such as pre-natal diagnosis of diseases and sexing of embryos. Detection of infectious diseases. Summary into answer for exam
| Component | Key Details |
|---|---|
| Template DNA | As little as one molecule is sufficient; sources include blood, sperm, tissue, forensic/ancient specimens, bacterial colonies |
| Primers | Oligonucleotides; minimum 16 nt, preferably 20-24 nt; similar G+C content; anneal on opposite strands; extended at 3' ends |
| dNTPs | All 4 types (dATP, dGTP, dCTP, dTTP) at 200 µM each (saturating concentration) |
| Enzyme | Taq polymerase (from Thermus aquaticus); thermostable; half-life >2 hr at 95°C; has 5'→3' exonuclease but lacks 3'→5' proofreading - prone to errors. High-fidelity alternatives: Vent, Pfu polymerase (have 3'→5' exonuclease) |
| Buffer | 50 mM KCl, 10 mM Tris-Cl, 1.5 mM MgCl₂, pH ~7.2; Mg²⁺ is critical |
Step 1: DENATURATION → 95°C → Separates double-stranded DNA
Step 2: PRIMER ANNEALING → ~55°C → Primers bind to complementary sequences
Step 3: EXTENSION → 72°C → Taq polymerase synthesizes new strand using dNTPs
| Type | Key Feature | Application |
|---|---|---|
| RT-PCR | RNA → cDNA (via reverse transcriptase) → PCR | Diagnose RNA viruses, mRNA expression |
| Nested PCR | Two rounds of PCR; second set of primers is internal to first amplicon | Increased specificity, reduced background |
| Multiplex PCR | Multiple primer pairs in one reaction | Amplifies several DNA targets simultaneously; saves time, template, and cost |
| Real-Time PCR (RTQ-PCR) | Simultaneous amplification + quantification | Quantitative analysis of DNA/RNA |
Add some other details from standard biotech books and make an essay typed flowchart and tabled form answer
PCR polymerase chain reaction steps components types standard biotechnology textbook details
Definition: PCR is an in-vitro, enzymatic amplification of a desired DNA sequence using a pair of oligonucleotide primers that are complementary to opposite ends of the target sequence, extended toward each other by a thermostable DNA polymerase through repetitive cycles of denaturation, primer annealing, and polymerization (extension).
| Enzyme | Source Organism | Proofreading (3'→5') | Error Rate | Notes |
|---|---|---|---|---|
| Taq polymerase | Thermus aquaticus | Absent | Higher | Most common; half-life >2 hr at 95°C; has 5'→3' exonuclease activity |
| Vent polymerase | Thermococcus litoralis | Present | Lower | High-fidelity; preferred when accuracy is critical |
| Pfu polymerase | Pyrococcus furiosus | Present | Lowest | Highest fidelity thermostable polymerase |
╔═══════════════════════════════════════════════════════════════╗
║ POLYMERASE CHAIN REACTION - PROCESS FLOW ║
╚═══════════════════════════════════════════════════════════════╝
┌────────────────────────────────────┐
│ REACTION SETUP (Pre-PCR) │
│ Mix: Template DNA + Forward & │
│ Reverse Primers + dNTPs + │
│ Taq Polymerase + Mg²⁺ Buffer │
│ Load into Thermocycler │
└──────────────┬─────────────────────┘
│
▼
┌────────────────────────────────────┐
│ INITIAL DENATURATION │
│ 95°C for 2-5 minutes │
│ (Activates hot-start Taq; │
│ fully separates template) │
└──────────────┬─────────────────────┘
│
▼
┌══════════════════════════════════════════════╗
║ CYCLE BEGINS (Repeat 20-40x) ║
╠══════════════════════════════════════════════╣
║ ║
║ STEP 1: DENATURATION ║
║ ┌──────────────────────────────────────┐ ║
║ │ 94-95°C for 30-60 seconds │ ║
║ │ Heat breaks H-bonds between strands │ ║
║ │ dsDNA ──────────────► 2 x ssDNA │ ║
║ └──────────────┬───────────────────────┘ ║
║ │ ║
║ ▼ ║
║ STEP 2: PRIMER ANNEALING ║
║ ┌──────────────────────────────────────┐ ║
║ │ 50-65°C for 30-60 seconds │ ║
║ │ Primers bind complementary sequences │ ║
║ │ Forward primer → 5'→3' on one strand │ ║
║ │ Reverse primer → 5'→3' on other strand│ ║
║ │ Both oriented TOWARD each other │ ║
║ └──────────────┬───────────────────────┘ ║
║ │ ║
║ ▼ ║
║ STEP 3: EXTENSION / POLYMERIZATION ║
║ ┌──────────────────────────────────────┐ ║
║ │ 72°C for 30-120 seconds │ ║
║ │ Taq polymerase adds dNTPs to 3' end │ ║
║ │ of primers (5'→3' synthesis) │ ║
║ │ Rate: ~1000 bp/minute │ ║
║ │ New complementary strands formed │ ║
║ └──────────────┬───────────────────────┘ ║
║ │ ║
║ ← ─ ─ ─ ┘ (Repeat cycle) ║
╚══════════════════════════════════════════════╝
│
│ After n cycles: 2ⁿ copies
│ Practical formula: (1+e)ⁿ
│ where e = efficiency (0-1)
▼
┌────────────────────────────────────┐
│ FINAL EXTENSION │
│ 72°C for 5-10 minutes │
│ Ensures all amplicons fully │
│ extended and complete │
└──────────────┬─────────────────────┘
│
▼
┌────────────────────────────────────┐
│ PRODUCT ANALYSIS / DETECTION │
│ • Agarose gel electrophoresis + │
│ ethidium bromide staining │
│ • Capillary electrophoresis │
│ • Probe hybridization │
│ • Real-time fluorescence │
│ • Mass spectrometry │
└────────────────────────────────────┘
| Cycle | Copies (theoretical) | Notes |
|---|---|---|
| 0 | 1 | Original template |
| 1 | 2 | First doubling |
| 10 | ~1,000 | Thousand-fold |
| 20 | ~1,000,000 | Million-fold |
| 30 | ~1,000,000,000 | Billion-fold |
| n | 2ⁿ | Theoretical maximum |
| Component | Specification | Function | Critical Notes |
|---|---|---|---|
| Template DNA | Any DNA source; as little as 1 molecule | Provides the sequence to be amplified | A260/A280 ratio ~1.8 for purity |
| Forward Primer | 18-30 nt; 0.1-0.5 µM | Anneals to antisense strand; initiates synthesis | Must not form hairpins or primer-dimers |
| Reverse Primer | 18-30 nt; 0.1-0.5 µM | Anneals to sense strand; initiates synthesis in opposite direction | Similar Tm to forward primer |
| dATP | 200 µM | Adenine building block | Equimolar with all dNTPs |
| dGTP | 200 µM | Guanine building block | Equimolar with all dNTPs |
| dCTP | 200 µM | Cytosine building block | Equimolar with all dNTPs |
| dTTP | 200 µM | Thymine building block | Equimolar with all dNTPs |
| Taq Polymerase | 0.05 units/µL | Catalyzes 5'→3' DNA synthesis | Lacks proofreading; error-prone |
| KCl | 50 mM | Stabilizes polymerase | Part of standard buffer |
| Tris-HCl | 10 mM, pH ~7.2 | Maintains pH | Part of standard buffer |
| MgCl₂ | 1.5 mM | Activates Taq; cofactor | Concentration is critical; too much → non-specific bands |
| Step | Temperature | Duration | What Happens |
|---|---|---|---|
| Initial denaturation | 95°C | 2-5 min | Full template strand separation; hot-start activation |
| Denaturation | 94-95°C | 30-60 sec | Breaks hydrogen bonds between complementary strands |
| Primer annealing | 50-65°C | 30-60 sec | Primers hybridize to their complementary sequences |
| Extension | 72°C | 30-120 sec | Taq adds dNTPs at 3' end of primer (~1 kb/min) |
| Final extension | 72°C | 5-10 min | Completes any partial strands |
| Hold | 4-15°C | Indefinite | Reaction storage until analysis |
| Type | Principle | Key Feature | Applications |
|---|---|---|---|
| Standard (Conventional) PCR | Basic 3-step cycling | Single primer pair; qualitative | Gene detection, cloning, sequencing templates |
| RT-PCR | RNA → cDNA (by reverse transcriptase), then PCR | Works with RNA template | RNA virus detection, mRNA expression; e.g., SARS-CoV-2, HIV |
| Nested PCR | Two successive rounds; second primer set is internal to first amplicon | Increased sensitivity + specificity; 15-30 cycles per round | Rare pathogen detection; confirms first-round identity |
| Hemi-nested PCR | Variant of nested; one primer is shared between rounds | Slightly less specific than fully nested | Diagnostic microbiology |
| Multiplex PCR | Multiple primer pairs in one reaction | Amplifies several targets simultaneously | Pathogen panels, deletion analysis, STR genotyping |
| Real-Time PCR (qPCR) | Fluorescent dyes/probes monitor amplification in real time | Simultaneous amplification + quantification; no post-PCR processing | Viral load quantification, gene expression, food pathogen testing |
| Digital PCR (dPCR) | Sample partitioned into thousands of droplets; each undergoes independent PCR | Absolute quantification without standard curve; counts positive vs negative partitions | Rare mutation detection, copy number variation, viral load, liquid biopsy |
| Allele-Specific PCR (AS-PCR) | 3' end of primer is specific for a mutant allele | Amplifies only mutant/wild-type allele | SNP genotyping, somatic mutation detection |
| Long-Range PCR | Special polymerase blends (Taq + proofreading enzyme) | Amplifies 5-30 kb fragments | Structural genomic analysis, large deletions |
| Hot-Start PCR | Taq is inhibited at low temp; activates only at high temp | Reduces non-specific priming and primer-dimers | Improved specificity for difficult targets |
| COLD-PCR | Selective denaturation enriches minor alleles | Enriches low-frequency mutant alleles | Cancer mutation detection, liquid biopsy |
| Polymerase | Source | 5'→3' Synthesis | 5'→3' Exonuclease | 3'→5' Proofreading | Fidelity | Best Used For |
|---|---|---|---|---|---|---|
| Taq | Thermus aquaticus | Yes | Yes | No | Low | Routine diagnostic PCR |
| Vent | Thermococcus litoralis | Yes | No | Yes | High | Cloning, sequencing |
| Pfu | Pyrococcus furiosus | Yes | No | Yes | Highest | High-accuracy cloning |
| Tth | Thermus thermophilus | Yes | Yes | No | Low | RT-PCR (has RT activity) |
| Domain | Application | Example |
|---|---|---|
| Diagnostics | Detection of infectious diseases | COVID-19 (SARS-CoV-2), TB (M. tuberculosis), HIV, Hepatitis |
| Oncology | Somatic mutation detection, minimal residual disease | KRAS, BRAF mutations; BCR-ABL in CML |
| Forensics | DNA fingerprinting, identity testing | Crime scene blood/hair identification |
| Genetics | Prenatal diagnosis, carrier screening | Sickle cell disease, cystic fibrosis, Down's syndrome |
| Reproductive Medicine | Embryo sexing, PGD | Pre-implantation genetic diagnosis (IVF) |
| Molecular Palaeontology | Ancient DNA analysis | Evolutionary studies of extinct species |
| Research | Gene cloning, mutagenesis, sequencing template | Site-directed mutagenesis, cDNA library construction |
| Microbiology | Pathogen identification, antibiotic resistance genes | mecA (MRSA), vanA (VRE) |
| Blood Banking | Donor screening | NAT testing for HIV, HCV, HBV |
| Food Safety | Pathogen detection, GMO detection | Salmonella, E. coli O157:H7 |
| Problem | Likely Cause | Solution |
|---|---|---|
| No amplification | Insufficient template; primer misdesign; Mg²⁺ too low | Check template quality/quantity; re-design primers; optimize Mg²⁺ |
| Non-specific bands | Annealing temp too low; Mg²⁺ too high | Increase annealing temperature; reduce MgCl₂; use hot-start Taq |
| Primer-dimer | Primer self-complementarity | Redesign primers; use hot-start PCR |
| Smear on gel | Over-amplification; template degradation | Reduce cycle number; improve template quality |
| False positives | Carry-over contamination (prior PCR products) | Use dUTP + UNG (uracil-N-glycosylase); closed-tube/real-time methods; UV decontamination |
| Method | Principle | Use |
|---|---|---|
| Agarose gel electrophoresis + EtBr | Size-based separation; intercalating dye | Classical; confirms product size |
| Capillary electrophoresis | High-resolution size discrimination | Finer band sizing, fragment analysis |
| Probe hybridization | Probe binds specifically to product | Confirms identity; used in real-time PCR |
| Real-time fluorescence (SYBR/TaqMan) | Fluorescent signal during amplification | Quantitative; no post-PCR steps |
| Mass spectrometry | Precise molecular weight of product | Accurate sizing, multiplexing |
| DNA sequencing | Sequence determination of amplicon | Gold standard for product verification |

┌─────────────────────────────────────────────────────────┐
│ PCR - MUST REMEMBER FACTS │
├─────────────────────────────────────────────────────────┤
│ • Inventor: Kary B. Mullis, 1983 (Nobel 1993) │
│ • Primer length: 18-30 nt (min 16 nt) │
│ • dNTPs: 200 µM each (4 types) │
│ • Taq: from Thermus aquaticus; NO proofreading │
│ • Pfu/Vent: HAVE proofreading → high fidelity │
│ • Mg²⁺ (1.5 mM MgCl₂): CRITICAL cofactor │
│ • Denaturation: 94-95°C | Annealing: ~55°C │
│ • Extension: 72°C (optimal for Taq) │
│ • Amplification: 2ⁿ (theory); (1+e)ⁿ (practical) │
│ • 20 cycles = ~10⁶ fold; 30 cycles = ~10⁹ fold │
│ • RT-PCR: RNA → cDNA first, then amplify │
│ • Nested: 2 rounds, inner primers → ↑ sensitivity │
│ • Multiplex: >1 primer pair in same tube │
│ • qPCR = quantitative = Real-Time PCR │
│ • Digital PCR = absolute quantification, no standards │
└─────────────────────────────────────────────────────────┘
Make it concise form exam writing
| Component | Details |
|---|---|
| Template DNA | As little as 1 molecule; sources - blood, tissue, forensic/ancient specimens |
| Primers | 18-30 nt long; similar G+C content; anneal on opposite strands; oriented toward each other |
| dNTPs | dATP, dGTP, dCTP, dTTP - each at 200 µM (saturating) |
| Taq Polymerase | From Thermus aquaticus; thermostable; has 5'→3' exonuclease; lacks 3'→5' proofreading |
| Buffer | 50 mM KCl + 10 mM Tris-HCl (pH 7.2) + 1.5 mM MgCl₂ (Mg²⁺ is critical) |
High-fidelity alternatives to Taq: Vent polymerase, Pfu polymerase - both have 3'→5' proofreading
REACTION SETUP
(Template + Primers + dNTPs + Taq + Mg²⁺ Buffer)
│
▼
INITIAL DENATURATION ── 95°C / 2-5 min
(Full strand separation)
│
▼
┌───────────────────────────────┐
│ CYCLE (Repeat 20-40 times) │
│ │
│ STEP 1: DENATURATION │
│ 94-95°C / 30-60 sec │
│ dsDNA → 2 × ssDNA │
│ │ │
│ ▼ │
│ STEP 2: PRIMER ANNEALING │
│ 50-65°C / 30-60 sec │
│ Primers bind complementary │
│ sequences on each strand │
│ │ │
│ ▼ │
│ STEP 3: EXTENSION │
│ 72°C / 30-120 sec │
│ Taq adds dNTPs at 3' end │
│ New strand synthesized 5'→3' │
└───────────────────────────────┘
│
▼
FINAL EXTENSION ── 72°C / 5-10 min
(Completes all partial strands)
│
▼
PRODUCT DETECTION
(Gel electrophoresis / qPCR / Sequencing)
| Cycles | Theoretical Copies | Fold Amplification |
|---|---|---|
| 10 | 2¹⁰ | ~1,000× |
| 20 | 2²⁰ | ~1,000,000× |
| 30 | 2³⁰ | ~1,000,000,000× |
| Type | Key Principle | Application |
|---|---|---|
| RT-PCR | RNA → cDNA (reverse transcriptase) → PCR | RNA virus detection; mRNA expression |
| Nested PCR | 2 rounds; 2nd primers are internal to 1st amplicon | ↑ Sensitivity + specificity; rare pathogens |
| Multiplex PCR | Multiple primer pairs in one reaction | Simultaneous amplification of several targets |
| Real-Time (qPCR) | Fluorescence monitors amplification in real time | Quantification of DNA/RNA |
| Digital PCR (dPCR) | Sample partitioned into droplets; count positive vs negative | Absolute quantification; no standard curve needed |
| Allele-Specific PCR | 3' primer end matches only mutant/wild-type allele | SNP + mutation detection |
| Hot-Start PCR | Taq inactive at low temp; activates at 95°C | Reduces non-specific bands and primer-dimers |
| Polymerase | Organism | Proofreading | Use |
|---|---|---|---|
| Taq | T. aquaticus | ✗ No | Routine PCR |
| Pfu | P. furiosus | ✓ Yes | High-fidelity cloning |
| Vent | T. litoralis | ✓ Yes | High-fidelity cloning |
| Fact | Value |
|---|---|
| Inventor | Kary B. Mullis, 1983 |
| Primer length | 18-30 nt (min 16 nt) |
| dNTP concentration | 200 µM each |
| Denaturation temp | 94-95°C |
| Annealing temp | ~50-65°C |
| Extension temp | 72°C (optimal for Taq) |
| Critical cofactor | Mg²⁺ (1.5 mM MgCl₂) |
| Taq proofreading | Absent (error-prone) |
| Cycles used | 20-40 |
| RT-PCR converts | RNA → cDNA first |
| Nested PCR advantage | ↑ Sensitivity + ↑ Specificity |
| Digital PCR advantage | Absolute quantification, no standards |
Need the above as pdf with images of pcr included as easy drawing
mkdir -p /tmp/workspace/pcr-pdf && ls /tmp/workspace/pcr-pdf/
~/pcr-pdf/make_diagrams.py
"""
Generate PCR diagrams as PNG images for embedding in PDF.
Diagram 1: PCR Cycle Flowchart
Diagram 2: DNA Strand amplification sketch (easy drawing style)
Diagram 3: Types of PCR overview
"""
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import FancyArrowPatch, FancyBboxPatch, Arc
import matplotlib.patheffects as pe
import numpy as np
# ─────────────────────────────────────────
# DIAGRAM 1: PCR CYCLE FLOWCHART
# ─────────────────────────────────────────
fig1, ax1 = plt.subplots(figsize=(8, 11))
ax1.set_xlim(0, 10)
ax1.set_ylim(0, 14)
ax1.axis('off')
fig1.patch.set_facecolor('#FAFAFA')
def rounded_box(ax, x, y, w, h, label, sublabel='', color='#2196F3', text_color='white', fontsize=11):
box = FancyBboxPatch((x - w/2, y - h/2), w, h,
boxstyle="round,pad=0.15",
facecolor=color, edgecolor='white',
linewidth=2, zorder=3)
ax.add_patch(box)
if sublabel:
ax.text(x, y + 0.18, label, ha='center', va='center',
fontsize=fontsize, fontweight='bold', color=text_color, zorder=4)
ax.text(x, y - 0.25, sublabel, ha='center', va='center',
fontsize=8.5, color=text_color, zorder=4, style='italic')
else:
ax.text(x, y, label, ha='center', va='center',
fontsize=fontsize, fontweight='bold', color=text_color, zorder=4)
def arrow_down(ax, x, y_top, y_bot, color='#555555'):
ax.annotate('', xy=(x, y_bot + 0.05), xytext=(x, y_top - 0.05),
arrowprops=dict(arrowstyle='->', color=color, lw=2))
# Title
ax1.text(5, 13.5, 'PCR CYCLE FLOWCHART', ha='center', va='center',
fontsize=15, fontweight='bold', color='#1A237E')
ax1.axhline(13.1, color='#1A237E', lw=2, xmin=0.05, xmax=0.95)
# Boxes top to bottom
boxes = [
(5, 12.4, 7.5, 0.75, 'REACTION SETUP', 'Template + Primers + dNTPs + Taq + Mg²⁺ Buffer', '#37474F'),
(5, 11.2, 7.5, 0.75, 'INITIAL DENATURATION', '95°C | 2-5 minutes | Complete strand separation', '#B71C1C'),
]
for bx in boxes:
rounded_box(ax1, *bx)
arrow_down(ax1, 5, 12.05, 11.6)
arrow_down(ax1, 5, 10.85, 10.2)
# Cycle box
cycle_rect = FancyBboxPatch((0.4, 7.3), 9.2, 2.75,
boxstyle="round,pad=0.2",
facecolor='#E8F5E9', edgecolor='#2E7D32',
linewidth=2.5, zorder=2)
ax1.add_patch(cycle_rect)
ax1.text(5, 10.22, '⟳ CYCLE (Repeat 20–40 times)', ha='center', va='center',
fontsize=11, fontweight='bold', color='#2E7D32')
# Three steps inside cycle
step_data = [
(2.4, 9.3, 2.8, 0.85, 'STEP 1\nDENATURATION', '94-95°C\n30-60 sec\ndsDNA → 2×ssDNA', '#C62828'),
(5.0, 9.3, 2.8, 0.85, 'STEP 2\nANNEALING', '50-65°C\n30-60 sec\nPrimers bind', '#1565C0'),
(7.6, 9.3, 2.8, 0.85, 'STEP 3\nEXTENSION', '72°C\n30-120 sec\nTaq synthesizes', '#2E7D32'),
]
for sx, sy, sw, sh, sl, ss, sc in step_data:
box = FancyBboxPatch((sx - sw/2, sy - sh/2), sw, sh,
boxstyle="round,pad=0.12",
facecolor=sc, edgecolor='white', linewidth=1.5, zorder=4)
ax1.add_patch(box)
lines = sl.split('\n')
ax1.text(sx, sy + 0.22, lines[0], ha='center', va='center',
fontsize=8.5, fontweight='bold', color='white', zorder=5)
ax1.text(sx, sy - 0.05, lines[1], ha='center', va='center',
fontsize=7.5, fontweight='bold', color='white', zorder=5)
for i, line in enumerate(ss.split('\n')):
ax1.text(sx, sy - 0.27 - i*0.18, line, ha='center', va='center',
fontsize=7, color='#FFECB3', zorder=5)
# Arrows between steps
ax1.annotate('', xy=(3.85, 9.3), xytext=(3.25, 9.3),
arrowprops=dict(arrowstyle='->', color='#555', lw=1.8))
ax1.annotate('', xy=(6.4, 9.3), xytext=(5.85, 9.3),
arrowprops=dict(arrowstyle='->', color='#555', lw=1.8))
# Cycle arrow (looping back)
ax1.annotate('', xy=(1.0, 8.6), xytext=(1.0, 7.8),
arrowprops=dict(arrowstyle='->', color='#2E7D32', lw=2,
connectionstyle='arc3,rad=-0.5'))
ax1.text(0.25, 8.2, 'Repeat', ha='center', va='center',
fontsize=8, color='#2E7D32', fontweight='bold', rotation=90)
arrow_down(ax1, 5, 7.3, 6.75)
# Final extension box
rounded_box(ax1, 5, 6.35, 7.5, 0.75,
'FINAL EXTENSION', '72°C | 5-10 minutes | Completes all partial strands', '#4527A0')
arrow_down(ax1, 5, 5.98, 5.45)
# Amplification note
ax1.text(5, 5.2, '2ⁿ copies (theoretical) (1+e)ⁿ copies (practical)',
ha='center', va='center', fontsize=9.5, color='#333',
bbox=dict(boxstyle='round,pad=0.3', facecolor='#FFF9C4', edgecolor='#F9A825'))
arrow_down(ax1, 5, 4.95, 4.45)
# Detection
rounded_box(ax1, 5, 4.1, 7.5, 0.65,
'PRODUCT DETECTION', 'Gel Electrophoresis | qPCR Fluorescence | Sequencing', '#00695C')
# Amplification table
ax1.text(5, 3.45, 'Amplification at key cycles:', ha='center', va='center',
fontsize=9.5, fontweight='bold', color='#333')
tbl_data = [['Cycles', '10', '20', '30', '40'],
['Copies', '~1,000×', '~1,000,000×', '~10⁹×', '~10¹²×']]
col_colors = ['#BBDEFB', '#E3F2FD', '#E3F2FD', '#E3F2FD', '#E3F2FD']
tbl = ax1.table(cellText=tbl_data,
loc='center',
bbox=[0.08, 0.14, 0.84, 0.12])
tbl.auto_set_font_size(False)
tbl.set_fontsize(9)
for (r, c), cell in tbl.get_celld().items():
cell.set_edgecolor('#90CAF9')
if r == 0:
cell.set_facecolor('#1565C0')
cell.set_text_props(color='white', fontweight='bold')
else:
cell.set_facecolor('#E3F2FD')
plt.tight_layout()
plt.savefig('/tmp/workspace/pcr-pdf/diagram1_cycle.png', dpi=150, bbox_inches='tight',
facecolor='#FAFAFA')
plt.close()
print("Diagram 1 saved.")
# ─────────────────────────────────────────
# DIAGRAM 2: DNA STRAND AMPLIFICATION (Easy Drawing)
# ─────────────────────────────────────────
fig2, axes = plt.subplots(1, 3, figsize=(13, 7))
fig2.patch.set_facecolor('#F8F9FA')
colors = {'fwd': '#E91E63', 'rev': '#4CAF50', 'orig': '#1565C0', 'new': '#FF8F00'}
def draw_dna_strand(ax, y, x_start, x_end, color, lw=4, label='', label_x=None, label_y=None):
ax.plot([x_start, x_end], [y, y], color=color, lw=lw, solid_capstyle='round')
if label:
lx = label_x if label_x else (x_start + x_end)/2
ly = label_y if label_y else y + 0.15
ax.text(lx, ly, label, ha='center', va='bottom', fontsize=8, color=color, fontweight='bold')
def draw_primer(ax, x_start, x_end, y, color, direction='right'):
ax.plot([x_start, x_end], [y, y], color=color, lw=6, solid_capstyle='butt',
alpha=0.9)
if direction == 'right':
ax.annotate('', xy=(x_end + 0.05, y), xytext=(x_end - 0.01, y),
arrowprops=dict(arrowstyle='->', color=color, lw=2))
else:
ax.annotate('', xy=(x_start - 0.05, y), xytext=(x_start + 0.01, y),
arrowprops=dict(arrowstyle='->', color=color, lw=2))
def hbonds(ax, x1, x2, y_top, y_bot, n=8, color='#9E9E9E'):
xs = np.linspace(x1 + 0.1, x2 - 0.1, n)
for x in xs:
ax.plot([x, x], [y_top, y_bot], color=color, lw=1, ls='--', alpha=0.6)
for idx, (ax, title, step_color) in enumerate(zip(
axes,
['STEP 1: DENATURATION\n(94-95°C)',
'STEP 2: ANNEALING\n(50-65°C)',
'STEP 3: EXTENSION\n(72°C)'],
['#C62828', '#1565C0', '#2E7D32'])):
ax.set_xlim(-0.2, 5.2)
ax.set_ylim(-0.5, 5.8)
ax.axis('off')
ax.set_facecolor('#FFFFFF')
# Step title
title_box = FancyBboxPatch((-0.15, 4.9), 5.3, 0.75,
boxstyle='round,pad=0.1',
facecolor=step_color, edgecolor='none')
ax.add_patch(title_box)
lines = title.split('\n')
ax.text(2.5, 5.45, lines[0], ha='center', va='center',
fontsize=9.5, fontweight='bold', color='white')
ax.text(2.5, 5.1, lines[1], ha='center', va='center',
fontsize=9, color='#FFE082')
if idx == 0:
# Double-stranded DNA with H-bonds
draw_dna_strand(ax, 3.5, 0, 5, colors['orig'], lw=5, label="5'─────────────────3'", label_y=3.75)
draw_dna_strand(ax, 2.8, 0, 5, colors['orig'], lw=5, label="3'─────────────────5'", label_y=2.55)
hbonds(ax, 0, 5, 3.5, 2.8, n=10)
ax.text(2.5, 4.3, 'Double-stranded DNA (dsDNA)', ha='center', fontsize=8.5,
color='#333', style='italic')
# Heat arrow
ax.annotate('', xy=(2.5, 1.9), xytext=(2.5, 2.6),
arrowprops=dict(arrowstyle='->', color='#FF5722', lw=2.5))
ax.text(2.5, 1.65, '🔥 HEAT → H-bonds break', ha='center', fontsize=8.5,
color='#FF5722', fontweight='bold')
# Two separated strands
draw_dna_strand(ax, 1.3, 0, 5, colors['orig'], lw=5)
ax.text(0, 1.5, "5'", fontsize=8, color=colors['orig'], fontweight='bold')
ax.text(4.85, 1.5, "3'", fontsize=8, color=colors['orig'], fontweight='bold')
draw_dna_strand(ax, 0.6, 0, 5, colors['orig'], lw=5)
ax.text(0, 0.78, "3'", fontsize=8, color=colors['orig'], fontweight='bold')
ax.text(4.85, 0.78, "5'", fontsize=8, color=colors['orig'], fontweight='bold')
ax.text(2.5, 0.15, '2 × Single-stranded DNA (ssDNA)', ha='center', fontsize=8.5,
color='#333', style='italic')
elif idx == 1:
# Two separated strands + primers annealing
draw_dna_strand(ax, 3.8, 0, 5, colors['orig'], lw=5)
ax.text(0, 4.0, "5'", fontsize=8, color=colors['orig'], fontweight='bold')
ax.text(4.85, 4.0, "3'", fontsize=8, color=colors['orig'], fontweight='bold')
# Reverse primer on top strand (anneals 3' end)
draw_primer(ax, 3.2, 4.9, 3.35, colors['rev'], direction='left')
ax.text(4.05, 3.55, 'Rev primer', fontsize=7.5, color=colors['rev'], fontweight='bold')
draw_dna_strand(ax, 1.8, 0, 5, colors['orig'], lw=5)
ax.text(0, 2.0, "3'", fontsize=8, color=colors['orig'], fontweight='bold')
ax.text(4.85, 2.0, "5'", fontsize=8, color=colors['orig'], fontweight='bold')
# Forward primer on bottom strand
draw_primer(ax, 0.1, 1.8, 1.35, colors['fwd'], direction='right')
ax.text(0.9, 1.5, 'Fwd primer', fontsize=7.5, color=colors['fwd'], fontweight='bold')
ax.text(2.5, 0.8, "Cool down → Primers bind\ncomplementary sequences",
ha='center', fontsize=8.5, color='#333', style='italic')
ax.text(2.5, 0.25, "Primers oriented TOWARD each other →",
ha='center', fontsize=8, color='#1565C0', fontweight='bold')
elif idx == 2:
# Extension: new strands being synthesized
# Top template
draw_dna_strand(ax, 4.0, 0, 5, colors['orig'], lw=5)
ax.text(0, 4.2, "5'", fontsize=8, color=colors['orig'], fontweight='bold')
ax.text(4.85, 4.2, "3'", fontsize=8, color=colors['orig'], fontweight='bold')
draw_primer(ax, 3.2, 4.9, 3.55, colors['rev'], direction='left')
# New strand growing from rev primer
draw_dna_strand(ax, 3.55, 0.1, 3.15, colors['new'], lw=4)
ax.text(1.6, 3.7, 'New strand', fontsize=7.5, color=colors['new'], fontweight='bold')
# Taq symbol
ax.text(3.0, 3.75, 'Taq→', fontsize=8, color='#FF6F00', fontweight='bold')
# Bottom template
draw_dna_strand(ax, 2.0, 0, 5, colors['orig'], lw=5)
ax.text(0, 2.2, "3'", fontsize=8, color=colors['orig'], fontweight='bold')
ax.text(4.85, 2.2, "5'", fontsize=8, color=colors['orig'], fontweight='bold')
draw_primer(ax, 0.1, 1.8, 1.55, colors['fwd'], direction='right')
draw_dna_strand(ax, 1.55, 1.85, 4.9, colors['new'], lw=4)
ax.text(3.4, 1.7, 'New strand', fontsize=7.5, color=colors['new'], fontweight='bold')
ax.text(2.0, 1.75, '←Taq', fontsize=8, color='#FF6F00', fontweight='bold')
ax.text(2.5, 0.9, "Taq polymerase adds dNTPs\nat 3' end of each primer",
ha='center', fontsize=8.5, color='#333', style='italic')
ax.text(2.5, 0.35, "72°C | ~1000 bp/minute",
ha='center', fontsize=9, color='#2E7D32', fontweight='bold')
# Legend
legend_elements = [
mpatches.Patch(color=colors['orig'], label='Original template strand'),
mpatches.Patch(color=colors['fwd'], label='Forward primer (pink)'),
mpatches.Patch(color=colors['rev'], label='Reverse primer (green)'),
mpatches.Patch(color=colors['new'], label='Newly synthesized strand'),
]
fig2.legend(handles=legend_elements, loc='lower center', ncol=4,
fontsize=8.5, framealpha=0.9,
bbox_to_anchor=(0.5, -0.02))
plt.suptitle('PCR DNA STRAND AMPLIFICATION - Three Steps of One Cycle',
fontsize=13, fontweight='bold', color='#1A237E', y=1.01)
plt.tight_layout(pad=1.0)
plt.savefig('/tmp/workspace/pcr-pdf/diagram2_strands.png', dpi=150, bbox_inches='tight',
facecolor='#F8F9FA')
plt.close()
print("Diagram 2 saved.")
# ─────────────────────────────────────────
# DIAGRAM 3: TYPES OF PCR
# ─────────────────────────────────────────
fig3, ax3 = plt.subplots(figsize=(12, 7))
ax3.set_xlim(0, 12)
ax3.set_ylim(0, 8)
ax3.axis('off')
fig3.patch.set_facecolor('#F8F9FA')
ax3.text(6, 7.55, 'TYPES OF PCR', ha='center', va='center',
fontsize=15, fontweight='bold', color='#1A237E')
# Central hub
hub = plt.Circle((6, 4), 0.9, color='#1A237E', zorder=5)
ax3.add_patch(hub)
ax3.text(6, 4.1, 'PCR', ha='center', va='center',
fontsize=14, fontweight='bold', color='white', zorder=6)
ax3.text(6, 3.7, 'Types', ha='center', va='center',
fontsize=9, color='#90CAF9', zorder=6)
# Satellite nodes: (angle_deg, label, sublabel, color)
nodes = [
(90, 'Standard\nPCR', 'Qualitative detection\nSingle primer pair', '#C62828'),
(45, 'RT-PCR', 'RNA→cDNA→PCR\nFor RNA viruses, mRNA', '#AD1457'),
(0, 'Nested\nPCR', '2 rounds, inner primers\n↑ Sensitivity + Specificity', '#6A1B9A'),
(315, 'Multiplex\nPCR', 'Multiple primer pairs\nSeveral targets at once', '#1565C0'),
(270, 'Real-Time\nqPCR', 'Fluorescence detection\nQuantitative', '#00695C'),
(225, 'Digital\nPCR (dPCR)', 'Droplet partitioning\nAbsolute quantification', '#E65100'),
(180, 'Hot-Start\nPCR', 'Taq activated at 95°C\n↓ Non-specific products', '#37474F'),
(135, 'Allele-Specific\nPCR', '3\' primer end specific\nSNP & mutation detection','#558B2F'),
]
radius = 2.8
for angle_deg, label, sublabel, color in nodes:
angle_rad = np.radians(angle_deg)
cx = 6 + radius * np.cos(angle_rad)
cy = 4 + radius * np.sin(angle_rad)
# Spoke
spoke_x = 6 + 0.95 * np.cos(angle_rad)
spoke_y = 4 + 0.95 * np.sin(angle_rad)
end_x = 6 + (radius - 0.7) * np.cos(angle_rad)
end_y = 4 + (radius - 0.7) * np.sin(angle_rad)
ax3.plot([spoke_x, end_x], [spoke_y, end_y], color=color, lw=2, alpha=0.7, zorder=3)
# Node box
bw, bh = 2.0, 1.0
box = FancyBboxPatch((cx - bw/2, cy - bh/2), bw, bh,
boxstyle='round,pad=0.1',
facecolor=color, edgecolor='white', linewidth=1.5, zorder=4)
ax3.add_patch(box)
lines = label.split('\n')
ax3.text(cx, cy + 0.22, lines[0], ha='center', va='center',
fontsize=9, fontweight='bold', color='white', zorder=5)
if len(lines) > 1:
ax3.text(cx, cy - 0.02, lines[1], ha='center', va='center',
fontsize=8, color='white', zorder=5)
for i, sline in enumerate(sublabel.split('\n')):
ax3.text(cx, cy - 0.3 - i * 0.2, sline, ha='center', va='center',
fontsize=7, color='#FFECB3', zorder=5)
plt.tight_layout()
plt.savefig('/tmp/workspace/pcr-pdf/diagram3_types.png', dpi=150, bbox_inches='tight',
facecolor='#F8F9FA')
plt.close()
print("Diagram 3 saved.")
print("All diagrams done.")
cd /tmp/workspace/pcr-pdf && python make_diagrams.py 2>&1
~/pcr-pdf/make_pdf.py
"""
Generate full PCR exam notes PDF using ReportLab.
Pages:
1. Cover + Definition + History
2. Components table
3. Diagram 1 - PCR Cycle Flowchart
4. Diagram 2 - DNA Strand Steps
5. Types of PCR table
6. Diagram 3 - Types of PCR radial
7. Polymerase comparison + Applications
8. High-yield summary box
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
Image, PageBreak, HRFlowable, KeepTogether
)
from reportlab.platypus.flowables import BalancedColumns
from reportlab.lib.colors import HexColor, white, black
import os
# ── Paths ──────────────────────────────────────────────
OUT = '/tmp/workspace/pcr-pdf/PCR_Exam_Notes.pdf'
D1 = '/tmp/workspace/pcr-pdf/diagram1_cycle.png'
D2 = '/tmp/workspace/pcr-pdf/diagram2_strands.png'
D3 = '/tmp/workspace/pcr-pdf/diagram3_types.png'
# ── Colour palette ──────────────────────────────────────
NAVY = HexColor('#1A237E')
BLUE = HexColor('#1565C0')
LBLUE = HexColor('#E3F2FD')
GREEN = HexColor('#2E7D32')
LGREEN = HexColor('#E8F5E9')
RED = HexColor('#B71C1C')
LRED = HexColor('#FFEBEE')
PURPLE = HexColor('#4527A0')
AMBER = HexColor('#F57F17')
LAMBER = HexColor('#FFF9C4')
GREY = HexColor('#37474F')
LGREY = HexColor('#ECEFF1')
TEAL = HexColor('#00695C')
LTEAL = HexColor('#E0F2F1')
# ── Styles ─────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
title_style = S('Title',
fontName='Helvetica-Bold', fontSize=22, textColor=white,
alignment=TA_CENTER, spaceAfter=4)
h1 = S('H1',
fontName='Helvetica-Bold', fontSize=14, textColor=NAVY,
spaceBefore=10, spaceAfter=4, borderPad=3)
h2 = S('H2',
fontName='Helvetica-Bold', fontSize=11, textColor=BLUE,
spaceBefore=7, spaceAfter=3)
body = S('Body',
fontName='Helvetica', fontSize=9.5, textColor=GREY,
leading=14, spaceAfter=3, alignment=TA_JUSTIFY)
bullet = S('Bullet',
fontName='Helvetica', fontSize=9.5, textColor=GREY,
leading=13, leftIndent=14, spaceAfter=2,
bulletFontName='Helvetica', bulletFontSize=9.5)
caption = S('Caption',
fontName='Helvetica-Oblique', fontSize=8.5, textColor=GREY,
alignment=TA_CENTER, spaceAfter=4)
highlight = S('Highlight',
fontName='Helvetica-Bold', fontSize=9.5, textColor=NAVY,
leading=14, spaceAfter=2)
small = S('Small',
fontName='Helvetica', fontSize=8.5, textColor=GREY, leading=12)
# ── Helper functions ───────────────────────────────────
def colored_header(text, bg=NAVY, fg=white, size=13):
"""Return a single-cell table that acts as a coloured heading."""
t = Table([[Paragraph(f'<b>{text}</b>',
ParagraphStyle('ch', fontName='Helvetica-Bold',
fontSize=size, textColor=fg,
alignment=TA_LEFT))]],
colWidths=[17*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (-1,-1), 10),
('ROUNDEDCORNERS', [4,4,4,4]),
]))
return t
def info_box(text, bg=LAMBER, border=AMBER):
t = Table([[Paragraph(text, ParagraphStyle('ib', fontName='Helvetica-Bold',
fontSize=9.5, textColor=HexColor('#5D4037'), leading=14))]],
colWidths=[17*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('BOX', (0,0), (-1,-1), 1.5, border),
('TOPPADDING', (0,0), (-1,-1), 7),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
('LEFTPADDING', (0,0), (-1,-1), 12),
]))
return t
def plain_table(header_row, data_rows, col_widths,
header_bg=BLUE, row_bg1=LBLUE, row_bg2=white):
all_rows = [header_row] + data_rows
t = Table(all_rows, colWidths=col_widths, repeatRows=1)
style = [
('BACKGROUND', (0,0), (-1,0), header_bg),
('TEXTCOLOR', (0,0), (-1,0), white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('GRID', (0,0), (-1,-1), 0.5, HexColor('#B0BEC5')),
('ROWBACKGROUNDS', (0,1), (-1,-1), [row_bg1, row_bg2]),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
]
t.setStyle(TableStyle(style))
return t
# ── Page template (header/footer) ──────────────────────
def on_page(canvas, doc):
canvas.saveState()
w, h = A4
# Footer
canvas.setFillColor(NAVY)
canvas.rect(0, 0, w, 1.0*cm, fill=1, stroke=0)
canvas.setFillColor(white)
canvas.setFont('Helvetica', 8)
canvas.drawCentredString(w/2, 0.35*cm, f'PCR Exam Notes • Page {doc.page} • Orris Study Aid')
# Top accent bar
canvas.setFillColor(NAVY)
canvas.rect(0, h - 0.4*cm, w, 0.4*cm, fill=1, stroke=0)
canvas.restoreState()
# ── Build story ────────────────────────────────────────
story = []
# ════════════════════════════════════════
# COVER BANNER
# ════════════════════════════════════════
cover_data = [[
Paragraph('POLYMERASE CHAIN REACTION', title_style),
]]
cover_sub = [[
Paragraph('Concise Exam Notes • With Diagrams • Key Tables',
ParagraphStyle('cs', fontName='Helvetica', fontSize=12,
textColor=HexColor('#BBDEFB'), alignment=TA_CENTER)),
]]
cover = Table(cover_data, colWidths=[17*cm])
cover.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), NAVY),
('TOPPADDING', (0,0), (-1,-1), 20),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
]))
cover_sub_t = Table(cover_sub, colWidths=[17*cm])
cover_sub_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), BLUE),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING', (0,0), (-1,-1), 12),
]))
story += [cover, cover_sub_t, Spacer(1, 0.4*cm)]
# ════════════════════════════════════════
# SECTION 1 - Definition & History
# ════════════════════════════════════════
story.append(colored_header('1. DEFINITION & HISTORICAL BACKGROUND'))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
'PCR is an <b>in-vitro enzymatic amplification</b> of a specific DNA sequence using a pair of '
'oligonucleotide primers, extended by a <b>thermostable DNA polymerase</b> through repetitive '
'cycles of denaturation, primer annealing, and extension. It is the most common '
'nucleic acid amplification (NAA) technique used in clinical and research laboratories.',
body))
story.append(Spacer(1, 0.2*cm))
hist_data = [
['Inventor', 'Kary B. Mullis (with colleagues Saiki et al., 1985; 1988)'],
['Year', '1983 (conceptualized); published 1985'],
['Nobel Prize','Chemistry, 1993 (Kary B. Mullis)'],
['Significance','Milestone that heralded the beginning of molecular diagnostics'],
]
ht = plain_table(['Detail', 'Information'], hist_data,
[4*cm, 13*cm], header_bg=GREY)
story += [ht, Spacer(1, 0.3*cm)]
story.append(info_box(
'KEY CONCEPT: "PCR is a simple in-vitro chemical reaction that permits synthesis of essentially '
'limitless quantities of a targeted nucleic acid sequence." — Henry\'s Clinical Diagnosis, 23rd Ed.'))
story.append(Spacer(1, 0.35*cm))
# ════════════════════════════════════════
# SECTION 2 - Components
# ════════════════════════════════════════
story.append(colored_header('2. COMPONENTS OF PCR'))
story.append(Spacer(1, 0.2*cm))
comp_data = [
['Template\nDNA', 'Any source', 'As little as 1 molecule\nA260/A280 ratio ~1.8 (purity)',
'Blood, tissue, forensic specimens,\nancient samples, plasmid, colonies'],
['Primers\n(Forward\n& Reverse)', '18-30 nt\n(min 16 nt)', 'Similar G+C content;\nanneal on OPPOSITE strands;\noriented TOWARD each other;\nfinal conc. 0.1-0.5 µM',
'If sequence unknown, degenerate\nprimers used; avoid hairpins\nand primer-dimers'],
['dNTPs\n(4 types)', '200 µM each\n(saturating)', 'dATP, dGTP, dCTP, dTTP\nEquimolar mixture',
'Building blocks for new strand;\ndepleted with excess cycles'],
['Taq\nPolymerase', 'From\nThermus\naquaticus', '5\'→3\' synthesis + 5\'→3\' exonuclease;\nNO 3\'→5\' proofreading;\nhalf-life >2 hr at 95°C',
'Error-prone (~1/10⁵ bases);\nhot-start variants available;\nalternatives: Vent, Pfu (proofreading)'],
['Buffer', 'pH ~7.2-8.4', '50 mM KCl\n10 mM Tris-HCl\n1.5 mM MgCl₂',
'Mg²⁺ is CRITICAL cofactor;\ntoo low → no product;\ntoo high → non-specific bands'],
]
ct = Table(
[['Component', 'Amount /\nSource', 'Key Properties', 'Important Notes']] + comp_data,
colWidths=[2.8*cm, 2.5*cm, 5.5*cm, 6.2*cm], repeatRows=1)
ct.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), BLUE),
('TEXTCOLOR', (0,0), (-1,0), white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8.5),
('GRID', (0,0), (-1,-1), 0.5, HexColor('#B0BEC5')),
('ROWBACKGROUNDS',(0,1), (-1,-1), [LBLUE, white]),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 5),
# Highlight Mg2+ row
('TEXTCOLOR', (0,4), (-1,4), HexColor('#B71C1C')),
('FONTNAME', (0,4), (-1,4), 'Helvetica-Bold'),
]))
story += [ct, Spacer(1, 0.3*cm)]
# Polymerase comparison
story.append(colored_header(' Polymerase Comparison', bg=GREY, size=11))
story.append(Spacer(1, 0.15*cm))
pol_data = [
['Taq', 'Thermus aquaticus', '✓ Yes', '✗ No', 'Low', 'Routine diagnostic PCR'],
['Pfu', 'Pyrococcus furiosus', '✓ Yes', '✓ Yes', 'Highest', 'High-fidelity cloning / sequencing'],
['Vent', 'Thermococcus litoralis','✓ Yes', '✓ Yes', 'High', 'High-fidelity cloning'],
['Tth', 'Thermus thermophilus', '✓ Yes', '✗ No', 'Low', 'RT-PCR (has reverse transcriptase activity)'],
]
pt = plain_table(
['Enzyme', 'Source Organism', '5\'→3\'\nSynthesis', '3\'→5\'\nProofreading', 'Fidelity', 'Best Used For'],
pol_data,
[1.8*cm, 4*cm, 2*cm, 2.2*cm, 2*cm, 5*cm])
story += [pt, Spacer(1, 0.2*cm)]
story.append(PageBreak())
# ════════════════════════════════════════
# SECTION 3 - PCR Cycle Flowchart Diagram
# ════════════════════════════════════════
story.append(colored_header('3. PCR CYCLE - STEP BY STEP'))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
'Each cycle consists of <b>three steps</b>: Denaturation → Annealing → Extension. '
'Two-step cycling (combined annealing/extension) is also used in diagnostic assays '
'when annealing temperature is close to extension temperature.',
body))
story.append(Spacer(1, 0.2*cm))
# Temperature table
temp_data = [
['Initial Denaturation', '95°C', '2-5 min', 'Full template strand separation; hot-start activation'],
['Denaturation', '94-95°C','30-60 sec', 'Breaks H-bonds; dsDNA → 2×ssDNA'],
['Primer Annealing', '50-65°C','30-60 sec', 'Primers bind complementary sequences on each strand'],
['Extension', '72°C', '30-120 sec', 'Taq adds dNTPs at 3\' end of primers (~1 kb/min)'],
['Final Extension', '72°C', '5-10 min', 'Completes all partial amplicon strands'],
['Hold', '4-15°C', 'Indefinite', 'Reaction storage; prevents degradation'],
]
tt = plain_table(['Step', 'Temp', 'Duration', 'What Happens'],
temp_data, [3.6*cm, 2*cm, 2.4*cm, 9*cm],
header_bg=RED)
story += [tt, Spacer(1, 0.3*cm)]
# Diagram 1
story.append(Image(D1, width=14*cm, height=18*cm, hAlign='CENTER'))
story.append(Paragraph('Fig 1: PCR Cycle Flowchart showing all steps, temperatures, and amplification mathematics.',
caption))
story.append(PageBreak())
# ════════════════════════════════════════
# SECTION 4 - DNA Strand Diagram
# ════════════════════════════════════════
story.append(colored_header('4. DNA STRAND AMPLIFICATION - VISUAL GUIDE'))
story.append(Spacer(1, 0.15*cm))
story.append(Image(D2, width=17*cm, height=9.5*cm, hAlign='CENTER'))
story.append(Paragraph(
'Fig 2: Easy drawing of the three PCR steps at the DNA level. '
'Pink = forward primer, Green = reverse primer, Blue = original template, Orange = newly synthesized strand.',
caption))
story.append(Spacer(1, 0.3*cm))
# Amplification maths box
story.append(colored_header(' Amplification Mathematics', bg=GREEN, size=11))
story.append(Spacer(1, 0.15*cm))
amp_data = [
['10', '2¹⁰', '~1,000×', 'Thousand-fold'],
['20', '2²⁰', '~1,000,000×', 'Million-fold'],
['30', '2³⁰', '~1,000,000,000×', 'Billion-fold'],
['n', '2ⁿ', '(1+e)ⁿ practical', 'e = efficiency (0–1)'],
]
mt = plain_table(['Cycles (n)', 'Theoretical Copies', 'Amplification', 'Notes'],
amp_data, [3.5*cm, 4*cm, 5*cm, 4.5*cm],
header_bg=GREEN, row_bg1=LGREEN)
story += [mt, Spacer(1, 0.2*cm)]
story.append(info_box(
'After 20 cycles → ~1,000,000-fold amplification. After 30 cycles → ~1,000,000,000-fold. '
'In practice, total amplification = (1+e)ⁿ where e is efficiency. '
'Inhibitors (blood heme, bile salts, urine urea) reduce e and can cause false negatives.'))
story.append(PageBreak())
# ════════════════════════════════════════
# SECTION 5 - Types of PCR
# ════════════════════════════════════════
story.append(colored_header('5. TYPES OF PCR'))
story.append(Spacer(1, 0.15*cm))
story.append(Image(D3, width=16.5*cm, height=9.5*cm, hAlign='CENTER'))
story.append(Paragraph('Fig 3: Radial overview of major PCR types.', caption))
story.append(Spacer(1, 0.25*cm))
types_data = [
['Standard PCR', 'Single primer pair; 3-step cycling',
'Qualitative; gene detection', 'Routine detection, cloning'],
['RT-PCR', 'RNA → cDNA (reverse transcriptase) → PCR',
'Targets RNA; cDNA intermediate', 'RNA viruses (HIV, COVID-19), mRNA expression'],
['Nested PCR', '2 rounds; 2nd primers internal to 1st amplicon\n(15-30 cycles each round)',
'↑ Sensitivity + ↑ Specificity;\nrisk: carry-over contamination', 'Rare pathogen detection; confirms 1st-round identity'],
['Hemi-Nested PCR', 'One primer shared between both rounds',
'Slightly less specific than full nested', 'Diagnostic microbiology'],
['Multiplex PCR', 'Multiple primer pairs in one reaction',
'Several targets amplified simultaneously;\nsaves time, template, cost', 'Pathogen panels, STR genotyping, deletion analysis'],
['Real-Time qPCR', 'Fluorescence (SYBR/TaqMan probe) monitors\namplification in real time',
'Simultaneous amplification + quantification;\nno post-PCR gel step', 'Viral load, gene expression, food pathogen quantification'],
['Digital PCR (dPCR)', 'Sample partitioned into thousands of droplets;\neach undergoes independent PCR',
'Absolute quantification WITHOUT standard curve;\ncounts +ve vs -ve droplets (Poisson correction)', 'Rare mutation detection, copy number variation,\nviral load, ctDNA liquid biopsy'],
['Allele-Specific PCR', '3\' end of primer matches ONLY mutant or wild-type allele',
'Amplifies one allele selectively', 'SNP genotyping, somatic mutation detection'],
['Hot-Start PCR', 'Taq inhibited at low temp (Ab or chemical);\nactivates only at 95°C',
'Reduces non-specific bands and primer-dimers', 'Difficult/GC-rich targets; improved specificity'],
['COLD-PCR', 'Selective denaturation enriches minor alleles',
'Enriches low-frequency mutant alleles', 'Cancer mutation detection, liquid biopsy'],
['Long-Range PCR', 'Taq + proofreading enzyme blend',
'Amplifies 5-30 kb fragments', 'Structural genomic analysis, large deletions'],
]
tyt = Table(
[['Type', 'Principle', 'Key Feature', 'Applications']] + types_data,
colWidths=[2.8*cm, 4.5*cm, 4.5*cm, 5.2*cm], repeatRows=1)
tyt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), PURPLE),
('TEXTCOLOR', (0,0), (-1,0), white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8),
('GRID', (0,0), (-1,-1), 0.5, HexColor('#CE93D8')),
('ROWBACKGROUNDS',(0,1), (-1,-1), [HexColor('#F3E5F5'), white]),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
]))
story += [tyt, PageBreak()]
# ════════════════════════════════════════
# SECTION 6 - Applications
# ════════════════════════════════════════
story.append(colored_header('6. APPLICATIONS OF PCR'))
story.append(Spacer(1, 0.15*cm))
app_data = [
['Infectious Disease\nDiagnosis', 'Detection of bacteria, viruses, fungi, parasites\nin clinical specimens',
'COVID-19 (SARS-CoV-2), HIV, TB (M. tuberculosis),\nHBV, HCV, HSV, CMV, MRSA, VRE'],
['Oncology', 'Somatic mutation detection; minimal residual disease;\nctDNA in liquid biopsy',
'KRAS, BRAF, BCR-ABL (CML monitoring), TP53'],
['Prenatal Diagnosis', 'Genetic disease screening of fetus;\nembryo sexing in IVF',
'Sickle cell disease, cystic fibrosis,\npre-implantation genetic diagnosis (PGD)'],
['Forensic Science', 'DNA fingerprinting; identity confirmation;\ncrime scene evidence',
'STR profiling, paternity testing,\ncrime scene blood/hair/saliva identification'],
['Blood Banking (NAT)', 'Nucleic acid testing of donor blood\nfor transfusion safety',
'HIV, HCV, HBV window period detection;\nprevents transfusion-transmitted infections'],
['Gene Cloning &\nResearch', 'Amplifying target genes for cloning;\nin-vitro mutagenesis;\nsequencing template',
'Site-directed mutagenesis, cDNA library\nconstruction, gene expression studies'],
['Molecular\nPalaeontology', 'Amplification of ancient DNA from\nextinct organisms',
'Evolutionary studies, species identification\nfrom museum specimens, fossils'],
['Food Safety &\nMicrobiology', 'Pathogen detection in food;\nGMO identification',
'Salmonella, E. coli O157:H7,\nListeria; GMO labelling compliance'],
['Antibiotic\nResistance', 'Detection of resistance genes in\nclinical microbiology',
'mecA (MRSA), vanA/vanB (VRE),\nKPC (carbapenem resistance)'],
['HLA Typing', 'Tissue matching for organ transplantation',
'Bone marrow and solid organ\ntransplantation matching'],
]
at = Table(
[['Domain', 'Description', 'Examples']] + app_data,
colWidths=[3.5*cm, 6*cm, 7.5*cm], repeatRows=1)
at.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), TEAL),
('TEXTCOLOR', (0,0), (-1,0), white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8),
('GRID', (0,0), (-1,-1), 0.5, HexColor('#80CBC4')),
('ROWBACKGROUNDS',(0,1), (-1,-1), [LTEAL, white]),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
]))
story += [at, Spacer(1, 0.3*cm)]
# ════════════════════════════════════════
# SECTION 7 - Detection Methods
# ════════════════════════════════════════
story.append(colored_header('7. POST-PCR DETECTION METHODS'))
story.append(Spacer(1, 0.15*cm))
det_data = [
['Agarose Gel + EtBr', 'Size-based separation + intercalating dye fluorescence', 'Classical; confirms product size; qualitative'],
['Capillary Electrophoresis', 'High-resolution electrophoretic sizing', 'Fragment analysis; finer band resolution than gel'],
['Probe Hybridization', 'Labelled probe binds specifically to amplicon', 'Confirms identity; used in blot-based assays'],
['Real-Time Fluorescence', 'SYBR Green (non-specific) or TaqMan probe (specific)', 'Quantitative; no post-PCR gel; closed-tube system'],
['Mass Spectrometry', 'Precise molecular weight determination of amplicon', 'Multiplex; accurate sizing; SNP analysis'],
['DNA Sequencing', 'Direct sequencing of PCR product', 'Gold standard; confirms sequence identity'],
['Melting Curve Analysis', 'Post-qPCR; monitors fluorescence vs temperature', 'Distinguishes specific product from primer-dimers'],
]
dt = plain_table(['Method', 'Principle', 'Use'], det_data,
[4*cm, 6.5*cm, 6.5*cm], header_bg=AMBER)
story += [dt, PageBreak()]
# ════════════════════════════════════════
# SECTION 8 - Troubleshooting
# ════════════════════════════════════════
story.append(colored_header('8. PCR TROUBLESHOOTING'))
story.append(Spacer(1, 0.15*cm))
tr_data = [
['No amplification', 'Insufficient template; Mg²⁺ too low;\nprimers misdesigned; polymerase inactive',
'Check template quantity/purity; optimize Mg²⁺;\nre-design primers; verify thermocycler program'],
['Non-specific bands', 'Annealing temp too low;\nMg²⁺ too high; primer-dimer formation',
'Raise annealing temp; reduce MgCl₂;\nuse hot-start Taq or touchdown PCR'],
['Smear on gel', 'Over-amplification; degraded template;\ntoo many cycles',
'Reduce cycle number; improve template quality;\ncheck dNTP concentration'],
['False positives', 'Carry-over contamination from prior\nPCR products (amplicon contamination)',
'Use dUTP + UNG (uracil-N-glycosylase);\nclosed-tube real-time PCR; UV decontamination;\nphysical separation of pre/post PCR areas'],
['Inhibited reaction', 'Blood heme, bile salts, urine urea,\nheparin, EDTA, SDS',
'Dilute template; use BSA or betaine;\nswitch to inhibitor-resistant polymerase'],
]
trt = Table(
[['Problem', 'Likely Cause', 'Solution']] + tr_data,
colWidths=[3.5*cm, 6cm, 7.5*cm], repeatRows=1)
trt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), RED),
('TEXTCOLOR', (0,0), (-1,0), white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 8),
('GRID', (0,0), (-1,-1), 0.5, HexColor('#EF9A9A')),
('ROWBACKGROUNDS',(0,1), (-1,-1), [LRED, white]),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
]))
story += [trt, Spacer(1, 0.35*cm)]
# ════════════════════════════════════════
# SECTION 9 - HIGH-YIELD SUMMARY BOX
# ════════════════════════════════════════
story.append(colored_header('9. HIGH-YIELD EXAM SUMMARY', bg=NAVY))
story.append(Spacer(1, 0.2*cm))
hy_data = [
['Inventor', 'Kary B. Mullis, 1983 (Nobel Prize Chemistry 1993)'],
['Primer length', '18-30 nt (minimum 16 nt)'],
['dNTP concentration', '200 µM each (dATP, dGTP, dCTP, dTTP)'],
['Denaturation temp', '94-95°C'],
['Annealing temp', '~50-65°C (depends on primer Tm)'],
['Extension temp', '72°C (optimal for Taq; ~1 kb/min)'],
['Critical cofactor', 'Mg²⁺ (1.5 mM MgCl₂)'],
['Taq proofreading', 'ABSENT (lacks 3\'→5\' exonuclease) → error-prone'],
['Vent / Pfu', 'HAVE proofreading → high fidelity → preferred for cloning'],
['Cycles used', '20-40 (commonly)'],
['20 cycles amplification', '~1,000,000-fold (10⁶)'],
['30 cycles amplification', '~1,000,000,000-fold (10⁹)'],
['RT-PCR converts', 'RNA → cDNA (by reverse transcriptase) FIRST, then PCR'],
['Nested PCR advantage', '↑ Sensitivity + ↑ Specificity; uses INNER primer set in 2nd round'],
['Multiplex PCR', 'Uses >1 primer pair in SAME tube; several targets at once'],
['qPCR = ', 'Quantitative = Real-Time PCR (simultaneous amplification + detection)'],
['Digital PCR advantage', 'Absolute quantification WITHOUT standard curve; droplet partitioning'],
['Major inhibitors', 'Blood heme, bile salts, urine urea, heparin, EDTA'],
]
hyt = Table(
[['Key Point', 'Detail']] + hy_data,
colWidths=[5.5*cm, 11.5*cm], repeatRows=1)
hyt.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), NAVY),
('TEXTCOLOR', (0,0), (-1,0), white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,-1), 9),
('GRID', (0,0), (-1,-1), 0.5, HexColor('#90CAF9')),
('ROWBACKGROUNDS',(0,1), (-1,-1), [LBLUE, white]),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('TEXTCOLOR', (0,1), (0,-1), NAVY),
('FONTNAME', (1,1), (1,-1), 'Helvetica'),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 6),
]))
story.append(hyt)
# Footer credit
story.append(Spacer(1, 0.4*cm))
story.append(HRFlowable(width='100%', thickness=1, color=NAVY))
story.append(Paragraph(
'Sources: Henry\'s Clinical Diagnosis & Management by Laboratory Methods 23e | '
'Medical Microbiology 9e | Tietz Textbook of Laboratory Medicine 7e | '
'Saiki et al. 1985 & 1988',
ParagraphStyle('src', fontName='Helvetica-Oblique', fontSize=7.5,
textColor=GREY, alignment=TA_CENTER, spaceBefore=4)))
# ── Build PDF ──────────────────────────────────────────
doc = SimpleDocTemplate(
OUT,
pagesize=A4,
topMargin=1.2*cm,
bottomMargin=1.5*cm,
leftMargin=2*cm,
rightMargin=2*cm,
title='PCR Exam Notes',
author='Orris Study Aid',
subject='Polymerase Chain Reaction - Concise Exam Notes'
)
doc.build(story, onFirstPage=on_page, onLaterPages=on_page)
print(f"PDF saved to: {OUT}")
cd /tmp/workspace/pcr-pdf && python make_pdf.py 2>&1
~/pcr-pdf/make_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/pcr-pdf/make_pdf.py'
cd /tmp/workspace/pcr-pdf && python make_pdf.py 2>&1
ls -lh /tmp/workspace/pcr-pdf/
PCR Exam Notes
PDF Document · PDF
| Section | Content |
|---|---|
| Cover | Title banner with subtitle |
| 1. Definition & History | Concise definition, history table, key concept quote from textbook |
| 2. Components | Full components table (Template, Primers, dNTPs, Taq, Buffer) + polymerase comparison table (Taq vs Pfu vs Vent vs Tth) |
| 3. PCR Cycle | Temperature/duration table + Fig 1: Full cycle flowchart diagram with all steps, temps, and amplification maths |
| 4. DNA Strand Guide | Fig 2: Easy step-by-step drawing of DNA denaturation, primer annealing, and extension at molecular level (colour-coded strands and primers) |
| 5. Types of PCR | Fig 3: Radial diagram of all 8 types + detailed comparison table (11 types total) |
| 6. Applications | 10-domain applications table with examples |
| 7. Detection Methods | Post-PCR detection table (gel, qPCR, sequencing, mass spec etc.) |
| 8. Troubleshooting | Common PCR problems, causes, and solutions |
| 9. High-Yield Summary | 18-row must-remember facts table - exam ready |