Objective Detection of Phage Treatment Effect Onset from Optical Density Data
by Stephen T. Abedon Ph.D.Steve Abedon, Ph.D., has taught well over 100 individual classes and ~10 individual courses over his 30+ years as a college professor. He has over 150 publications, including multiple monographs, and is ranked in the top 1 or 2 percent among researchers of all disciplines worldwide. His research focuses on bacteriophage biology and phage therapy. (abedon.1@osu.edu)
phage.org | phage-therapy.org | biologyaspoetry.org | abedon.phage.org | google scholar | publications
Jump to: 📋 Menu | 💡 Concept | ∂ The Math | 🔬 Analyzer | n-Analyzer | 🧪 Time-Kill | 📊 Compare | 📖 Methods | ⚙️ Tech | 🧮 More Calculators
?simdata=1) for analyzing ODE simulation outputs against the same
detection algorithms. T1 PFU-titration sub-series (Experiments 21–23) is exposed
via URL ?pfus=1.
deviation.phage.org · Abedon’s Books · DOI: 10.5281/zenodo.19023877
How can I improve this page? contact: deviation@phage.org
Threshold-based detection (Uni & Multi) enables direct comparison between approaches; it is also more robust than the "earliest" estimate for both noisy and continuous data.
For a primer on the underlying math — first derivative, second derivative, inflection points — see the ∂ The Math tab.
When lytic bacteriophage infect a bacterial culture, the optical density (OD) of the culture eventually begins to drop as infected cells lyse. But the actual onset of deviation — when the phage treatment first measurably affects bacterial growth — often occurs earlier than the OD drop. Deviation is the separation of phage-containing from phage-free OD curves; it is the OD signature of phage impact on a bacterial culture. Detecting this precisely, objectively, and early is the goal of this calculator.
Deviation is a y-axis phenomenon — a magnitude. Its onset and the operational estimates of that onset are x-axis quantities — times. The methods first detect whether deviation is occurring (y-axis), then estimate when it began (x-axis).
Deviation onset is the calculus landmark itself (d²(OD)/dt² = 0; equivalently, d(OD)/dt at its maximum). Earliest deviation and threshold deviation are operational alternatives, used when a noise margin past the bare onset is desired. In temporal order: deviation onset → earliest deviation (half a sample later) → threshold deviation (later still, after the deviation has accumulated to 5% of peak slope). All three are computed from the same OD curve; which one to report depends on how much noise margin the application requires.
Deviation timing — the x-axis quantity — is a measure of phage antibacterial virulence: earlier deviation onset means faster-acting phage (Abedon 2025a; Abedon 2025b). It complements traditional metrics like OD-max and area-under-curve (AUC), but perhaps most importantly it provides an OD-based alternative to traditional time-kill curves. The key advantage: automated OD plate readers can take readings every few minutes across a multi-hour experiment, whereas traditional time-kill curves require manual plating at each timepoint — making fine-resolution sampling impractical (Abedon 2026).
Every phage-bacterial OD curve contains a sequence of biologically meaningful moments. The calculator identifies and reports the following landmarks, each marked by a feature of the OD curve, its first derivative d(OD)/dt, or its second derivative d²(OD)/dt²:
The two killings — phage-mediated bactericidal activity (deviation) and bacterial physiological death (lysis) — sit at successive landmarks separated by approximately one latent period. A single signal (the second derivative) narrates the entire phage-bacterial dynamic. The landmarks above the lysis cascade (PL, 95L, EOL) and beyond (presumptive regrowth) extend the same calculus-based framework to capture the full lifecycle of the OD signature.
The Time-Kill tab adds CFU-side landmarks (CFU peak, CFU 50% drop, CFU 10× drop, CFU 100× drop) when CFU measurements are also provided. The Sim Data tab adds simulation-only landmarks (Peak culture growth, Control stationary phase). For chart axes and AUC integration windows, the calculator consistently anchors at TD — see the Math tab section 8 for rationale.
This calculator implements three approaches to detecting deviation, ordered from least to most complex — in terms of what data you need, what assumptions you make, and what happens when simpler approaches are insufficient. These are Univariate Detection, Multivariate Detection, and Statistical Detection:
One curve — no control required. When bacterial growth is exponential, the natural logarithm of OD increases linearly with time. This means the instantaneous slope of ln(OD) — the specific growth rate μ — is constant. Deviation is detected as the first sustained departure of μ from its pre-deviation plateau: mathematically, when the second derivative of ln(OD) with respect to time (d²(ln OD)/dt²) first becomes persistently negative — that is, when the growth rate itself is declining.
The instantaneous slope (the slope of a short local window of ln(OD) vs time, approximating d(ln OD)/dt at each moment) is computed at each timepoint and compared against the peak pre-deviation slope. When the slope first drops below a threshold fraction of that peak and stays down, deviation is declared.
Experimental flexibility: Because Univariate Detection requires only a single curve, it offers greater experimental flexibility than the two-curve approaches. Multiple treatment curves with different starting bacterial concentrations can be generated and analyzed simultaneously without the need to precisely pair each one with a matched phage-free control experiment. Technical replicates can likewise be analyzed individually and compared directly, rather than averaged to match a control — preserving within-experiment variation that averaging would obscure.
The cost of this flexibility is also experimental: Univariate Detection requires not only that deviation occurs during exponential growth, but that exponential growth is captured over a sufficient number of timepoints to establish with confidence that the pre-deviation growth was in fact exponential. Too few pre-deviation timepoints, or a lag phase that extends too far into the pre-deviation period and thereby obscures it (it is best practice to start these experiments with log-phase bacteria), will compromise the reliability of the result — as reflected in a low correlation coefficient.
Quality metric: How flat is the instantaneous slope series during the pre-deviation window? If the slope d(OD)/dt is nearly constant (or equivalently, if d(ln OD)/dt is constant on a logarithmic plot — exponential growth being linear on a log scale but not on a linear scale) (a flat horizontal line), the pre-deviation growth was cleanly exponential and detection is reliable. If the slope is erratic or trending, exponential growth was not clean and results should be interpreted with caution. The calculator reports this flatness using the correlation coefficient (R²) — expressed as a percentage from 0% to 100%, where higher means flatter and more reliable.
Two curves — phage-free control required. The Univariate Detection approach requires exponential growth because it is the linearity of ln(OD) vs time that provides the flat reference baseline. If growth is not exponential — for example, if the culture is in a lag phase, approaching stationary phase, or growing linearly rather than exponentially — then ln(OD) is not linear in time, the slope series is not flat, and establishing a stable baseline becomes more difficult, making the approach less reliable.
The Multivariate Detection approach solves this by using the phage-free control curve as the reference rather than pre-deviation bacterial growth in phage presence — no curve fitting or assumption about growth shape is needed. At each timepoint, the instantaneous slope of ln(OD_treatment) and the instantaneous slope of ln(OD_control) are each computed independently. As long as phage are having no effect, both cultures are growing at the same rate, so the two slopes are equal — their difference hovers near zero regardless of what shape the growth curve has. It doesn't matter whether growth is exponential, linear, decelerating, or anything else: whatever is driving both cultures equally appears in both slope series and cancels out when you subtract one from the other.
Deviation is declared at the first moment when the treatment slope drops persistently below the control slope — the same logic as Univariate Detection, but using the control curve's instantaneous slope as the reference rather than the treatment curve's own pre-deviation slope. No curve fitting is required; the control curve provides the reference point by point.
What Multi can and cannot resolve. Multi fires when the treatment slope falls persistently below the control slope by more than 5% of the control's own peak growth rate. That comparison is well posed whenever the two curves separate over a reasonably narrow span of time. It is not well posed when they separate gradually: if the phage effect builds smoothly over an extended period, there is no single moment at which the curves part company, and the reported time necessarily depends on where the threshold is placed. This is common on:
A useful diagnostic follows from this. Re-run the analysis at several thresholds: if the reported time barely moves, the deviation is inflectional and the landmark is well defined; if it marches steadily later as the threshold is raised, the deviation is gradual and no single deviation time exists to be found. Across a 69-pair evaluation corpus, 58 pairs gave a stable answer and 11 — all of them lysis-inhibition or late-log records — gave a threshold-dependent ramp. A detector that reported one number for those 11 would be inventing it.
Historical note. Before 2026-07-26 Multi also failed on a second, separate class of dataset: mid-log infections whose deviation onset fell inside Multi's training window, where the signal contaminated the noise estimate that set the detection threshold. That training window has been removed and the failure with it — Multi's coverage across the evaluation corpus rose from 78% to 100%. Only the gradual-versus-inflectional limitation above remains, and it is a property of the data rather than of the algorithm.
Quality metric: Noise level of the pre-deviation residual. Low noise → sensitive detection. High noise → consider the Statistical approach.
Why the three “5%” thresholds are not the same 5%
Each detector reports a threshold deviation at a nominal 5%, and it is tempting to read the three numbers as one measurement made three ways. They are not. The three thresholds are applied to three quantities of different kinds, and only two of them describe a divergence at all.
| Landmark | Quantity thresholded | Reference the fraction is taken of |
|---|---|---|
| TDuni | treatment d(OD)/dt | its own maximum — one curve only |
| TDmulti | treatment − control d(OD)/dt | the control’s peak d(OD)/dt |
| TDstat | treatment / control OD values | its pre-deviation baseline |
Part of the difference is unavoidable. The detectors work at different derivative orders: Statistical compares OD values, Univariate and Multivariate compare rates, and deviation onset is a curvature landmark. A 5% change in a value, in a rate and in an acceleration are not the same physical quantity, and no choice of wording makes them commensurable. This also explains an ordering seen throughout the corpus — DO precedes the rate-based TDs, which in turn precede TDstat — because an accumulated difference in OD is the integral of a difference in rate, and integrals take time to become visible. Statistical is not lagging because it is worse; it is measuring something that necessarily happens later.
The rest of the difference is convention, and only TDuni is affected. Multivariate and Statistical each threshold a divergence between two curves, so the quantity being tested means something outside the algorithm. Univariate has no second curve. It measures how far the treatment has fallen from its own maximum growth rate, which is a departure from itself rather than a divergence from anything. Its threshold therefore cannot be justified by reference to an external quantity — it can only be justified by whether it reproduces the answer the two-curve detectors give.
So it is calibrated rather than assumed. Measured against TDmulti across a 69-pair corpus, a 5% drop makes TDuni fire a median 6.2 min early, agreeing within 10 min on 65% of pairs; a 20% drop reduces the bias to 0.4 min and raises agreement to 88%. The reason is visible on any steeply lysing curve: a 5% fall in the treatment’s own d(OD)/dt is a very small departure, crossed within a minute of the slope peaking, whereas 5% of the control’s peak rate is a much larger and later event. The two thresholds are numerically equal and physically unalike. The calculator therefore defaults TDuni to a 20% drop, separately from the Multi/Stat threshold, and exposes it as a control.
What this means when the detectors agree. TDuni corroborating TDmulti remains useful, but the corroboration is by established convention rather than from first principles. It shows that a single-curve method reproduces the two-curve answer on this class of data — which is exactly the property needed to trust Univariate on experiments run without a control, and that was the reason for having a single-curve detector in the first place. It is not independent confirmation, because the threshold was chosen to produce it. Conventions calibrated on one body of data may need adjusting for another: different hosts, phages, sampling intervals or growth conditions may shift the value, which is why it is adjustable rather than fixed.
Deviation onset is untouched by all of this. DO is a curvature landmark — the moment acceleration ceases, d²(OD)/dt² = 0 — and carries no threshold at all. It is produced by Univariate only; Multivariate and Statistical yield threshold deviations exclusively. DO is therefore the calculator’s one genuinely convention-free deviation landmark, and remains independent of any calibration applied to TDuni.
Two curves — phage-free control required. Direct OD-value comparison; no derivatives. Statistical detects when treatment OD falls below threshold × control OD (default 5% below) for two or more consecutive sample points. The reported time is the linearly-interpolated crossing within the bracketing sample pair — not the time of the first-below sample. This gives a sub-sampling-interval estimate of the threshold crossing, important for manually-collected data where samples are 5-15 minutes apart.
Unlike Univariate and Multivariate (which compare slopes), Statistical compares OD values directly. At low starting cell density these give similar answers; at high density they diverge — Statistical reports the time when the curves visibly separate by 5%, which happens later than when slopes first deviate (often by 30+ minutes). The gap between slope-deviation and OD-value-deviation is itself a biologically meaningful manuscript-relevant observation.
Parameter grid. Multiple window sizes (here serving as settle-in skips at the curve start) and raw vs log comparisons are run; for the OD-ratio test all combinations should converge to the same interpolated crossing. Convergence stability is a quality indicator.
The three approaches are complementary, not competing. When all three agree, you have very strong multi-method evidence. When they disagree, the pattern of disagreement is itself informative:
Starting inoculum: Beginning experiments with log-phase (exponentially growing) bacteria produces cleaner pre-deviation data for all three approaches. With log-phase inocula, OD begins rising almost immediately and the slope curve rises quickly to a reliable plateau. Stationary-phase inocula introduce a true lag phase that can obscure the pre-deviation baseline. Log-phase inocula are therefore strongly recommended.
All three approaches benefit from denser sampling. Experimental OD plate readers sampling every 5–10 minutes may appear to show sharper transitions than fine-resolution simulations — this however is a sampling artifact. Denser sampling reveals the true gradual nature of the transition and improves detection precision for all three approaches, particularly Univariate.
For Univariate specifically, two quality metrics predict detection reliability: pre-deviation R² > 0.85 indicates clean exponential growth; noise level < 10% indicates low measurement variability. Both being good = reliable. Low R² or high noise level suggests caution and preference for Statistical (Multivariate noise level is necessarily higher than Univariate on the same data, but it does not require exponential growth).
Computational models of phage-bacteria dynamics (e.g., ODE-based population models) are ideally suited to validate these detection approaches. Key open questions addressable by simulation include:
Hypothesis (working, supported by ten paired OD+CFU datasets across five experiments): All three deviation-related landmarks — deviation onset, earliest deviation, and threshold deviation — closely track CFU-measured bacterial killing time, while ODmax and end-of-lysis lag the killing event substantially. The strongest finding is that deviation onset places r48 and WT phages within half the OD sampling interval of each other in every paired experiment, even when CFU sampling is too coarse to detect the within-experiment correspondence directly.
Five reasons all three deviation candidates are useful estimators of bacterial killing:
The important caveat: These conclusions depend on having sufficiently short OD sampling intervals. With 1–5 minute sampling, threshold deviation crossings are detected with sub-sampling-interval precision via linear interpolation between samples. With 10+ minute intervals, the threshold crossing may be poorly resolved, and earliest deviation (or deviation onset itself) may become the better choice because their timings are anchored to the slope-peak sample rather than to the interpolated threshold crossing.
Test these conclusions on your own paired OD+CFU data using the 🧪 Time-Kill tab. The Time-Kill comparison table directly shows which deviation estimator (onset, earliest, or threshold) best matches the CFU 10× drop and CFU 50% drop times on your dataset.
This tab explains the mathematical ideas behind OD deviation detection — no prior calculus knowledge required.
A derivative measures how fast something is changing at a given moment. If you plot a quantity on a graph, the derivative at any point is the slope of the curve at that point — how steeply it is rising or falling.
More precisely, the first derivative of OD with respect to time, written d(OD)/dt, answers the question: "How fast is the optical density changing right now?" A large positive value means OD is rising rapidly; a value near zero means OD is barely changing; a negative value means OD is falling.
The second derivative, d²(OD)/dt², tells you how fast the first derivative itself is changing — whether the growth rate is speeding up, staying constant, or slowing down.
Physics analogy: if OD is position, then d(OD)/dt is velocity and d²(OD)/dt² is acceleration. Just as you can describe a moving car by its position, velocity, and acceleration, you can describe an OD curve by its current value, its rate of change, and the rate at which that rate of change is itself changing.
During exponential growth, a bacterial culture doubles at a constant rate. This means the OD curve rises as an exponential function: OD(t) = OD₀ × eμt, where μ is the specific growth rate.
A typical phage-bacterial OD curve passes through three biologically distinct moments, each marked by a specific feature of the derivatives of OD(t):
The second derivative as a single narrator. A single signal — d²(OD)/dt² — passes through all three landmarks in sequence: it starts positive (growth accelerating), crosses zero at deviation onset, reaches its minimum near ODmax, and crosses zero again at end-of-lysis. This calculator computes all three.
Asymmetry: deviation onset is fundamentally harder to detect than the other two landmarks — but the other two are not the same kind of "easy."
Bottom line: the value every other landmark is measured from is the slope zero crossing — it is what Figure 1A marks, what the contact sheet reports, and what bounds the deviation-onset search and anchors end of lysis, PL and L95. The peak-anchored value is the most precise of the three where a peak is well formed, and the naive value the most robust to a badly formed one; both are reported for comparison. An earlier version of this page called the peak-anchored value the default, which the code has never done.
Why is deviation onset the most informative for time-kill? Lysis onset (ODmax) occurs approximately one latent period after the phage-mediated killing events that produced it. By the time OD has peaked, the killing decision has already been made; the OD curve is reporting downstream consequence. Deviation onset, by contrast, marks the earliest detectable moment that growth has slowed relative to pure exponential — the closest OD-based correlate to the actual phage adsorption and host commitment events.
When a phage population begins to have an effect on a bacterial population, bacterial growth slows. This shows up immediately in the first derivative: d(OD)/dt, which had been rising steadily, begins to drop. The zero-crossing — where d(OD)/dt = 0 — marks where ODmaxs. At this exact moment the second derivative d²(OD)/dt² = 0, meaning the OD curve has an inflection point. This zero-crossing is the latest possible deviation time.
More sensitively, deviation can be detected before the zero-crossing, as a drop from the rising first-derivative curve. Panel A of Figures 1 and 2 shows the first derivative of OD vs time. The calculator reports two estimates:
Note on fine-grained simulations: For continuously sampled or very fine-grained data (e.g., simulations with 1-second intervals), the "earliest" estimate (peak slope timepoint) and the threshold estimate converge — adjacent timepoints are so close together that the bracket between them is negligibly small. In this regime, the threshold-based interpolated crossing is the better-defined estimate, since it gives a precise continuous time rather than depending on the sampling interval. For typical plate-reader data (4-minute intervals), the earliest and threshold estimates bracket a meaningful temporal range.
Expected ordering: The earliest estimate should always be earlier than (or equal to) the threshold estimate, which should always be earlier than (or equal to) ODmax (zero-crossing). That is: earliest ≤ threshold ≤ ODmax. Note on two-peak OD profiles: Even without phage-resistant mutant development or host-range mutation, some phage-bacterium combinations produce two distinct OD decline events: a first partial lysis (reflecting early rounds of infection) followed by bacterial regrowth and then terminal lysis (culture clearing). This is most common with lysis-inhibition phages at intermediate bacterial densities. The first ODmax is the virulence-relevant landmark — it marks when phages first began lysing bacteria at a detectable scale. The pre-terminal ODmax (last local maximum before EOL) is the KOTE-relevant landmark for phage titer calibration, since it is the consistent event across curves at all titers that precedes culture-wide clearing. Peak lysis rate timing should likewise be measured during the terminal lysis decline. The KOTE Calibration tab uses the pre-terminal ODmax automatically; the main Analyzer tab reports both (as ODmax and, when detected, the second hump time in the second lysis row). If the threshold estimate appears earlier than the earliest estimate, this indicates a data quality issue — likely a noisy spike in the first derivative that created a false peak, or insufficient data before the true deviation.
To see the zero-crossing clearly, use the X-min and X-max controls in the Figure 1 or Figure 2 toolbar to crop the x-axis around ODmax — X-min cuts off the early growth phase, X-max cuts off the post-lysis tail.
Statistical Detection is the calculator's OD-ratio detector. Unlike Univariate and Multivariate — both of which compare slopes (Uni: own-curve slope drop from peak; Multi: treatment slope drop relative to control slope) — Statistical compares OD values directly: at each treatment sample t, it computes R(t) = ODtreatment(t) / ODcontrol(t) (with control interpolated onto treatment sample times when their time grids differ), and triggers when R(t) falls below the threshold (default 0.95) for at least minConsecutive consecutive samples.
Interpolated threshold crossing. The reported time is not the time of the first sample below threshold — it is the linearly-interpolated time at which R(t) = threshold within the bracketing sample pair. Given last-above-threshold sample at (t0, T0, C0) and first-below-threshold sample at (t1, T1, C1), linear interpolation gives:
T(t) = T0 + f · (T1 − T0), C(t) = C0 + f · (C1 − C0), where f = (t − t0) / (t1 − t0).
Setting T(t) = threshold · C(t) and solving for f:
f = (threshold · C0 − T0) / [(T1 − T0) − threshold · (C1 − C0)]
Crossing time: tcross = t0 + f · (t1 − t0), valid when f ∈ [0, 1].
This interpolation makes Statistical's reported time independent of sampling interval. For 4-min plate-reader data the correction is sub-minute (negligible); for 6-12 min manual Klett data the correction is several minutes (essential for the reported time to be consistent with the threshold value).
Parameter grid — mostly degenerate for the OD-ratio test. Statistical still runs a parameter sweep across multiple window sizes and across raw vs log-space comparisons. But for the OD-ratio crossing test these dimensions are mathematically degenerate: log(T) − log(C) < log(threshold) iff T/C < threshold, and changing the leading-points skip doesn't move the eventual crossing. All grid combinations should therefore return the same interpolated crossing time. The trimmed mean and the per-method earliest collapse to the same value. Disagreement across grid combinations is therefore the meaningful diagnostic: it indicates an edge case (control values near zero, missing leading samples, transient noise spike below threshold then recovery).
When Statistical lands earlier vs later than Univariate / Multivariate. Because Statistical answers a different question (when did OD values diverge?) than Univariate / Multivariate (when did slopes diverge?), the ordering of the three reported times is itself informative:
The calculator reports three estimates of ODmax, each addressing different failure modes of the others:
The peak-anchored value carries a PRECISE / MODERATE PRECISION / LOW PRECISION / IMPRECISE label based on slope-sign consistency around the anchor point. Specifically: in a window around the discrete max, the algorithm computes short-window slopes on either side. It reports:
Confidence levels:
Confidence reflects curve shape, not biological importance. A canonical fast-lysis curve (sharp rise, sharp fall around one latent period) yields PRECISE. A delayed-lysis curve where OD drifts upward and then very gradually drifts down can yield LOW PRECISION or IMPRECISE even though the experiment is interpretable — the "peak" is just genuinely ill-defined in the data, and the confidence flag is signaling that honestly.
When all three methods agree, the data has a clean well-defined peak and any value is trustworthy. When they disagree, the disagreement is itself informative:
The naive and zero-crossing values are kept in the table as reference points for this kind of diagnostic comparison.
Note on AUC calculations: AUC windows that anchor to ODmax use the naive max time (not the peak-anchored value), because the AUC computation needs an actual sample point and the naive value is naturally aligned to one. For pre-lysis-recovery datasets (where the global naive max is post-lysis), this can produce an inappropriate AUC window — a known limitation. For most clean datasets the naive max is biologically meaningful and the AUC windows are correct.
The choice is a series of yes/no tests, applied in order. Each detector answers a different question and fails in a different way, so the tree exists to say which answer is being reported and why — not to average them. Every branch is deterministic; nothing here is fitted or weighted.
What the tree is aiming at is the earliest believable deviation. Across the 24 time-kill experiments a tenfold fall in viable counts arrives after the deviation and, in most records, before ODmax — so the useful landmark is the earliest one that can be defended, not the earliest one that can be computed.
The same tree is what the Best Estimate banner reports: its decision trail lists each detector in this order with the test it passed or failed, so the figure and the banner cannot disagree.
Every threshold in this calculator had, until now, been calibrated against another optical-density landmark. TDmulti's τ was set against TDstat, and TDuni's 20% against TDmulti — a chain with no external reference at any link. The 24 embedded time-kill experiments provide one, because they carry viable counts alongside the optical densities.
TDmulti is the best optical-density predictor of killing, and it is not the one that was trained to be. Mean absolute offset against the time at which viable counts fall to half their peak, across all 24 experiments:
| Landmark | n | mean |offset| |
|---|---|---|
| TDmulti | 24 | 4.46 min |
| TDuni | 23 | 7.98 min |
| Headline | 24 | 9.83 min |
| TDstat | 24 | 14.92 min |
TDstat, the landmark TDmulti was calibrated against and the one the manuscript rests on, is the weakest of the four. The Headline estimate, which prefers TDstat, is worse than TDmulti alone.
τ swept against the counts rather than against TDstat. Mean offset (a positive value means the kill landmark comes after TDmulti):
| τ | n | vs 50% drop | n | vs 1-log drop |
|---|---|---|---|---|
| 0.95 | 24 | +13.4 | 22 | +21.2 |
| 0.7 | 24 | +0.8 | 22 | +9.0 |
| 0.6 | 24 | −1.8 | 22 | +6.6 |
| 0.5 (current) | 24 | −4.1 | 22 | +4.4 |
| 0.3 | 22 | −6.9 | 21 | +1.5 |
| 0.2 | 20 | −7.8 | 19 | +0.1 |
τ can be aimed at a chosen depth of kill: about 0.65 to predict the 50% drop, about 0.2 to 0.3 to predict the 1-log drop. At τ = 0.3 the mean absolute offset from the 1-log time is 2.6 min with a standard deviation of 2.9, on a landmark that ranges from 45 to 120 min across the set. The correlation is r = 0.99. (Figures recomputed 2026-08-05 after the six T4 blocks were re-extracted in full from their workbooks: every one had been embedded with three or four CFU readings missing, which had removed the 1-log landmark from the 2025-12-09a pair entirely. At τ = 0.5 the 1-log correlation is now r = 0.989 across all 24 experiments rather than 0.987 across 22. On 2026-08-05 the remaining nine examples with available workbooks — the 2025-12-05a T4 pair and seven of the eight T1 runs — were re-extracted as well, all of them also truncated; every kill landmark is now measurable on all 24. Final values against the 2-fold, 1-log and 2-log drops: TDmulti r = 0.982, 0.989, 0.983 on 24 records each; ODmax 0.967, 0.975, 0.982 on 21; TDuni 0.814, 0.819, 0.831 on 23; TDstat 0.552, 0.581, 0.556 on 24.)
Three cautions, so that the claim is not made larger than the evidence.
1. This is the time OF decimal reduction, not the decimal reduction time. The two are different quantities with unhelpfully similar names. A D-value is an interval — how long a 1-log reduction takes once killing is under way. What is predicted here is the clock time at which viable counts have fallen tenfold, measured from the start of the experiment. Against the peak-to-1-log interval, which is the D-value analogue, TDmulti correlates at r = 0.77 rather than 0.99, and that interval itself ranges from 8.7 to 54.2 min across these experiments. The time of decimal reduction is what the data supports; DRT, the interval, is a different and weaker claim.
2. Much of the agreement is shared timing. The 1-log drop time correlates with the CFU peak time at r = 0.90, so 81% of its variance is variance the two landmarks share. Part of what TDmulti tracks is when the culture turned over, not the kill kinetics alone.
3. ODmax predicts the 2-log drop better than anything else, and should still not be trusted for it. Where a 100-fold reduction is reached, ODmax sits 2.0 min before it on average, mean absolute offset 3.2 min, r = 0.984 — tighter than TDmulti against the same landmark (8.1 min, r = 0.979). The objection is mechanistic, not statistical: ODmax is the moment turbidity stops rising, and anything postponing lysis without postponing killing — lysis inhibition above all — moves it while leaving viable counts where they were. These 24 experiments contain no strong lysis-inhibition case, so the agreement says little about the situation where it would matter most. Full set, against the 2-fold, 1-log and 2-log drops: ODmax r = 0.967, 0.970, 0.984; TDmulti 0.982, 0.987, 0.979; TDuni 0.814, 0.750, 0.706; TDstat 0.552, 0.652, 0.853.
4. Measurability falls with τ. 24 experiments contribute at τ = 0.6, 22 at 0.3 and 20 at 0.2, so the tightest figures rest on the fewest and most completely killed records. And τ was chosen from a sweep over these same 24 experiments, which is a calibration, not a validated prediction — the honest quantity to quote alongside it is the standard deviation, not the mean alone.
Eight substantive changes were made to the detectors in three days. Until now they existed only in the code, which meant the interface described behaviour the calculator no longer had. They are set out here in the order they matter to a reader of the numbers.
Names. The contact sheet and the manuscript call the four landmarks TDstat, TDmulti, DO and TDuni. This calculator has called the detectors Statistical, Multivariate, Alternative and Univariate, and the onset landmark “deviation onset”. They are the same four things: TDstat is Statistical Detection's crossing, TDmulti is Multivariate Detection's, TDuni is Univariate Detection's, and DO is deviation onset, which only the univariate path produces. Both vocabularies appear below; the subscripted forms are preferred in new text.
1. Slopes are stamped at the centre of the window they were fitted over. A rolling regression from i − w to i describes the middle of that span, not its right-hand edge. Labelling it ti made every multivariate landmark late by the centre-to-edge offset of its window. That offset is floor(slopeWin/2) sampling intervals, not half the window's duration: at the default the window is 9 intervals, so the offset is 4 intervals — 16 time units on 4-unit sampling, not the 18 that halving the span would suggest. The window is specified in time units so that it adapts to sampling rate, but its consequences have to be counted in points, because points are what the regression indexes.
2. TDstat aligns the two curves before comparing them. The ratio at time zero is instrument, not biology: the treated and control wells hold the same culture before the phage acts, so any gap there is a well-to-well difference. It is divided out on the mean of the first five ratios. Without this the test was true before the phage had done anything on a substantial fraction of records — on the T1 set, 49 of 121 begin more than 5% apart and 22 of those already sit below the 0.95 line.
3. TDstat is the headline TD. It compares optical densities directly, needs no slope window and therefore has no dead zone at the start of a record, and it is the definition the manuscript uses.
4. TDstat is now a fitted crossing (4 August). The test was made on the raw aligned ratio sample by sample, with the consecutive-sample requirement as its only protection. That rejects a single spike but not a shallow crossing, where wobbles of a few thousandths move the reported time by many minutes and one reading effectively sets the answer. Detection now runs on a short centred straight-line fit of the ratio, so several readings contribute to each tested value and to the crossing. The fit is centred rather than trailing, and its half-width is shrunk symmetrically at either end of the record, so no fitted value is displaced in time — a trailing fit would reintroduce the half-window lag that change 1 removed. Across 376 records the crossing moves by a median of 1.9 minutes and the two-sigma interval on it narrows from a median of 12.9 minutes to 4.1; records pinning their crossing to 20 minutes or better rise from 224 to 312. This is also what gives the window-size setting an honest job in this detector again: it sets the span of the fit.
5. The multivariate cutoff uses a running peak anchor. The yardstick is the fastest growth rate the control has reached so far, not its peak over the whole record. Anchoring to the global peak let the future set the threshold for the past: on the 121 T1 records that peak arrives after the deviation in 94 of them, by a median of 56 minutes, so a stated 5% threshold behaved like 11% at the median. The control's instantaneous slope was tried in its place on 4 August and rejected on measurement — see the note on record T5-2 below.
6. The slope window adapts to the sampling interval. It spans a target number of time units rather than a fixed number of samples, so that hand-collected runs sampled every 10 to 15 minutes are not over-smoothed and dense plate-reader runs are not under-smoothed.
7. The three thresholds are not commensurable. TDstat's threshold is a fraction of the control's optical density; TDmulti's is a fraction of the control's peak growth rate; TDuni's is a fraction of the treatment's own peak growth rate. Setting one number across all three compares nothing, and a single control that appeared to do so has been removed. Currently TDstat tests a 5% shortfall, TDmulti a 50% drop and TDuni a 20% drop, and those three numbers should not be read against one another.
8. Precision and accuracy are different questions. Precision is how tightly a record pins its own crossing — the two-sigma interval on the crossing time, from the scatter of the aligned ratio before deviation, inflated for autocorrelation and divided by the slope at which the curve crosses. Accuracy is whether that crossing can track killing at all, and it is set by the control. TDstat is a ratio, so it cannot register a shortfall until the control pulls away from a stalled treatment, and the time that takes is about 0.051 divided by the control's growth rate. A control doubling every 45 minutes reaches a 5% deficit within a few minutes; one doubling every 30 hours needs hours, by which time the killing being reported is long past. A record can be precise and inaccurate: block T1-98 pins a crossing at 330 minutes on a control doubling every 1308.
The rule behind most of these. Nearly every detector fault found in this period was one pattern: an extremum taken over too wide a span, reaching forward in time past the event it describes. The primary lysis window took the largest drawdown rather than the first, so on a culture that lyses, regrows and declines again it described the second event. TDuni's peak-slope anchor was captured by post-lysis regrowth. TDmulti's cutoff was anchored to a control peak that arrived after the deviation. The autocorrelation window ran past the crossing. ODmax was found on the way down on records with no rising limb. On a clean mid-log record with a single lysis these all coincide with the right answer, which is why they survived validation for so long. No landmark should be defined using data from after the event it describes.
A second rule: suppress at the source. A value that is not measurable should be null in the metric, not flagged for each consumer to check. Two consequences of applying it: ODmax is now null where the culture was at or past its maximum when recording began, and because every univariate landmark is measured from that rising limb, the univariate detector reports nothing at all on such a record rather than a plausible-looking number taken from the regrowth. On the 376-record set this removes ODmax from 63 records, DO from 27 and TDuni from 29, and adds none.
Record T5-2, and a diagnosis that did not survive testing. On T5-2 the treated culture stops accelerating but keeps growing while the control accelerates throughout, and TDmulti lands at 79.7 against TDstat at 38.8 and DO at 64, on a healthy control doubling every 57 minutes. This was attributed to the running peak anchor chasing the control upward, and the instantaneous control slope was implemented to remove it. It does not: on T5-2 the two anchors agree to a tenth of a minute, because a monotonically accelerating control has a running peak equal to its current slope by construction. The lateness comes from the threshold — at a 50% drop the treatment must fall to half the control's rate, which a culture that is still growing takes a long time to do. Across the whole set the instantaneous anchor also cost accuracy, and it was not kept. The episode is recorded because the wrong diagnosis was a reasonable one.
An interpolation defect found by that test. The crossing was interpolated against the cutoff taken at the end of the record while detection tested against the cutoff at each point — correct only while the anchor was a single number, and wrong from the moment it became a running peak. The crossing is now solved on the margin, slope minus cutoff, which is the quantity whose sign change defines the event, and clamped into the bracket it was solved within. It moves TDmulti earlier by a median of 8.9 minutes on the 219 records affected, and reduces landmarks falling after the culture's own fastest loss of optical density from 33 records to 27 for TDmulti and from 10 to 4 for TDuni. The τ = 0.5 calibration predates this correction and should be re-derived against time-kill data rather than re-tuned against these curves.
Note on the Multivariate cutoff. As of 2026-07-26 Multivariate detection uses no training window. The cutoff is set directly from the control curve: deviation is declared when d(ODtreatment)/dt falls below d(ODcontrol)/dt by more than (1 − τ) × the peak value of d(ODcontrol)/dt, with the peak taken over the first 75% of the record so that post-lysis regrowth cannot supply it. At the default τ = 0.95 this is a 5% margin, keeping TD numerically comparable with the Univariate and Statistical detectors. Detection additionally requires the drop to persist for at least five consecutive timepoints, and the reported time is the interpolated crossing of the cutoff. The rolling-slope regression spans a target of 36 time units rather than a fixed number of samples, so that hand-collected runs sampled every 10–15 min are not over-smoothed; on a 4-min plate-reader run this evaluates to nine intervals. A training-derived cutoff of the earlier form is retained solely as a fallback for records in which the control never achieves a positive growth rate.
Pre-deviation R² is reported for Univariate only. It measures how flat the slope series d(OD)/dt is during the pre-deviation period — for clean exponential growth this series should be nearly constant (≈ μ_peak rising slowly), giving high R². Low R² indicates the slope was not steady before deviation, which undermines the Univariate detection's premise. R² is not reported for Multivariate because Multivariate's relevant series is the slope-difference (treatment − control), which is expected to hover near zero. A linear regression of a near-zero series explains almost no variance, so its R² is structurally near 0 regardless of data quality. Reporting it would mislead more than inform.
Noise level (σ / peak slope) is reported for both Univariate and Multivariate and is directly comparable between them. It is the standard deviation of slope values in a ±5-point window around the peak slope, divided by the peak treatment slope. The peak window is where the slope is approximately constant, so SD there represents true noise (not the rising trend of exponential growth). Interpretation:
Multivariate combines noise from two independently noisy curves, so its noise level is typically higher than Univariate on the same data. (If the two curves share correlated noise — e.g., parallel temperature fluctuations — some common-mode noise cancels in the subtraction and Multi noise can be lower than Uni.)
Taking the logarithm of OD before computing the first derivative gives d(ln OD)/dt — which equals μ (the specific growth rate) when growth is truly exponential. Unlike d(OD)/dt, which rises continuously during exponential growth, d(ln OD)/dt should be flat during exponential growth.
This makes Panel B a powerful noise diagnostic. If Panel B is flat and horizontal, pre-deviation growth was cleanly exponential and Panel A detection is reliable. If Panel B is noisy, rising, or trending, then either:
In either case, Panel B noise warrants caution. However, the magnitude of the variation matters greatly — a y-axis spanning 0.0001 ln-OD units that appears dramatic is actually negligible biologically. This is the same phenomenon seen when graphing the OD of a sterile-broth control: the variation looks enormous on the graph, but the absolute values are trivially small. Always check the y-axis scale before concluding that Panel B noise is biologically meaningful. When Panel B noise is large in absolute terms (y-axis spanning a substantial fraction of μ), the Multivariate or Statistical approaches should be preferred.
True instantaneous derivatives require continuous functions. Real OD data is sampled at discrete timepoints. The calculator approximates the first derivative at each timepoint using ordinary least squares (OLS) linear regression over a short sliding window of 3 consecutive timepoints. The slope of that fitted line is the derivative estimate at the center timepoint.
This is called a finite difference approximation — standard practice in numerical analysis. The 3-point window is small enough to be locally responsive (capturing rapid changes) but large enough to reduce the impact of individual noisy readings.
Any noise visible in Panel B at early timepoints — where the flat line appears to wobble — reflects real measurement noise in the OD readings. At low OD values, small absolute fluctuations create large proportional changes in ln(OD), amplifying noise in the d(ln OD)/dt estimate. As OD builds, signal-to-noise improves and Panel B stabilizes.
Loading Example 4 (pure noiseless exponential growth, no deviation) demonstrates the theory:
Loading Example 5 (noiseless exponential with a sharp theoretical deviation at t = 120 min) shows:
Alongside the landmark-based detection approaches discussed above, this calculator also computes two whole-curve summary metrics from the literature: the Virulence Index (VI) of Storms et al. (2020) and the Centroid Index (CI) of Hosseini et al. (2024). Both are based on the area under the curve (AUC) and require a phage-free control curve for computation. They are included for compatibility with the existing literature and for users who wish to compare results to published work.
Raw AUC is computed by trapezoidal integration of (time, OD) over a defined window. The integration baseline is y = 0 (matching the conventions of both Storms 2020 and Hosseini 2024).
Virulence Index is defined as VI = 1 − (AUCtreatment / AUCcontrol). For an ideally effective phage that completely prevents bacterial growth, AUCtreatment = 0 and VI = 1. For a phage with no effect (treatment curve identical to control), VI = 0. VI does not consider when the area accumulates; only how much area accumulates overall.
Centroid Index uses the centroid (x̄, ȳ) of the region under each curve. The centroid coordinates carry information about both how much OD-mass accumulated (ȳ) and when in the experiment it accumulated (x̄). CI is defined as CI = 1 − (x̄t · ȳt) / (x̄c · ȳc). This makes CI sensitive to late regrowth: a treatment curve with substantial post-lysis bacterial regrowth has its centroid pulled toward later times (higher x̄), producing a lower CI even if the simple AUC ratio (VI) would be similar.
The classical use of VI and CI integrates from t = 0 to the end of the experiment. We additionally compute both indices over three landmark-anchored windows:
Plus a user-adjustable fifth window in the calculator interface, allowing free exploration of integration limits.
The windows often give quite different VI and CI values for the same data — illustrating directly the "limit selection" sensitivity that Ceballos and Stacy (2021) identify as a fundamental weakness of AUC-based metrics.
The lower anchor in landmark-anchored AUC windows is TD (threshold deviation) — the time at which d(OD)/dt has dropped by τ% from its peak. TD is used everywhere in the calculator as the universal deviation comparative for one practical reason: it is the only deviation estimator that can be produced by every detection approach this calculator supports. The Univariate approach can produce both DO (deviation onset, d²(OD)/dt² = 0) and TD; the Multivariate and Statistical approaches produce only TD; and the Sim Data tab's simulator produces only TD (its noise-free curves do not admit a meaningful Univariate calculus DO, since d²(OD)/dt² zero-crossing is ill-defined on a smooth curve). For cross-approach and cross-tab consistency, the only common landmark across all of these is TD, so TD is what the calculator uses as the AUC window anchor everywhere.
Mechanistically, TD is slightly later than DO: TD fires once the slope has dropped by τ% from its peak, while DO fires at the inflection (peak slope) itself. Both are valid "phage zero points" for AUC purposes; TD is simply the one with universal availability. On real Time-Kill data where Univariate also runs, DO and TD typically differ by half a sampling interval to a few sampling intervals depending on τ — small enough that the resulting VI and CI values are quite similar in either choice.
The conventional Storms 2020 and Hosseini 2024 implementations integrate from y = 0. Mathematically clean, but biologically the "from y = 0" choice means the AUC also includes the substantial OD that exists below the phage-attributable signal — the residual turbidity that any bacterial culture contributes simply by being present, plus the broth itself, plus any post-lysis floor that remains. A more biologically motivated baseline would be the minimum OD observed after phage activity has begun — i.e., the lysis floor, or whatever the curve settles to between deviation onset and end-of-lysis. Integrating from this baseline strips away the residual turbidity and measures only the area above the floor — the bacterial biomass that phage still has to deal with, in OD-time units.
The calculator offers four baseline modes via radio buttons at the top of the AUC card: (1) y = 0 (literature default), (2) y = min OD post-deviation (the biological baseline), (3) Show both (renders both tables side-by-side for comparison), and (4) User-defined (set by hand — useful, e.g., for the OD of sterile broth, around 0.04 in many systems). Non-zero baselines use clip-to-zero arithmetic: any region of the curve falling below the baseline contributes zero area, with the curve-baseline crossing point computed exactly via linear interpolation. This matches the "area above the floor" interpretation.
Like the window choice, the baseline choice is itself a free parameter — different baselines will give different VI and CI values, sometimes substantially so. The "Show both" mode makes this sensitivity directly visible. None of these choices has a single "right" answer; what they have are different biological interpretations.
VI and CI are whole-curve summary statistics. As such, they cannot distinguish bacterial killing from post-extinction regrowth of phage-resistant bacteria, they conflate multiple temporally distinct biological events (pre-deviation growth, deviation, lysis, post-lysis), and their values depend strongly on the integration window. Negative CI values can occur and are not errors — they indicate that the phage-treated curve had higher OD-weighted mass than the control, which typically signals substantial bacterial regrowth.
The landmark-based deviation framework that is the focus of this calculator addresses these limitations directly by identifying specific moments on the OD curve (deviation onset, lysis onset, end-of-lysis) rather than integrating across the whole curve. Deviation onset, in particular, is positioned closer in time to the actual phage-mediated bacterial-killing event than is any AUC-based metric. Nevertheless, VI and CI remain useful for cross-study comparison and as quick whole-curve summaries, and are provided here for those purposes.
References:
Supported formats: Excel (.xlsx, .xls) or CSV (.csv)
Data structure: Columns for Time, Control OD, and Treatment OD
Example: Time (min) | Control OD | Treatment OD
Drag and drop your data file, or click to select — spreadsheet, delimited text, or an analyzer JSON
Analyzing your data...
What the detectors found, and how much they agree. Populated when an analysis is run on the Analyzer tab, which is where the data, the columns and the parameters are chosen. Everything the run produced is below.
Parenthetical values shown alongside each landmark time are the corresponding treatment OD readings — e.g., "28.00 (0.150)" means at time 28 the OD value is 0.150. These are linearly interpolated between samples and provide visual reality checks for landmark placement.
| Metric | Univariate (uni) | Multivariate (multi) | Statistical (stat) |
|---|
Lysis inhibition delays lysis without changing how fast the phage population grew beforehand. That separation is why the deviation onset is the right place to stand: it is measured entirely before the inhibition takes effect, so a rate anchored there is unaffected by it, and any discrepancy that appears afterwards is the inhibition itself.
1. Geometric — how far the culture falls. An inhibited culture dips and recovers rather than collapsing. Measured on a nine-reading smoothed trace as the minimum after the first peak, divided by that peak.
2. Kinetic — how late it collapses for its rate. Steve's suggestion, and the more principled of the two. Predict the collapse time from the amplification rate, which is measured before the deviation, and take the residual. Inhibition delays lysis without altering that rate, so an inhibited record collapses later than its rate implies.
On the 329 BASEL records with both a rate and a collapse time, the two agree strongly. Records collapsing later than predicted fall to a median 83% of their peak; records collapsing on time fall to 11%. The residual tracks fall depth at ρ = +0.62.
Run against the labelled archive: T2, T4 and T6 inhibit; T1, T3 and T7 do not; r48 is T4 with rI knocked out and so does not inhibit either, which makes it the sharpest control available. T5 is the separate criterion. Balanced accuracy is quoted at each route's own best cut, which flatters all three.
| Route | Balanced accuracy | Labelled records | T5 called an inhibitor |
|---|---|---|---|
| 1. Depth of first fall | 0.719 | 105 / 168 | 19 of 19 (100%) |
| 2. Residual from the rate–collapse relationship | 0.826 | 100 / 158 | 59 of 73 (81%) |
| 3. The Collapse-to-T3L gap | 0.845 | 62 / 10 | 20 of 49 (41%) |
Route 1 fails on both counts, as expected, and worse than the 70% previously recorded: at its best cut it calls every one of the 19 T5 records an inhibitor. T5's falls are the shallowest of any phage in the archive and it does not inhibit.
Route 2's 0.826 is not what it appears to be. The rate–collapse relationship it takes residuals from has to be fitted separately in each corpus, because rpha is on a different scale in luminescence and in optical density — which already fails the third criterion. Worse, the relationship barely exists on the archive: ln(collapse) against ln(rpha) gives R2 = 0.373 on the 329 BASEL records and R2 = 0.027 on the 331 archive records. A residual taken from a fit with no predictive content is log(ODmax) with a constant subtracted, so what the classifier is really reporting is that T2, T4 and T6 reach ODmax later than T1, T3 and T7 do — true, and nothing to do with rate. The premise holds in BASEL and does not hold in the archive, and that difference is worth understanding before the route is pursued further.
Route 3 comes closest and cannot yet be tested. 0.845 is within reach of the bar, but it rests on ten negative records: T3L exists on only 7 of 121 T1, 1 of 52 T3, 0 of 58 T7 and 2 of 54 r48. A balanced accuracy computed against ten negatives is not a test of anything. And most of the information is carried by whether T3L exists at all — it is found on 62%, 66% and 76% of T2, T4 and T6 against 7–21% of the non-inhibitors — which is the two-peak detection that is already in the calculator, not a new signal. The gap itself is worth keeping, but it needs a corpus in which the non-inhibitors have a T3L to measure from.
T5 defeats all three routes, and that is the finding that matters most. It has the shallowest falls in the archive (median depth 12.5% against 38–68% for every other phage), it carries a T3L on 64% of its records — a rate matching the inhibitors — and it reaches ODmax late for its rate. Every geometric and kinetic signature of inhibition, in a phage that does not inhibit. Any classifier settled without T5 in the negative set will be settled on nothing.
Written before the work, as with the regrowth detector:
Analyze a set of OD curves simultaneously — one time column, N treatment columns, optional control column. Each curve is analyzed independently using Univariate detection (Multivariate when Univariate fails and a control is available). Results appear as a landmark table with one row per curve. Landmark definitions match the main Analyzer tab.
Specialized analysis for experiments combining optical density (OD) measurements with colony-forming unit (CFU) plating in the same run. Loads three curves — phage-free bacterial OD, with-phage OD, with-phage CFU — and addresses two distinct biological questions.
Question 1 — When did bacterial genetic killing occur? (time-kill, loss of colony-forming ability — the genetic / culturability sense of "killing"). The CFU drop is the ground truth: CFUs measure cells that can still divide. The report ranks OD-based candidates (deviation onset, deviation, ODmax, end-of-lysis) by how closely each matches the CFU 10× drop time. Deviation is the leading hypothesis here because, unlike ODmax or end-of-lysis, its timing captures the moment biomass accumulation in the phage-containing culture first lags the control — temporally upstream of any lysis-based observable.
Question 2 — How and when did phages affect bacterial structural wholeness? (cumulative lytic effect on culture biomass — the structural / physical sense of "impact"). This is a different biological question from Q1: cells can be genetically dead (Q1) long before they physically lyse (Q2). Phages first commit cells to death (deviation begins), then later lyse them (OD declines), and eventually extinction of turbidity (end-of-lysis). Q2 has both a temporal component (ODmax, end-of-lysis times) and a magnitude component (VI, CI — AUC-based scalars). There is no CFU equivalent for Q2 — CFU measures viable cells, not turbidity.
The literature has often conflated these two questions, treating AUC-based virulence as if it answers "when did killing happen." It does not — AUC produces a scalar, not a time. The CFU comparison in this report makes the distinction operationally clear.
A downloadable HTML report includes all inputs, outputs, charts, and AI-parsing metadata, suitable for archival, supplementary materials, or upload back to Claude for synthesis across experiments.
Paste data with this column structure (tab- or comma-separated; header row recommended):
Time | "B" OD | Time | "R" OD | Time | "R" CFUs [ | Time | "B" CFUs ]
Each curve may have its own time column (typical for plate-reader and manual experiments where readings are sequential). The first six columns are required; the optional columns 7–8 (B CFUs with their own time) are added if you also recorded phage-free CFU counts. The calculator accepts files with either six or eight columns.
Column meanings: "B" = phage-free bacterial culture; "R" = with-phage culture (R = reaction or resistance-testing); OD = optical density (any units); CFUs = colony-forming units per ml. When B CFUs are present, they're plotted alongside R CFUs on the CFU chart for direct visual comparison of the with-phage and phage-free CFU trajectories.
About the example datasets: Twenty-seven datasets organized as four phage groups (the fourth, three T1 runs at 5×10⁶ PFU, is hidden unless ?pfus=1). Phage T1 (Experiments 1–8): eight chronological single-phage experiments acquired between 2025-12-13 and 2025-12-16 in E. coli B. T1 has a short latent period (~5 min); the OD curve produces a clean lytic peak. These eight experiments establish that deviation onset on the OD curve corresponds to CFU 50% drop time with a mean absolute offset of about 3–5 minutes (n=8). Because T1's latent period is short, ODmax also corresponds reasonably to the CFU 10× drop (~1.6 min mean absolute offset) — this is an expected consequence of short latent period rather than evidence that ODmax is generally reliable. Phage T4 (Experiments 1–5, ten datasets): five paired experiments acquired between 2025-12-05 and 2025-12-12 (chronologically earlier than the T1 series but reported second because T4 introduces the more complex r48-vs-WT comparison) in E. coli B. Each T4 experiment compares T4 r48 (rapid-lysis mutant, short latent period, deep OD lysis trough) against T4 WT (longer latent period, frequently producing a plateau-and-rise OD profile without a clear lytic peak). These five paired experiments demonstrate that when latent period is longer and the OD curve lacks a clean lytic peak, ODmax fails by tens of minutes while deviation-based timings still track CFU killing within ~3–5 min. The within-experiment T4 r48-vs-WT difference in deviation onset is exactly 0.50 min in all five experiments — at the limit of OD sampling resolution — directly demonstrating that deviation captures the bacterial killing event (shared between r48 and WT) rather than the lysis event (which differs by tens of minutes). Together, the T1 and T4 datasets establish that deviation-based detection is latent-period-independent while ODmax-based detection is reliable only for short-latent-period phages. Phage T7 (Experiments 1–5, ongoing): five manual experiments in E. coli B recording paired Klett-Summerson turbidity readings (treated as OD-equivalent) and CFU counts on both control and treatment sides. The first three step the starting cell density upward (Klett ~30, ~50, ~70); Experiments 4 and 5 are replicates of Experiment 3’s Klett ~70 starting density, giving three replicates at that condition for explicit replicate-variability analysis (also exposed as Compare-tab presets). T7 has a long latent period; the OD curve produces a pronounced lytic peak followed by a sharp decline. The series steps the starting cell density upward across experiments to test whether the deviation-tracks-CFU result is robust to B₀: Experiment 1 started at Klett ~30 (deep lysis trough, Klett ~8-12; control in clean log-phase throughout); Experiment 2 started at Klett ~50 (shallow lysis trough, Klett ~43-50; control transitioning out of log-phase by deviation time; strong selection from t≈60 onward, ~3 h of post-strong-selection observation with no resistant-mutant regrowth visible); Experiment 3 started at Klett ~70 (modest trough, Klett ~64-66; control deeply in saturation phase by deviation time at t≈84-92). Together these three experiments span the spectrum from log-linear-control to saturated-control conditions, directly testing the framework's robustness to the control's growth regime. Late T7 CFU values below detection are shown as 1×10³ PFU/ml (Exp 1/2, 10⁻⁴ dilution scheme) or 1×10⁶ PFU/ml (Exp 3, different dilution at higher starting density) so they render on the log axis. T1 Experiments 1, 4, 5, 6, 7, 8 had below-detection CFU entries excluded; T4 Experiment 3 had spurious zero CFU entries removed. The data loaded by these buttons are the cleaned versions used in the manuscript analysis.
Overlay all experiments in a category onto a single chart, treating each data point as evidence in a single cloud. Lines vertical at the 50%-trimmed-mean deviation time across the category; the headline statistic — average viable cells lost relative to control at that deviation time — is rendered alongside. Manuscript-quality output suitable for direct figure use. Clicking a category button below loads each experiment in turn, runs deviation detection, and assembles the summary. Note: running a category will temporarily replace whatever's currently loaded in the Time-Kill paste area; the previous content is automatically restored once the summary finishes.
All 69 BASEL phages at five phage doses, from Mulla et al. (2025), with their reported collapse time shown against DO and ODmax computed here. Zoomable across the whole screen and orderable by any of the four quantities. These records carry no phage-free control, so TDuni is the only threshold deviation available on them.
Open the BASEL summary ↗ Open Rapid Analysis ↗Load several experiments (drop multiple files at once) to view their OD and CFU curves overlaid on one chart. Each experiment gets a distinct color; line style separates control (dashed) from treatment (solid); markers separate OD (line with dots) from CFU (filled circles). Useful for comparing replicates and for the manuscript's correlation case (deviation onset vs CFU drop timing across experiments).
Drop multiple Excel files at once, or load them one at a time. Each becomes a separate experiment on the overlay.
No experiments loaded yet.
The Phage OD Deviation Calculator implements three detection approaches, described in order from least to most complex. Each is described in the 💡 Concept tab; this tab covers operational details, output interpretation, and guidance on using the calculator effectively.
Univariate Detection operates on the treatment curve alone — no phage-free control is required. It computes the first derivative of OD with respect to time (d(OD)/dt, Panel A of Figure 1) at each timepoint using a short sliding-window OLS regression. During exponential growth this rises continuously; deviation is detected as the first sustained drop from the rising curve. Panel B (d(ln OD)/dt) serves as a noise diagnostic — a flat Panel B confirms clean exponential growth; a noisy Panel B warrants caution. Reliability is measured by the pre-deviation R² (Univariate only) and the noise level (σ/peak slope, comparable between Univariate and Multivariate).
Univariate Detection is most powerful when pre-deviation exponential growth spans a sufficient number of timepoints, and when deviation occurs while growth is still exponential, which is best achieved by starting experiments with log-phase bacteria that are adapted to experimental conditions. See the Concept tab for a discussion of experimental flexibility.
Multivariate Detection requires a phage-free control curve. At each timepoint it computes the first derivative d(OD)/dt (Panel A of Figure 2) for both treatment and control curves. When phage have no effect, both first derivatives track together on the rising curve. Deviation is detected as the first moment the treatment first derivative drops and stays below the control first derivative. Panel B (d(ln OD)/dt for both curves) serves as a noise diagnostic. No curve fitting or assumption about growth shape is required.
Multivariate Detection is most useful when pre-deviation growth is not cleanly exponential (low Univariate R² or high noise level), but the phage-free control curve provides a reliable empirical reference.
Statistical Detection requires a phage-free control curve. Unlike Univariate and Multivariate, it does not compute slopes or derivatives — it operates directly on OD values. At each treatment sample point, with the control curve linearly interpolated onto treatment sample times where the two time grids differ, it computes the ratio R(t) = ODtreatment(t) / ODcontrol(t). Detection triggers when this ratio falls below the threshold (default 0.95, meaning treatment OD is 5% below control OD) for at least minConsecutive consecutive sample points (default 2).
Interpolated threshold crossing. The reported deviation time is the linearly-interpolated time at which R(t) = threshold within the bracket [last-above-threshold sample, first-below-threshold sample] — not the time of the first-below sample. Linear interpolation of ODtreatment(t) and ODcontrol(t) between the bracketing samples gives the exact crossing time (solving T0 + f·(T1−T0) = threshold · [C0 + f·(C1−C0)] for f ∈ [0,1]). Without this interpolation Statistical would snap to the next sample after the crossing — a sub-minute difference for densely-sampled plate-reader data but a 5-15 minute error for manually-collected Klett data, large enough that the reported gap at the deviation time visibly exceeds the threshold value.
What Statistical answers vs Univariate / Multivariate. Statistical asks “when did treatment OD first fall below threshold × control OD?” — a direct comparison of OD values. Univariate and Multivariate ask “when did treatment growth rate first drop?” — a comparison of slopes. The two questions can give substantially different answers:
Parameter grid. Statistical's parameter sweep iterates over multiple window sizes (which here serve as settle-in skips against plate-reader warmup artifacts; with the OD-ratio test there is no smoothing) and over both raw and log-space comparisons. For the OD-ratio test these dimensions are essentially degenerate: log(T) − log(C) < log(threshold) is equivalent to T/C < threshold, and skipping initial settle-in samples doesn't change the eventual crossing time. All grid combinations should therefore converge to the same interpolated crossing. The stability of this convergence is itself a quality indicator — any disagreement across grid combinations reflects edge cases (control curve crossing zero, missing leading samples, post-saturation plateau).
What "0.95 ×μ_peak" means: A threshold of 0.95 means d(OD)/dt must drop below 95% of its peak value to register a sustained-drop event. This is a fraction of the peak first derivative — a multiplicative threshold against a known reference. The same notation now applies to both Univariate and Multivariate (sharing the unified 5%-drop threshold), where Multivariate's cutoff = pre-deviation mean − (1 − 0.95) × peak_treatment_slope, giving the threshold the same meaning of "5% drop from the treatment curve's peak first derivative."
ODmax for each approach: Univariate and Multivariate report the same interpolated zero-crossing of d(OD)/dt — a continuous, calculus-based estimate. Statistical does not use derivatives, so it reports ODmax as the discrete timepoint at which the maximum measured OD occurred — an actual data point. These two definitions agree closely but are not identical (the interpolated zero-crossing may fall between sampling intervals; the discrete max is snapped to a measured timepoint).
Deviation onset (= time of peak d(OD)/dt): Shown for both Univariate and Multivariate since both compute the first derivative of the treatment curve and find its peak. Mathematically, deviation onset is the zero-crossing of d²(OD)/dt² going from positive (growth accelerating) to negative (growth decelerating), which is equivalent to the time at which d(OD)/dt attains its maximum. The two values should match (same curve, same algorithm). Not applicable to Statistical, which doesn't compute derivatives. Caveat: on datasets where the bacterial culture exits mid-log phase before phage-induced lysis (e.g., long plate-reader runs with slow-acting phage), peak d(OD)/dt occurs during the natural deceleration of the host culture, not at the phage event. Univariate cannot distinguish these cases on its own; Multivariate, which uses the phage-free control curve to subtract out natural deceleration, is the appropriate approach for such datasets.
Pre-deviation R²: Shown for Univariate only. Measures how flat the d(OD)/dt slope series is during the pre-deviation period — high values (e.g. >0.85) indicate clean exponential growth and reliable detection; low values indicate that the treatment curve was not cleanly exponential before deviation. R² is not shown for Multivariate because Multivariate's regression-of-slope-differences metric is structurally low even for excellent data (see Math tab §4 for full explanation).
Noise level (σ / peak slope): A directly comparable noise metric for both Univariate and Multivariate. Computed as the standard deviation of slope values in a ±5-point window around the peak slope, divided by the peak slope. The window is positioned where the slope is approximately constant (at its maximum), so variation within it represents noise rather than the rising trend of exponential growth. Lower is better: ~0% = essentially noiseless; 5–10% = mild noise; 25%+ = noisy. Multivariate combines noise from two independently noisy curves, so its noise level is typically higher than Univariate on the same data.
Std dev (across methods): Shown only for Statistical Detection, where the threshold × window-size grid produces multiple deviation-time estimates whose spread is informative. For Univariate and Multivariate (which use a single shared 5% threshold), all methods within an approach return the same interpolated crossing time — the spread is zero by construction, which is not informative, so the row is omitted for those approaches.
AUC-based analysis (4th column): Three whole-curve summary metrics are computed alongside the landmark-based deviation detection: raw AUC (the trapezoidal area under each curve), Virulence Index (VI) per Storms et al. 2020, and Centroid Index (CI) per Hosseini et al. 2024. Each is computed over three integration windows: 0 → end of data (the traditional whole-experiment window), 0 → end-of-lysis (excludes post-extinction bacterial regrowth), and TD → end-of-lysis (isolates the phage-active phase, anchored at threshold deviation — the universal cross-approach deviation comparative used everywhere in this calculator). Raw AUC is always computed; VI and CI require a phage-free control curve. VI = 1 − (AUC_treat / AUC_ctrl), ranging from 0 (no impact) to 1 (perfect killing). CI = 1 − (x̄_t · ȳ_t) / (x̄_c · ȳ_c), additionally sensitive to when in the experiment the OD-mass was distributed (later mass — e.g., regrowth — penalizes the index). Negative CI values are displayed as-is and indicate the phage-treated curve had higher OD-weighted mass than the control (typically due to substantial bacterial regrowth). These AUC-based metrics are useful for comparison with the existing literature but have known limitations (whole-curve summaries cannot distinguish phage-mediated bacterial killing from later regrowth of phage-resistant bacteria; they conflate multiple temporally distinct biological events; and they depend strongly on the integration window). The landmark-based deviation detection in columns 2–4 addresses these limitations directly by isolating specific time points rather than integrating across the whole curve.
The results table shows four columns — Metric | Univariate | Multivariate | Statistical — for each curve analyzed. Deviation times for Univariate and Multivariate are computed using first-derivative (d(OD)/dt) interpolation and the halfway method described above. Pre-deviation R² (Univariate only) indicates how cleanly exponential pre-deviation growth was; noise level (σ/peak slope) is shown for both Univariate and Multivariate for direct comparison. When all three approaches agree closely, you have strong multi-method evidence for the deviation time. When they disagree, the pattern is informative:
If a reference curve is loaded it is automatically analyzed, and its results table appears directly below the treatment table for easy comparison.
The phage-bacterial OD curve is best understood as a sequence of three calculus landmarks, each marking a distinct biological event:
This calculator reports all three. The deviation onset is reported in two flavors: "earliest" (calculus-based midpoint) and "threshold" (interpolated 5%-drop crossing). Lysis onset is reported as both the interpolated zero-crossing (calculus-based) and the discrete OD maximum (data-based). End-of-lysis is reported as the midpoint of the bracket around the minimum d(OD)/dt.
Why threshold-based detection matters: The threshold-based deviation time (midpoint of the bracket where d(OD)/dt drops below threshold×μ_peak for ≥ minConsec consecutive points) serves two purposes: (1) it is directly comparable within an approach across experiments — since both Univariate and Multivariate use the same bracket-midpoint logic, threshold times from the same approach can be compared across datasets; (2) it is more robust than the "earliest" estimate for data that is continuous or nearly continuous, where the first derivative decreases gradually rather than dropping sharply — a threshold requirement prevents detecting trivially small initial drops. The "earliest" estimate (Univariate only) gives the theoretical lower bound but has no Multivariate equivalent because the difference series in Multivariate is doubly noisy.
Expected ordering of estimates: earliest ≤ threshold ≤ ODmax. The earliest estimate should never be later than the threshold estimate; the threshold estimate should never be later than ODmax (the zero-crossing). This ordering is mathematically expected: the "earliest" fires at the first drop from peak, the threshold fires only after a sustained drop, and ODmax is where the curve has already peaked. Violations of this ordering indicate data quality issues.
ODmax is defined as the time at which the first derivative d(OD)/dt crosses zero — computed by linear interpolation between the last timepoint where d(OD)/dt > 0 and the first timepoint where d(OD)/dt < 0. This gives a continuous time estimate, not restricted to a measured timepoint. The threshold-based deviation time is computed as the interpolated crossing time: linear interpolation between the last above-threshold and first below-threshold timepoints gives the exact time where d(OD)/dt crosses the threshold. This is a continuous estimate independent of the sampling interval — deviation is not forced to occur at a measured timepoint. The threshold and minimum-consecutive parameters are still used to confirm the sign change is real (not a single noisy point), but the reported time is always this midpoint.
Note: by default, these individual-method tables are hidden to reduce clutter; they are revealed on user request via the "Show Statistical Detection Method Details" toggle in the results display.
Green cards show Statistical Detection methods included in the trimmed mean; red cards show excluded outliers. Stat-raw and stat-ln methods are displayed in separate side-by-side grids. This transparency lets you assess consensus quality and identify any outlier parameter combinations.
Figure 1 shows two side-by-side panels for the treatment curve:
Vertical markers across both panels indicate the calculus-based "earliest" deviation (orange), the threshold-based deviation (green), ODmax (purple), and end-of-lysis (red). The same set of markers appears on Multivariate Figure 2 below.
The x-axis range can be adjusted via the X-min and X-max controls in the Figure 1 and Figure 2 toolbars; both endpoints synchronize across the two figures for direct comparison. X-min cuts off the early portion of the curve (the rising exponential phase); X-max cuts off the late portion (post-lysis). Useful for zooming in on the peak region when investigating ODmax divergence or end-of-lysis timing.
Traditional time-kill curves measure bacterial viability by plating at coarse intervals (typically 30 min to several hours). This coarseness is a feature when the goal is a qualitative distinction — culture alive vs. culture dead — and a limitation when the goal is precise timing. Time-kill methodology has traditionally all but abandoned timing precision in favor of robust binary outcome scoring.
OD-based deviation detection inverts this trade-off. Because OD is measured continuously and at high frequency, and because deviation timing is computed via interpolation rather than snapped to a measured timepoint, deviation gives a quantitative, sub-sampling-interval estimate of when phage killing first manifests in population dynamics. The "earliest" estimate captures the most sensitive possible detection; the "threshold" estimate (5% drop from peak) provides a more robust, consistent landmark that allows direct comparison across approaches and between datasets. Both are continuous in time.
An important caveat: deviation at threshold occurs later than the earliest detectable departure from exponential growth, and therefore corresponds to a state in which somewhat more bacteria have been productively infected than at the earliest point. Whether this matters depends on the question — for comparing phage-host pairs the threshold estimate is reproducible and comparable; for inferring the absolute earliest kinetics, the calculus-based "earliest" estimate is more sensitive.
Unless deviation is defined very late (e.g., at or near ODmax), deviation onset does not mean that all (or even a majority of) phage-sensitive bacteria have been infected. Rather, it marks some aspect of the start of that process — the moment when biomass accumulation in the phage-containing culture first measurably lags that of the phage-free control. By the time of deviation onset, only a fraction of bacteria may yet have been productively infected; the rest will be infected over the remaining course of the experiment.
Caveat: this interpretation may apply less directly to phages whose infection does not substantially impact bacterial replication rates during the infection — for such phages, deviation timing reflects more directly the timing of lysis itself than the timing of bacterial death-commitment.
An important consideration for Multivariate and Statistical Detection: when bacterial cultures are older at the point of deviation — i.e., the phage-free control curve has begun to deviate from clean exponential growth due to nutrient depletion, density-dependent slowing, or stationary-phase entry — it can take a very long time before the treatment curve reaches ODmax or undergoes the lysis-to-extinction transition. Multi and Statistical Detection compare treatment against a control whose own dynamics are no longer exponential, which complicates their interpretation. In such cases, Univariate Detection (which uses only the treatment curve and seeks its own inflection point) is often more reliable, since it does not require the control to be cleanly exponential at the deviation point.
When the calculator detects no deviation from exponential growth — that is, when the slope d(OD)/dt does not drop persistently below its peak value — this is itself an important diagnostic result, not a failure of detection. A no-deviation outcome strongly suggests one of:
The first interpretation — null phage impact — is biologically informative and worth reporting in its own right. In phage-bacterial screening, a clean "no deviation" outcome distinguishes ineffective phage-host pairs from those producing measurable killing, even before considering quantitative deviation timing.
Starting with log-phase (exponentially growing) bacteria produces cleaner pre-deviation OD curves and more reliable deviation detection. OD rises almost immediately from inoculation, the slope series reaches a clear plateau quickly, and there is less ambiguity about where the pre-deviation phase begins. A one- or two-timepoint instrument-settling artifact at t=0 is normal and does not affect detection.
Window sizes for Statistical Detection are automatically adjusted based on data spacing:
For questions, bug reports, or methodology discussions: deviation@phage.org
To cite this tool: Abedon, S.T. (2026). Phage OD Deviation Calculator. deviation.phage.org. 10.5281/zenodo.19023877
Additional manuscripts describing the computational methodology and validation of the Deviation approach are in preparation.
A precise account of how the Phage OD Deviation Calculator detects the three landmarks of the phage-bacterial OD curve — deviation onset, lysis onset (ODmax), and end-of-lysis — together with the quality metrics, parameters, and pseudocode, suitable for methods sections and peer review.
The calculator analyzes a phage-bacterial optical-density (OD) curve to extract three biologically meaningful landmarks corresponding to successive features of the second derivative d²(OD)/dt²:
Deviation onset is the operationally most informative landmark for inferring phage time-kill, since it precedes the latent-period delay inherent in lysis-based detection. All three landmarks are reported in the results table.
Three detection approaches are implemented for deviation onset: Univariate Detection (single-curve, first-derivative-based), Multivariate Detection (two-curve, first-derivative-based), and Statistical Detection (two-curve, OD-ratio test with interpolated crossing). All three are run when a phage-free control curve is provided; only Univariate Detection runs without one. Figures 1 and 2 in the Analyzer show Panel A (d(OD)/dt, used for detection) and Panel B (d(ln OD)/dt, noise diagnostic) for Univariate and Multivariate respectively.
Control and treatment OD time series are extracted from the uploaded file. If separate time columns are provided, the treatment series is interpolated onto the control time grid using linear interpolation. A minimum of 10 valid timepoints is required.
For all three approaches, local slopes are estimated using a 3-point sliding window of ordinary least-squares (OLS) linear regression. For a given window size W and timepoint i:
slope = (n·ΣxᵢYᵢ − ΣxᵢΣYᵢ) / (n·Σxᵢ² − (Σxᵢ)²) // OLS
For Univariate and Multivariate Detection, this window is fixed at 3 points. For Statistical Detection, window sizes target 15, 30, and 45 minutes of elapsed time.
Operates on the treatment curve alone. Detects the first inflection point of OD — equivalently, the peak of d(OD)/dt — and reports it in two flavors (earliest and threshold-based). Also computes lysis onset (zero-crossing of d(OD)/dt) and end-of-lysis (minimum of d(OD)/dt).
// Step 1: Compute d(OD)/dt at each timepoint (3-point OLS on raw OD) localSlope[i] = OLS slope of OD_treatment over points [i-3..i] // Also compute d(ln OD)/dt for noise diagnostic (Panel B) lnSlope[i] = OLS slope of ln(OD_treatment) over points [i-3..i] // Step 2: Training window = first 25% of timepoints fitEndIdx = floor(n × 0.25) // Step 3: Find peak d(OD)/dt in first 75% of data (= deviation onset landmark) μ_peak = max(localSlope[i] for i ≤ 0.75·n) t_peak = time at which μ_peak occurs // Step 3b: Zero-crossing of d(OD)/dt (= lysis onset = OD_max) t_lysisOnset = linear interpolation between last-positive and first-negative slope // Step 3c: Minimum of d(OD)/dt after lysis onset (= end-of-lysis) t_endOfLysis = midpoint of bracket around min(localSlope[i] for i > t_lysisOnset) // Step 4: Correlation coefficient R² of pre-peak slope series (quality metric) R² = flatness of slope series up to peak (0–1; higher = cleaner exponential growth) // Step 5: Detect first sustained drop below threshold × μ_peak // Thresholds: 0.75, 0.85, 0.95 × μ_peak // minConsecutive: 2, 3, ... (at least 2 required) // Report first timepoint of sustained run // Step 6: Trimmed mean across threshold × minConsecutive grid trimCount = ceil(n × 0.25) from each end uniMean = mean of included deviation times
Requires phage-free control curve. Detects when the slope of the difference between treatment and control ln-OD first drops persistently below zero.
// Step 1a: Compute d(OD)/dt for both curves (3-point OLS on raw OD) → Panel A treatLinSlope[i] = OLS slope of OD_treatment over points [i-3..i] ctrlLinSlope[i] = OLS slope of OD_control over points [i-3..i] // Step 1b: Compute d(ln OD)/dt for both curves → Panel B (noise diagnostic) lnDiff[i] = ln(OD_treatment[i]) − ln(OD_control[i]) diffSlope[i] = OLS slope of lnDiff over points [i-3..i] // Step 2: Reference scale = peak growth rate of the CONTROL peakCtrlSlope = max( d(OD_control)/dt ) over the first 75% of the record // The control is unaffected by phage, so the fastest rate at which it gains // optical density is the natural yardstick for "how far behind is treatment". // No training window is used, and none is needed: the cutoff does not depend // on any baseline estimate. // Step 3: Cutoff cutoff = −(1 − τ) × peakCtrlSlope // τ = 0.95 default, so −5% of peak // Read directly: fire when the treatment slope falls below the control slope // by more than 5% of the fastest rate the control ever achieves. // Step 4: Detect first sustained drop below cutoff // minConsecutive ≥ 5; report the interpolated crossing of the cutoff // Step 5: Trimmed mean across the minConsecutive grid
Revised 2026-07-26 — the training window has been removed. Earlier versions set the cutoff from the mean and standard deviation of the diff-slope series over a training window at the start of the record. That construction fails whenever deviation onset falls inside that window: the signal being detected inflates the σ that sets the detection threshold, so the threshold relaxes by exactly as much as the signal grows. Evaluation across 69 treatment/control pairs and 27 Time-Kill records with paired CFU counts showed the control-anchored cutoff above raising coverage from 0.78 to 1.00, titer-series ordering from 0.906 to 0.995, and correlation with 90% CFU decline from r = 0.799 to r = 0.914. The threshold remains at the conventional 5%, so TD stays directly comparable across Univariate, Multivariate and Statistical. A training-derived cutoff is retained only as a fallback for records in which the control never achieves a positive growth rate. See the 🧠 Concept tab for the accompanying discussion.
Requires phage-free control curve. Runs two sub-approaches (stat-raw and stat-ln) across a full parameter grid and takes a trimmed mean consensus.
// For each window size W ∈ {W₁₅, W₃₀, W₄₅}:
// For each threshold T ∈ {0.75, 0.85, 0.95}:
// For each minConsecutive C:
// Compute treatmentSlope[i] and controlSlope[i] (OLS over W points)
// ratio[i] = treatmentSlope[i] / controlSlope[i]
// Flag timepoint when: ratio < T AND controlSlope > 0
// Deviation = first timepoint of ≥ C consecutive flags
// → one method result per (W, T, C, approach)
// stat-raw: OLS on raw OD values (absolute growth rate)
// stat-ln: OLS on ln(OD) values (specific growth rate; skipped if any OD ≤ 0)
// Trimming per sub-approach:
sorted = methods.sort(ascending by deviationTime)
trimCount = ceil(n × 0.25)
included = sorted[trimCount … n − trimCount]
rawMean = mean(included stat-raw times)
lnMean = mean(included stat-ln times)
// Combined Statistical mean:
statMean = (rawMean + lnMean) / 2 // equal-weighted
| Parameter | Default | Derivation |
|---|---|---|
| Window sizes (W) | Auto: targets 15, 30, 45 min | max(3, round(target / avgSpacing)) |
| Thresholds | 0.75, 0.85, 0.95 | Fixed; user-adjustable ±0.05 |
| Min consecutive (C) | Auto: derived from window size | max(2, round(W / 4)) |
| Trim fraction | 25% from each end, per sub-approach | ceil(n × 0.25) independently |
| Control slope guard | controlSlope > 0 required | Prevents detection during flat/declining control |
To cite this tool: Abedon, S.T. (2026). Phage OD Deviation Calculator. deviation.phage.org. https://doi.org/10.5281/zenodo.19023877
Development preview — not yet publicly linked
This tab implements two functions for kinetic optical density-based phage titer estimation (KOTE assays). Calibration Generator: upload OD curves with known titers (at one, two, or three bacterial concentrations) to produce a reusable calibration JSON encoding the best-performing metrics and their regression parameters. Titer Estimator: load a calibration JSON and upload an unknown OD curve to obtain an ensemble titer estimate weighted across all qualifying metrics.
Upload one CSV per bacterial concentration. CSV format: first column
Time_min, then one column per known titer with the titer value
(PFU/ml) as the column header. Include a column headed 0 or
control for the no-phage control. Each OD value should be the
mean of technical replicates. Up to three bacterial concentrations supported.
Development preview — not publicly linked
Upload or paste output from a phage–bacteria population dynamics model. The calculator synthesizes a simulated culture density curve (B + infected cells), treats B(no phage) as the control, and applies the full deviation-detection algorithm — reporting all landmarks just as the Analyzer tab does for real OD data. All four model variables are plotted together on a shared axis (cells/ml or PFU/ml).
Coupled recurrence equations for phage-bacteria dynamics with delayed lysis (Bull, in preparation). Output TSV is in Jim's standard format and loads directly into the analysis pipeline below.
Sim Data JSON (canonical format, produced by this calculator or Jim's model):
{"model_parameters":{"k":…,"b":…,"L":…},"data":[{"time":…,"B_nophage":…,"B_uninfected":…,"Pf":…,"inf_cells":…},…]}
Jim-format TSV (auto-detected by k=…b=…L=… header line):
Row 1: model parameters · Row 2: column headers ·
Remaining rows: time=X.X B(no phage) = X B=X Pf=X inf_cells=X
Plain CSV or TSV — five columns, header row required:
time, B_nophage, B_uninfected, Pf, inf_cells (matched case-insensitively)
All concentrations assumed cells/ml (bacteria) or PFU/ml (free phage).
This tab analyzes simulation data across multiple initial phage densities (P₀). To use it: open the Sim Data tab and load a multi-titer Jim-format TSV file — one with multiple "Initial phage density = …" delimited blocks (e.g., the SA2.tsv format, which stacks six simulations at k, b, L fixed and steps P₀ through 10², 10³, 10⁴, 10⁵, 10⁶, 10⁷).
Once such data is loaded, this tab will display: