6 Chapter 6 — Reading the Test
Applied Epidemiology in Aquaculture — Part III: The Investigator’s Toolkit
Where this sits — Detect (secondary prevention). Early detection is only as good as the test behind it. This chapter quantifies how much to trust a qPCR or culture result, finishes the apparent-vs-true prevalence correction from Chapter 4, and underpins every surveillance decision in Chapters 8 and 12.
6.1 Overview
A laboratory result is not the truth; it is evidence about the truth, and its weight depends on the test’s accuracy and on how common the disease is. This chapter covers the numbers that turn a “positive” into a decision: sensitivity and specificity (properties of the test), predictive values (what a result means for this fish, which depends on prevalence), likelihood ratios, the ROC curve for choosing a cut-off, and agreement between tests when there is no gold standard. The running example is P. salmonis detection by qPCR and culture — the exact problem your keynote framed as “what do we do when PCR does not match the clinical picture?”
We use srs_diagnostics.csv: 400 salmon with a qPCR call, its Ct value, a culture result, and (for teaching) the reference infection status.
6.2 6.1 Preparation
pacman::p_load(rio, here, tidyverse, janitor, epiR, pROC)
dx <- import(here("data", "srs_diagnostics.csv"))
glimpse(dx)6.3 6.2 Sensitivity and specificity
Cross-classify the test against the reference:
dx <- dx |> mutate(qpcr = factor(qpcr, levels = c("pos","neg")),
ref = factor(true_status, levels = c("infected","clear")))
epi.tests(table(dx$qpcr, dx$ref))| Infected | Clear | |
|---|---|---|
| qPCR positive | 107 (TP) | 9 (FP) |
| qPCR negative | 8 (FN) | 276 (TN) |
- Sensitivity (Se) = TP/(TP+FN) = 107/115 = 0.93 — of truly infected fish, 93% test positive.
- Specificity (Sp) = TN/(TN+FP) = 276/285 = 0.97 — of truly clear fish, 97% test negative.
🧮 Epivet Tools — Diagnostic test evaluation Enter TP/FP/FN/TN for Se, Sp, PPV, NPV and likelihood ratios, and watch PPV change with prevalence: tools.epivet.cl/dx-test. Reference model: Ausvet EpiTools.
Se and Sp are (roughly) properties of the test, stable across settings. They answer “if I know the true status, how will the test behave?” — which is backwards from what a clinician actually faces.
6.4 6.3 Predictive values depend on prevalence
The farm’s real question is the reverse: given a positive result, how likely is this fish truly infected? That is the positive predictive value (PPV), and it depends on the prevalence in the tested population.
- PPV = TP/(TP+FP) = 107/116 = 0.92
- NPV = TN/(TN+FN) = 276/284 = 0.97
At the sample prevalence (29%), a positive qPCR means a 92% chance of true infection. But watch what happens when the same test is used for surveillance in a low-prevalence population — say 5% infected:
# PPV at 5% prevalence, same Se = 0.93, Sp = 0.97
Se <- 0.93; Sp <- 0.97; prev <- 0.05
(Se*prev) / (Se*prev + (1-Sp)*(1-prev)) # 0.61The PPV collapses to 61% — four in ten positives are now false alarms, even though the test has not changed. This is the single most important idea in diagnostics: the same test means different things in different populations. It is why a positive in an outbreak is nearly definitive, while a positive in a clean area demands confirmation (exactly the pragmatic rule in your keynote).
6.5 6.4 Likelihood ratios
Likelihood ratios (LR) combine Se and Sp into how much a result shifts the odds of infection, and (unlike predictive values) do not depend on prevalence:
- LR+ = Se/(1−Sp) = 0.93/0.032 = ≈ 30 — a positive is 30× more likely in an infected than a clear fish (strong).
- LR− = (1−Se)/Sp = 0.07/0.97 = 0.07 — a negative nearly rules infection out.
LRs are the cleanest way to update belief as new results arrive, and they travel across populations.
6.6 6.5 Choosing a cut-off: the ROC curve
The qPCR call hinged on a Ct cut-off (positive if Ct ≤ 36). Move the cut-off and you trade sensitivity against specificity. The ROC curve plots that trade-off across all cut-offs; the area under it (AUC) summarises overall discrimination (0.5 = useless, 1.0 = perfect):
roc_ct <- roc(response = dx$true_status, predictor = dx$ct_value,
levels = c("clear","infected"), direction = ">")
auc(roc_ct) # 0.96
plot(roc_ct)Here AUC = 0.96 — Ct value discriminates infected from clear fish very well. The cut-off that maximises Youden’s index (Se + Sp − 1), here 0.90, is the statistically “balanced” choice — but the right operational cut-off depends on purpose: screening for freedom from disease wants high sensitivity; confirming before antibiotics wants high specificity.
6.7 6.6 When there is no gold standard
We cheated above by knowing true_status. In reality culture and qPCR are both imperfect, and they disagree. Cohen’s kappa measures agreement beyond chance:
epi.kappa(table(dx$qpcr, dx$culture)) # kappa ~ 0.53Agreement is only moderate (κ = 0.53) — because culture misses many true infections that qPCR catches (its sensitivity is ~5–30× lower; Laurin et al., 2020). When no test is perfect, latent-class models estimate Se and Sp without a gold standard, as Laurin and colleagues did for P. salmonis across three farms. And the trouble compounds between laboratories: a blinded ring trial of the authorised Chilean labs found differing positivity cut-offs and inconsistent detection of low-load samples (Peña et al., 2025) — so “qPCR-positive” is not one thing, and Ct values are only comparable within a single lab and method.
6.7.1 Finishing the true-prevalence correction
With Se and Sp in hand we can complete the Chapter 4 bridge. The apparent prevalence of 29% corrects to a true prevalence via Rogan–Gladen:
ap <- 0.29
(ap + Sp - 1) / (Se + Sp - 1) # true prevalenceBecause this test is accurate, the correction is small here — but in a low-prevalence surveillance setting with an imperfect test, the gap between apparent and true can be large and must never be ignored.
6.8 6.7 Interpretation on the farm
Detect done well means reading a result in context: a positive in a clean area (low PPV) triggers confirmation, not treatment; a negative with SRS-like mortality prompts a check of sampling, assay target and the possibility of a different agent (even P. nova, which can read as P. salmonis). The practical hierarchy from your keynote falls straight out of these numbers — target the right fish to raise sensitivity, use quality-assured labs to protect specificity, and follow Ct trends rather than a single value before committing antibiotics.
6.9 6.8 Exercises
Try it yourself (6.1). Run
epi.tests()and confirm Se and Sp. Then recompute PPV assuming a prevalence of 2% — how many of every 10 positives would be false?
6.2 Explain, using LR+, why a single positive qPCR is far more convincing during an outbreak than during routine screening of a clean site.
6.3 Build the ROC curve for Ct and find the Youden-optimal cut-off. If your goal were to certify a site free of SRS, would you move the cut-off to favour sensitivity or specificity? Why?
6.4 Culture here has high specificity but low sensitivity. If you used culture alone as your reference to “validate” qPCR, what mistake would you make about qPCR’s specificity, and why do latent-class models avoid it?
6.5 Using Rogan–Gladen with Se = 0.93, Sp = 0.97, convert an apparent prevalence of 10% to a true prevalence. Repeat with Sp = 0.90 and comment.
6.10 Summary & what’s next
- Sensitivity/specificity are test properties; predictive values depend on prevalence — the same positive means different things in outbreak vs surveillance settings.
- Likelihood ratios update belief and are prevalence-independent.
- The ROC/AUC describes discrimination across cut-offs; the operational cut-off follows the purpose.
- With no gold standard, quantify agreement (kappa) and estimate accuracy with latent-class models; results are also lab-dependent.
- Se and Sp complete the apparent→true prevalence correction from Chapter 4.
In Chapter 7 — Choosing a Study Design we step back to Anticipate and ask how to collect evidence in the first place: cross-sectional, cohort, and case-control designs, and the trade-offs that decide which measure of association (Chapter 5) you can even compute.
6.11 References & further reading
- Laurin E, Gardner IA, et al. Bayesian estimation of diagnostic sensitivity and specificity for P. salmonis. J Fish Dis. 2020;43:1167–1175.
- Peña A, Rozas-Serri M, Gardner IA, Diethelm-Varela B, et al., Mardones FO. Inter-laboratory comparison of qPCR for P. salmonis. J Fish Dis. 2025;48:e14044.
- Dohoo I, Martin W, Stryhn H. Veterinary Epidemiologic Research. 2nd ed. VER Inc.; 2009. — screening and diagnostic test evaluation.
- Thrusfield M, Christley R. Veterinary Epidemiology. 4th ed. Wiley-Blackwell; 2018.
- Rodger H, et al. Piscirickettsia-like organisms (incl. P. nova) in European salmon. Bull Eur Assoc Fish Pathol. 2025. — why assay target matters.
Files for this chapter: data/srs_diagnostics.csv and scripts/make_srs_diagnostics.R (new).