Fit growth models and extract growth statistics#

This tutorial demonstrates how to fit growth models and extract growth statistics using the growthcurves package.

The analysis workflow includes:

  1. Generating or loading growth data

  2. Fitting mechanistic models (ODE-based, parametric)

  3. Fitting phenomenological models (parametric and non-parametric)

  4. Extracting growth statistics from all fits

  5. Saving results for visualization

For preprocessing examples (blank subtraction, outlier detection, path length correction), see the companion notebook: preprocessing.ipynb.

For visualization of the results, see the companion notebook: plotting.ipynb (Visualize fitted growth curves, derivatives, and growth statistics)

from pprint import pprint

import numpy as np
import pandas as pd

import growthcurves as gc

Generate synthetic data#

This cell generates synthetic growth data from a clean logistic function.

  • time is modeled in hours, with measurements every 12 minutes (0.2 hours) for a total of 440 points (88 hours).

  • We assume a lag of 30 hours, an intrinsic growth rate of 0.15 hour⁻¹, and a carrying capacity of 0.45 OD.

Hide code cell source

# Generate synthetic growth data from logistic function
np.random.seed(42)

# Parameters for synthetic growth curve
n_points = 440
measurement_interval_minutes = 12
t = np.array([(measurement_interval_minutes * n) / 60 for n in range(n_points)])


def logistic_growth(t, N0, K, mu, lag):
    """Logistic growth model with smooth transition through lag phase"""
    # Standard logistic formula centered at lag time
    # This creates a smooth S-curve with inflection point at t = lag + (K - N0) / N0
    factor = (K - N0) / N0
    growth = K / (1 + factor * np.exp(-mu * (t - lag)))
    return growth, lag + np.log(factor) / mu


def get_logistic_growth_and_rate(t, K, N0, mu, lag):
    """
    Returns (Population, Growth_Rate) at time t.
    """
    p_t, _ = logistic_growth(t, N0, K, mu, lag)
    derivative = mu * p_t * (1 - (p_t / K))
    return p_t, derivative


# Example: At the inflection point (where P = K/2)
# log_der = mu * (1 - 0.5) = 0.5 * mu

# Generate clean logistic curve
K = 2.45
mu = 0.15
N0 = 0.05
lag = 10.0
ln_N, t_inflec = logistic_growth(t, N0=N0, K=K, mu=mu, lag=lag)

ax = pd.Series(ln_N, index=t).plot(
    title="Synthetic Growth Curve", xlabel="Time (hours)", ylabel="$ln(OD/N_0)$"
)
_ = ax.vlines(
    t_inflec,
    ymin=N0,
    ymax=K,
    color="red",
    linestyle="--",
)
der_inflec, p_inflec = mu * K / 4, (K / 2 + N0)
_ = ax.annotate(
    f"Inflection Point\nt={t_inflec:.2f}\n"
    f"$\\frac{{dP}}{{dt}}_{{inflection}}$={der_inflec:.5f}",
    xy=(t_inflec, p_inflec),
    xytext=(t_inflec + 2, 0.15),
    arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"),
)
delta_t = np.log(2 + np.sqrt(3)) / mu
t_accel, p_accel = t_inflec - delta_t, K * (0.5 - np.sqrt(3) / 6)
_ = ax.vlines(
    t_accel,
    ymin=N0,
    ymax=K,
    color="green",
    linestyle="--",
)
der_max = 1 / 6 * mu * K
_ = ax.annotate(
    f"Mu max\nt={t_accel:.2f}\n$\\frac{{dP}}{{dt}}_{{max}}$={der_max:.5f}",
    xy=(t_accel, p_accel),
    xytext=(t_accel - 22, 0.25),
    arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"),
)
doubling_time_at_inflection = np.log(2) / (mu * (1 - (p_accel) / K))
print(
    "Doubling time at maximum acceleration point "
    f"(t={t_accel:.2f}): {doubling_time_at_inflection:.2f} hours"
)

max_mu = mu * (1 - ((p_accel) / K))
print(
    "Maximum specific growth rate (mu_max of log curve)"
    f" at t={t_accel:.2f}: {max_mu:.5f} hour^-1"
)
Doubling time at maximum acceleration point (t=27.03): 5.86 hours
Maximum specific growth rate (mu_max of log curve) at t=27.03: 0.11830 hour^-1
../_images/541cee309a684a6d9ff253a5bb154fb07852a980feee9ac1cee2cf457c2fb963.png

If we go from logarithmic to linear space, the curve looks very similar, but the interpretation of the y-axis changed. Starting from linear space is recommended in practice.

N = N0 * np.exp(ln_N)

ax = pd.Series(N, index=t).plot(
    title="Synthetic Growth Curve", xlabel="Time (hours)", ylabel="OD"
)
_ = ax.vlines(
    t_inflec,
    ymin=N0,
    ymax=max(N),
    color="red",
    linestyle="--",
)
der_inflec, p_inflec = mu * K / 4, (K / 2 + N0)
_ = ax.annotate(
    (
        f"Inflection Point\nt={t_inflec:.2f}\n"
        # f"$\\frac{{dP}}{{dt}}_{{inflection}}$={der_inflec:.5f}"
    ),
    xy=(t_inflec, 0.063),
    xytext=(t_inflec + 2, 0.055),
    arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"),
)
delta_t = np.log(2 + np.sqrt(3)) / mu
t_accel, p_accel = t_inflec - delta_t, K * (0.5 - np.sqrt(3) / 6)
_ = ax.vlines(
    t_accel,
    ymin=N0,
    ymax=max(N),
    color="green",
    linestyle="--",
)
der_max = 1 / 6 * mu * K
_ = ax.annotate(
    (
        f"Mu max\nt={t_accel:.2f}"
        # f"\n$\\frac{{dP}}{{dt}}_{{max}}$={der_max:.5f}"
    ),
    xy=(t_accel, 0.055),
    xytext=(t_accel - 22, 0.06),
    arrowprops=dict(arrowstyle="->", connectionstyle="arc3,rad=.2"),
)
doubling_time_at_inflection = np.log(2) / (mu * (1 - (p_accel) / K))
print(
    "Doubling time at maximum acceleration point "
    f"(t={t_accel:.2f}): {doubling_time_at_inflection:.2f} hours"
)

max_mu = mu * (1 - ((p_accel) / K))
print(
    "Maximum specific growth rate (mu_max of log curve)"
    f" at t={t_accel:.2f}: {max_mu:.5f} hour^-1"
)
Doubling time at maximum acceleration point (t=27.03): 5.86 hours
Maximum specific growth rate (mu_max of log curve) at t=27.03: 0.11830 hour^-1
../_images/78a4456d3fbae3ffdb6857ba6275fe6694009ee9c2d333952fcb25f54f534c47.png

How Growth Parameters Are Calculated#

The table below summarizes how the main reported growth statistics are calculated across model classes.

Output key

Meaning

How it is calculated

max_od

Maximum observed/fitted OD

Maximum OD over the valid data range

mu_max

Maximum specific growth rate (μ_max)

Maximum of d(ln N)/dt from the fitted model (or local fit for non-parametric)

intrinsic_growth_rate

Intrinsic model rate parameter

For mechanistic models: fitted intrinsic μ; for phenomenological/non-parametric: None

doubling_time

Doubling time in hours

ln(2) / mu_max

time_at_umax

Time at maximum specific growth

Time where mu_max reaches its maximum

od_at_umax

OD at time of μ_max

Model-predicted OD at time_at_umax

exp_phase_start, exp_phase_end

Exponential phase boundaries

From threshold or tangent phase-boundary method in extract_stats()

model_rmse

Fit error

RMSE between observed OD and model-predicted OD over the model fit window

For this tutorial:

  • Mechanistic comparisons use mechanistic parametric fits.

  • Phenomenological comparisons include both phenomenological parametric and non-parametric fits.

Extract growth stats from the dataset#

The extract_stats_from_fit() function calculates these key metrics:

  • max_od: Maximum OD value within the fitted window

  • mu_max: Observed maximum specific growth rate μ_max (hour⁻¹) - calculated from the fitted curve

  • intrinsic_growth_rate: Model parameter for intrinsic growth rate (parametric models only, None for non-parametric)

  • doubling_time: Time to double the population at peak growth (hours)

  • exp_phase_start: When exponential phase begins (hours)

  • exp_phase_end: When exponential phase ends (hours)

  • time_at_umax: Time when μ reaches its maximum (hours)

  • od_at_umax: OD value at time of maximum μ

  • fit_t_min: Start of fitting window (hours)

  • fit_t_max: End of fitting window (hours)

  • fit_method: Identifier for the method used

  • model_rmse: Root mean squared error

Descriptive parameters are extracted from the fits. Where parameters are not extracted directly from the fitted model, they are calculated. The table below shows how different stats are calculated according to the different approaches:

MECHANISTIC MODELS#

Use linear space (N(t)) to fit the mechanistic models.

Name

Model

Equation

Exp Start

Exp End

Intrinsic μ

μ max

Carrying Capacity

Fit

Logistic

parametric

dN/dt = μ * (1 - N(t) / K) * N(t)

threshold/
tangent

threshold/
tangent

μ

max dln(N)/dt

K

entire curve

Gompertz

parametric

dN/dt = μ * math.log(K / N(t)) * N(t)

threshold/
tangent

threshold/
tangent

μ

max dln(N)/dt

K

entire curve

Richards

parametric

dN/dt = μ * (1 - (N(t) / K)**beta) * N(t)

threshold/
tangent

threshold/
tangent

μ

max dln(N)/dt

A

entire curve

Baranyi

parametric

dN/dt= μ * math.exp(μ * t) / (math.exp(h0) - 1 + math.exp(μ * t)) * (1 - N(t) / K) * N(t)

threshold/
tangent

threshold/
tangent

μ

max dln(N)/dt

K

entire curve

try transposed display

Name

Logistic

Gompertz

Richards

Baranyi

type

parametric

parametric

parametric

parametric

Equation

dN/dt = μ * (1 - N(t) / K) * N(t)

dN/dt = μ * math.log(K / N(t)) * N(t)

dN/dt = μ * (1 - (N(t) / K)**beta) * N(t)

dN/dt= μ * math.exp(μ * t) / (math.exp(h0) - 1 + math.exp(μ * t)) * (1 - N(t) / K) * N(t)

Exp Start

threshold/
tangent

threshold/
tangent

threshold/
tangent

threshold/
tangent

Exp End

threshold/
tangent

threshold/
tangent

threshold/
tangent

threshold/
tangent

Intrinsic μ

μ

μ

μ

μ

μ max

max dln(N)/dt

max dln(N)/dt

max dln(N)/dt

max dln(N)/dt

Carrying Capacity

K

K

A

K

Fit

entire curve

entire curve

entire curve

entire curve

PHENOMENOLOGICAL MODELS#

Use log space (ln(N(t)/N0)) to fit the phenomenological models.

Name

Model

Equation

Exp Start

Exp End

Intrinsic μ

μ max

Max OD

Fit

Linear

non-parametric

ln(N(t)) = N0 + b * t

threshold/
tangent

threshold/
tangent

n.a.

b

max OD raw

only window

Spline

non-parametric

ln(N(t)) = spline(t)

threshold/
tangent

threshold/
tangent

n.a.

max of derivative of spline

max OD raw

entire curve

Logistic (phenom)

parametric

ln(N(t)/N0) = A / (1 + exp(4 * μ_max * - t) / A + 2))

λ

threshold/
tangent

n.a.

μ_max

K

entire curve

Gompertz (phenom)

parametric

ln(N(t)/N0) = A * exp(-exp(μ_max * exp(1) * - t) / A + 1))

λ

threshold/
tangent

n.a.

μ_max

K

entire curve

Gompertz (modified)

parametric

ln(N(t)/N0) = A * exp(-exp(μ_max * exp(1) * - t) / A + 1)) + A * exp(α * (t - t_shift))

λ

threshold/
tangent

n.a.

μ_max

K

entire curve

Richards (phenom)

parametric

ln(N(t)/N0) = A * (1 + ν * exp(1 + ν + μ_max * (1 + ν)**(1/ν) * - t) / A))**(-1/ν)

λ

threshold/
tangent

n.a.

μ_max

K

entire curve

Understanding Growth Rates: Intrinsic vs. Observed#

Important distinction:

  • mu_max (μ_max): The observed maximum specific growth rate calculated from the fitted curve as max(d(ln N)/dt). This is what you measure from the data.

  • intrinsic_growth_rate: The model parameter representing intrinsic growth capacity:

    • Parametric models: This is a fitted parameter (e.g., r in Logistic, mu_max in Gompertz)

    • Non-parametric methods: Returns None (no model parameter exists)

Mechanistic Models#

Mechanistic models are ODE-based parametric models that encode growth dynamics as differential equations.

Fit Models#

# Fit mechanistic models
fit_mech_logistic = gc.parametric.fit_parametric(t, ln_N, method="mech_logistic")
fit_mech_gompertz = gc.parametric.fit_parametric(t, ln_N, method="mech_gompertz")
fit_mech_richards = gc.parametric.fit_parametric(t, ln_N, method="mech_richards")
fit_mech_baranyi = gc.parametric.fit_parametric(t, ln_N, method="mech_baranyi")

# Combine fits into a dictionary
mechanistic_fits = {
    "mech_logistic": fit_mech_logistic,
    "mech_gompertz": fit_mech_gompertz,
    "mech_richards": fit_mech_richards,
    "mech_baranyi": fit_mech_baranyi,
}

# Display example fit result
print("=== Logistic Fit Result ===")
pprint(fit_mech_logistic, indent=2)
=== Logistic Fit Result ===
{ 'model_type': 'mech_logistic',
  'params': { 'K': np.float64(2.4495516323928404),
              'N0': np.float64(0.011341689051871499),
              'fit_t_max': 87.8,
              'fit_t_min': 0.0,
              'mu': np.float64(0.14996304571978236)}}

Extract Growth Statistics#

# Extract stats from each mechanistic fit
stats_mech_logistic = gc.inference.extract_stats(fit_mech_logistic, t, ln_N)
stats_mech_gompertz = gc.inference.extract_stats(fit_mech_gompertz, t, ln_N)
stats_mech_richards = gc.inference.extract_stats(fit_mech_richards, t, ln_N)
stats_mech_baranyi = gc.inference.extract_stats(fit_mech_baranyi, t, ln_N)

# Combine stats into a dictionary
mechanistic_stats = {
    "mech_logistic": stats_mech_logistic,
    "mech_gompertz": stats_mech_gompertz,
    "mech_richards": stats_mech_richards,
    "mech_baranyi": stats_mech_baranyi,
}

# Display growth statistics for logistic fit
print("=== Logistic Growth Statistics ===")
pprint(stats_mech_logistic, indent=2)

# Create comparison dataframe
print("\n=== Mechanistic Models Comparison ===")
mechanistic_df = pd.DataFrame(mechanistic_stats).T[
    [
        "mu_max",
        "intrinsic_growth_rate",
        "doubling_time",
        "time_at_umax",
        "exp_phase_start",
        "exp_phase_end",
        "model_rmse",
    ]
]
mechanistic_df.T
=== Logistic Growth Statistics ===
{ 'N0': 0.011341689051871499,
  'doubling_time': 4.574975589334522,
  'exp_phase_end': 47.27876666305249,
  'exp_phase_start': 0.0,
  'fit_method': 'model_fitting_mech_logistic',
  'fit_t_max': 87.8,
  'fit_t_min': 0.0,
  'intrinsic_growth_rate': 0.14996304571978236,
  'max_od': 2.4495516323928404,
  'model_rmse': 0.0003798064158688436,
  'mu_max': 0.15150838884820603,
  'od_at_umax': 0.011341689051871499,
  'time_at_umax': 0.0}

=== Mechanistic Models Comparison ===
mech_logistic mech_gompertz mech_richards mech_baranyi
mu_max 0.151508 0.286745 0.151749 0.151508
intrinsic_growth_rate 0.149963 0.044568 0.150234 0.149963
doubling_time 4.574976 2.417299 4.567735 4.574976
time_at_umax 0.0 0.0 0.0 0.0
exp_phase_start 0.0 0.0 0.0 0.0
exp_phase_end 47.278767 42.028476 47.353533 47.278767
model_rmse 0.00038 0.287891 0.002854 0.00038

Phenomenological Models - Parametric#

These are phenomenological parametric models fit in ln-space.

Fit Models#

# Fit phenomenological parametric models
fit_phenom_logistic = gc.parametric.fit_parametric(t, ln_N, method="phenom_logistic")
fit_phenom_gompertz = gc.parametric.fit_parametric(t, ln_N, method="phenom_gompertz")
fit_phenom_gompertz_modified = gc.parametric.fit_parametric(
    t, ln_N, method="phenom_gompertz_modified"
)
fit_phenom_richards = gc.parametric.fit_parametric(t, ln_N, method="phenom_richards")

# Combine fits into a dictionary
phenom_param_fits = {
    "phenom_logistic": fit_phenom_logistic,
    "phenom_gompertz": fit_phenom_gompertz,
    "phenom_gompertz_modified": fit_phenom_gompertz_modified,
    "phenom_richards": fit_phenom_richards,
}

# Display example fit
print("=== Phenomenological Logistic Fit ===")
pprint(fit_phenom_logistic, indent=2)
pprint("\n=== Phenomenological Richards Fit ===")
pprint(fit_phenom_richards, indent=2)
pprint("\n=== Phenomenological Gompertz Fit ===")
pprint(fit_phenom_gompertz, indent=2)
pprint("\n=== Phenomenological Modified Gompertz Fit ===")
pprint(fit_phenom_gompertz_modified, indent=2)
=== Phenomenological Logistic Fit ===
{ 'model_type': 'phenom_logistic',
  'params': { 'A': np.float64(2.4499999999999997),
              'fit_t_max': 87.8,
              'fit_t_min': 0.0,
              'lam': np.float64(22.47467340605259),
              'mu_max': np.float64(0.09187499999999979)}}
'\n=== Phenomenological Richards Fit ==='
{ 'model_type': 'phenom_richards',
  'params': { 'A': np.float64(2.4499999999999993),
              'fit_t_max': 87.8,
              'fit_t_min': 0.0,
              'lam': np.float64(22.474673406052688),
              'mu_max': np.float64(0.09187499999999946),
              'nu': np.float64(1.000000000000007)}}
'\n=== Phenomenological Gompertz Fit ==='
{ 'model_type': 'phenom_gompertz',
  'params': { 'A': np.float64(2.5017092939443906),
              'fit_t_max': 87.8,
              'fit_t_min': 0.0,
              'lam': np.float64(21.517860012689678),
              'mu_max': np.float64(0.09115567652957923)}}
'\n=== Phenomenological Modified Gompertz Fit ==='
{ 'model_type': 'phenom_gompertz_modified',
  'params': { 'A': np.float64(1.424018685129793),
              'alpha': np.float64(0.02232389347101253),
              'fit_t_max': 87.8,
              'fit_t_min': 0.0,
              'lam': np.float64(27.802350159942915),
              'mu_max': np.float64(0.11167982988745084),
              't_shift': np.float64(87.79999999999998)}}

Extract Growth Statistics#

# Extract stats from each phenomenological parametric fit
stats_phenom_logistic = gc.inference.extract_stats(
    fit_phenom_logistic, t, ln_N, phase_boundary_method="tangent"
)
stats_phenom_gompertz = gc.inference.extract_stats(
    fit_phenom_gompertz, t, ln_N, phase_boundary_method="tangent"
)
stats_phenom_gompertz_modified = gc.inference.extract_stats(
    fit_phenom_gompertz_modified, t, ln_N, phase_boundary_method="tangent"
)
stats_phenom_richards = gc.inference.extract_stats(
    fit_phenom_richards, t, ln_N, phase_boundary_method="tangent"
)

# Combine stats into a dictionary
phenom_param_stats = {
    "phenom_logistic": stats_phenom_logistic,
    "phenom_gompertz": stats_phenom_gompertz,
    "phenom_gompertz_modified": stats_phenom_gompertz_modified,
    "phenom_richards": stats_phenom_richards,
}

# Display example stats
print("=== Phenomenological Logistic Stats ===")
pprint(stats_phenom_logistic, indent=2)

# Create comparison dataframe
print("\n=== Phenomenological Parametric Models Comparison ===")
phenom_param_df = pd.DataFrame(phenom_param_stats).T[
    [
        "mu_max",
        "intrinsic_growth_rate",
        "doubling_time",
        "time_at_umax",
        "exp_phase_start",
        "exp_phase_end",
        "model_rmse",
    ]
]
phenom_param_df.T
=== Phenomenological Logistic Stats ===
{ 'N0': nan,
  'doubling_time': 7.544459108135476,
  'exp_phase_end': 58.508066846718286,
  'exp_phase_start': 22.47467340605259,
  'fit_method': 'model_fitting_phenom_logistic',
  'fit_t_max': 87.8,
  'fit_t_min': 0.0,
  'intrinsic_growth_rate': None,
  'max_od': 2.448995355074426,
  'model_rmse': 1.0880301597790466e-15,
  'mu_max': 0.09187499999999979,
  'od_at_umax': 0.011336238243933507,
  'time_at_umax': 0.0}

=== Phenomenological Parametric Models Comparison ===
phenom_logistic phenom_gompertz phenom_gompertz_modified phenom_richards
mu_max 0.091875 0.091156 0.11168 0.091875
intrinsic_growth_rate None None None None
doubling_time 7.544459 7.603994 6.206557 7.544459
time_at_umax 0.0 0.0 29.735872 0.0
exp_phase_start 22.474673 21.51786 27.80235 22.474673
exp_phase_end 58.508067 87.8 43.316863 58.508067
model_rmse 0.0 0.050251 0.161893 0.0

Phenomenological Models - Non-Parametric#

These are phenomenological non-parametric fits that estimate growth features directly from local trends and smoothing.

For spline fitting, use smooth to choose smoothing behavior:

  • smooth="fast" (default): auto-default lambda rule

  • smooth="slow": weighted GCV smoothing

  • smooth=<float>: manual lambda value

Fit Models#

# Fit non-parametric models

# Spline supports smooth="fast" (default), smooth="slow", or a manual float.
fit_spline = gc.non_parametric.fit_non_parametric(
    t,
    ln_N,
    method="spline",
    smooth="fast",
)

# Example manual smoothing value:
# fit_manual = gc.non_parametric.fit_non_parametric(t, ln_N, method="spline", smooth=0.5)

fit_sliding_window = gc.non_parametric.fit_non_parametric(
    t,
    ln_N,
    method="sliding_window",
    window_points=7,
)

# Combine fits into a dictionary
phenom_nonparam_fits = {
    "spline": fit_spline,
    "sliding_window": fit_sliding_window,
}

# Display non-parametric fit results
pprint(phenom_nonparam_fits, indent=2)
{ 'sliding_window': { 'model_type': 'sliding_window',
                      'params': { 'fit_t_max': 1.2,
                                  'fit_t_min': 0.0,
                                  'intercept': -4.479738585450681,
                                  'slope': 0.14924053473188278,
                                  'time_at_umax': 0.6,
                                  'window_points': 7}},
  'spline': { 'model_type': 'spline',
              'params': { 'fit_t_max': 87.8,
                          'fit_t_min': 0.0,
                          'mu_max': 0.14929995999407364,
                          'smooth': 'fast',
                          'spline_s': 1.881415714560523e-07,
                          'tck_c': [ -4.479750760109631,
                                     -4.46979742944336,
                                     -4.449890768110815,
                                     -4.420036155591577,
                                     -4.390185644709152,
                                     -4.360339744408421,
                                     -4.330498490551317,
                                     -4.300662050704768,
                                     -4.270830562475359,
                                     -4.241004176917491,
                                     -4.211183047077068,
                                     -4.181367331218917,
                                     -4.151557192129859,
                                     -4.121752797476377,
                                     -4.091954319884778,
                                     -4.062161937100348,
                                     -4.032375832130291,
                                     -4.002596193395992,
                                     -3.972823214887887,
                                     -3.94305709632488,
                                     -3.9132980433178637,
                                     -3.883546267537611,
                                     -3.853801986887077,
                                     -3.8240654256782,
                                     -3.7943368148133247,
                                     -3.7646163919713076,
                                     -3.734904401798434,
                                     -3.7052010961042017,
                                     -3.6755067340621137,
                                     -3.645821582415522,
                                     -3.6161459156886617,
                                     -3.586480016402934,
                                     -3.5568241752985554,
                                     -3.527178691561657,
                                     -3.4975438730569066,
                                     -3.467920036565773,
                                     -3.4383075080304946,
                                     -3.4087066228038547,
                                     -3.379117725904818,
                                     -3.3495411722801625,
                                     -3.3199773270721016,
                                     -3.290426565892059,
                                     -3.2608892751005962,
                                     -3.231365852093594,
                                     -3.201856705594747,
                                     -3.172362255954387,
                                     -3.1428829354547667,
                                     -3.11341918862174,
                                     -3.0839714725429834,
                                     -3.0545402571926963,
                                     -3.025126025762862,
                                     -2.995729275001062,
                                     -2.9663505155548275,
                                     -2.9369902723225736,
                                     -2.9076490848110206,
                                     -2.878327507499159,
                                     -2.8490261102086496,
                                     -2.8197454784806255,
                                     -2.790486213958859,
                                     -2.761248934779143,
                                     -2.7320342759648413,
                                     -2.702842889828467,
                                     -2.6736754463791526,
                                     -2.6445326337358637,
                                     -2.61541515854616,
                                     -2.586323746410337,
                                     -2.557259142310684,
                                     -2.5282221110456575,
                                     -2.4992134376686583,
                                     -2.47023392793113,
                                     -2.4412844087296586,
                                     -2.4123657285566864,
                                     -2.3834787579544825,
                                     -2.3546243899719252,
                                     -2.3258035406236375,
                                     -2.2970171493509883,
                                     -2.2682661794844377,
                                     -2.2395516187066096,
                                     -2.210874479515542,
                                     -2.182235799687398,
                                     -2.1536366427379723,
                                     -2.125078098382228,
                                     -2.0965612829910927,
                                     -2.0680873400446136,
                                     -2.0396574405806533,
                                     -2.011272783638101,
                                     -1.9829345966936458,
                                     -1.9546441360910416,
                                     -1.9264026874617162,
                                     -1.8982115661356136,
                                     -1.8700721175409614,
                                     -1.8419857175917351,
                                     -1.8139537730614128,
                                     -1.7859777219416346,
                                     -1.7580590337842759,
                                     -1.730199210025382,
                                     -1.702399784289373,
                                     -1.6746623226718342,
                                     -1.6469884239991759,
                                     -1.6193797200633446,
                                     -1.5918378758297573,
                                     -1.5643645896165108,
                                     -1.536961593242928,
                                     -1.5096306521453717,
                                     -1.4823735654582808,
                                     -1.4551921660582532,
                                     -1.428088320569035,
                                     -1.4010639293251461,
                                     -1.3741209262919176,
                                     -1.347261278939612,
                                     -1.3204869880693066,
                                     -1.2938000875881979,
                                     -1.2672026442319406,
                                     -1.2406967572316756,
                                     -1.2142845579233283,
                                     -1.187968209296857,
                                     -1.1617499054830638,
                                     -1.1356318711756659,
                                     -1.1096163609863372,
                                     -1.0837056587304845,
                                     -1.0579020766415916,
                                     -1.0322079545120213,
                                     -1.0066256587582934,
                                     -0.9811575814088849,
                                     -0.9558061390128173,
                                     -0.9305737714673185,
                                     -0.9054629407630921,
                                     -0.8804761296458078,
                                     -0.8556158401926669,
                                     -0.8308845923030611,
                                     -0.8062849221025639,
                                     -0.7818193802597119,
                                     -0.7574905302153123,
                                     -0.7333009463242303,
                                     -0.7092532119099214,
                                     -0.685349917232266,
                                     -0.6615936573695413,
                                     -0.6379870300157523,
                                     -0.6145326331948072,
                                     -0.591233062893444,
                                     -0.5680909106151131,
                                     -0.5451087608574616,
                                     -0.5222891885163813,
                                     -0.4996347562200118,
                                     -0.47714801159648046,
                                     -0.4548314844795347,
                                     -0.4326876840566426,
                                     -0.41071909596453865,
                                     -0.3889281793375388,
                                     -0.3673173638144131,
                                     -0.34588904650989244,
                                     -0.3246455889573354,
                                     -0.3035893140293519,
                                     -0.28272250284359063,
                                     -0.2620473916611424,
                                     -0.24156616878535392,
                                     -0.2212809714690588,
                                     -0.2011938828385281,
                                     -0.18130692884258046,
                                     -0.1616220752355037,
                                     -0.1421412246025652,
                                     -0.12286621343695171,
                                     -0.1037988092770752,
                                     -0.08494070791315542,
                                     -0.06629353067196625,
                                     -0.04785882178855778,
                                     -0.02963804587363081,
                                     -0.01163258548506658,
                                     0.00615626118809411,
                                     0.0237272825212178,
                                     0.04107935552148068,
                                     0.05821144775975211,
                                     0.07512261916004288,
                                     0.09181202363999057,
                                     0.10827891059639205,
                                     0.12452262623028307,
                                     0.14054261470662482,
                                     0.15633841914426608,
                                     0.17190968243243382,
                                     0.18725614787067055,
                                     0.20237765962978313,
                                     0.21727416303204247,
                                     0.23194570464957284,
                                     0.24639243222054927,
                                     0.260614594383517,
                                     0.274612540230866,
                                     0.28838671868314064,
                                     0.3019376776865783,
                                     0.31526606323691536,
                                     0.32837261823312636,
                                     0.34125818116542317,
                                     0.35392368464236984,
                                     0.3663701537625864,
                                     0.37859870433700304,
                                     0.39061054096812187,
                                     0.40240695499320445,
                                     0.4139893222986874,
                                     0.4253591010135147,
                                     0.4365178290893654,
                                     0.447467121776064,
                                     0.4582086690006346,
                                     0.4687442326586961,
                                     0.47907564382697326,
                                     0.48920479990581933,
                                     0.49913366170066364,
                                     0.5088642504513123,
                                     0.5183986448179498,
                                     0.5277389778326486,
                                     0.5368874338250018,
                                     0.5458462453304023,
                                     0.5546176899892219,
                                     0.5632040874449623,
                                     0.571607796249165,
                                     0.5798312107805892,
                                     0.5878767581858458,
                                     0.5957468953483637,
                                     0.603444105892187,
                                     0.6109708972267669,
                                     0.6183297976385169,
                                     0.6255233534345194,
                                     0.632554126143378,
                                     0.6394246897778245,
                                     0.646137628163275,
                                     0.6526955323361379,
                                     0.6591009980153015,
                                     0.6653566231498025,
                                     0.6714650055453325,
                                     0.6774287405718399,
                                     0.6832504189541322,
                                     0.688932624647034,
                                     0.6944779327963035,
                                     0.6998889077862025,
                                     0.7051681013742841,
                                     0.7103180509136855,
                                     0.7153412776629191,
                                     0.7202402851828937,
                                     0.7250175578206622,
                                     0.7296755592791356,
                                     0.7342167312718229,
                                     0.7386434922614323,
                                     0.7429582362809982,
                                     0.7471633318360356,
                                     0.7512611208860764,
                                     0.7552539179038036,
                                     0.7591440090098801,
                                     0.7629336511814852,
                                     0.7666250715324454,
                                     0.7702204666628142,
                                     0.773722002075659,
                                     0.7771318116587776,
                                     0.7804519972290223,
                                     0.7836846281368944,
                                     0.786831740929021,
                                     0.7898953390661642,
                                     0.7928773926943639,
                                     0.7957798384668648,
                                     0.798604579414459,
                                     0.8013534848619271,
                                     0.8040283903882662,
                                     0.8066310978284397,
                                     0.8091633753144222,
                                     0.8116269573533456,
                                     0.8140235449406142,
                                     0.8163548057059009,
                                     0.818622374089976,
                                     0.8208278515504123,
                                     0.822972806794225,
                                     0.8250587760355962,
                                     0.82708726327688,
                                     0.8290597406111548,
                                     0.8309776485446396,
                                     0.8328423963373719,
                                     0.8346553623605916,
                                     0.8364178944693459,
                                     0.8381313103888983,
                                     0.8397968981135732,
                                     0.8414159163167384,
                                     0.8429895947706945,
                                     0.84451913477528,
                                     0.8460057095940775,
                                     0.8474504648971659,
                                     0.8488545192093865,
                                     0.8502189643632003,
                                     0.8515448659552075,
                                     0.8528332638055008,
                                     0.8540851724190409,
                                     0.8553015814483015,
                                     0.8564834561564946,
                                     0.8576317378806868,
                                     0.8587473444942216,
                                     0.859831170867845,
                                     0.8608840893290153,
                                     0.8619069501188902,
                                     0.8629005818465316,
                                     0.8638657919399055,
                                     0.864803367093277,
                                     0.8657140737106422,
                                     0.8665986583448713,
                                     0.8674578481322458,
                                     0.8682923512221337,
                                     0.8691028572015407,
                                     0.8698900375143144,
                                     0.8706545458748065,
                                     0.87139701867581,
                                     0.8721180753906135,
                                     0.8728183189690357,
                                     0.8734983362273165,
                                     0.8741586982317726,
                                     0.8747999606761112,
                                     0.8754226642523583,
                                     0.8760273350153228,
                                     0.8766144847405598,
                                     0.8771846112758129,
                                     0.8777381988859,
                                     0.8782757185910477,
                                     0.8787976284986752,
                                     0.8793043741286274,
                                     0.8797963887318999,
                                     0.8802740936028625,
                                     0.880737898385026,
                                     0.8811882013704081,
                                     0.881625389792515,
                                     0.8820498401130347,
                                     0.8824619183022614,
                                     0.8828619801133537,
                                     0.8832503713504585,
                                     0.8836274281308106,
                                     0.8839934771408501,
                                     0.8843488358864655,
                                     0.8846938129374174,
                                     0.8850287081660635,
                                     0.8853538129804268,
                                     0.8856694105517335,
                                     0.8859757760364942,
                                     0.8862731767932164,
                                     0.8865618725938479,
                                     0.8868421158300478,
                                     0.8871141517143601,
                                     0.8873782184764145,
                                     0.8876345475542117,
                                     0.8878833637806272,
                                     0.8881248855651916,
                                     0.8883593250712701,
                                     0.8885868883887148,
                                     0.8888077757020993,
                                     0.8890221814546158,
                                     0.88923029450773,
                                     0.8894322982966975,
                                     0.8896283709820092,
                                     0.8898186855968764,
                                     0.8900034101908363,
                                     0.8901827079695588,
                                     0.890356737430956,
                                     0.8905256524976655,
                                     0.8906896026460006,
                                     0.8908487330314493,
                                     0.8910031846107997,
                                     0.8911530942609717,
                                     0.8912985948946482,
                                     0.8914398155727586,
                                     0.8915768816139175,
                                     0.8917099147008757,
                                     0.8918390329840596,
                                     0.891964351182286,
                                     0.8920859806806997,
                                     0.8922040296260242,
                                     0.8923186030191824,
                                     0.89242980280536,
                                     0.892537727961569,
                                     0.8926424745817882,
                                     0.8927441359597312,
                                     0.89284280266931,
                                     0.8929385626428538,
                                     0.8930315012471376,
                                     0.8931217013572874,
                                     0.8932092434286029,
                                     0.8932942055663731,
                                     0.8933766635937136,
                                     0.8934566911175087,
                                     0.8935343595924722,
                                     0.8936097383834164,
                                     0.8936828948257448,
                                     0.893753894284237,
                                     0.8938228002101636,
                                     0.8938896741967768,
                                     0.8939545760332259,
                                     0.8940175637569319,
                                     0.894078693704474,
                                     0.8941380205610199,
                                     0.8941955974083438,
                                     0.8942514757714739,
                                     0.8943057056640015,
                                     0.8943583356320899,
                                     0.8944094127972253,
                                     0.8944589828977368,
                                     0.8945070903291233,
                                     0.8945537781832238,
                                     0.8945990882862538,
                                     0.8946430612357534,
                                     0.8946857364364623,
                                     0.8947271521351684,
                                     0.894767345454541,
                                     0.894806352425994,
                                     0.8948442080215938,
                                     0.8948809461850474,
                                     0.8949165998617888,
                                     0.8949512010282031,
                                     0.8949847807199888,
                                     0.8950173690597133,
                                     0.8950489952835564,
                                     0.8950796877672847,
                                     0.8951094740514687,
                                     0.895138380865964,
                                     0.8951664341536899,
                                     0.8951936590937011,
                                     0.8952200801236062,
                                     0.8952457209613156,
                                     0.8952706046261679,
                                     0.8952947534594377,
                                     0.895318189144238,
                                     0.8953409327248557,
                                     0.8953630046255115,
                                     0.895384424668574,
                                     0.8954052120922495,
                                     0.8954253855677429,
                                     0.895444963215928,
                                     0.8954639626235233,
                                     0.8954824008588032,
                                     0.895500294486818,
                                     0.8955176595842944,
                                     0.8955345117536241,
                                     0.8955508661382231,
                                     0.8955667374307866,
                                     0.8955821399061731,
                                     0.8955970873603702,
                                     0.89561159339866,
                                     0.8956256704169069,
                                     0.8956393334656015,
                                     0.8956525858627955,
                                     0.8956654730195578,
                                     0.8956737452180905,
                                     0.8956778813173569],
                          'tck_k': 3,
                          'tck_t': [ 0.0,
                                     0.0,
                                     0.0,
                                     0.0,
                                     0.2,
                                     0.4,
                                     0.6,
                                     0.8,
                                     1.0,
                                     1.2,
                                     1.4,
                                     1.6,
                                     1.8,
                                     2.0,
                                     2.2,
                                     2.4,
                                     2.6,
                                     2.8,
                                     3.0,
                                     3.2,
                                     3.4,
                                     3.6,
                                     3.8,
                                     4.0,
                                     4.2,
                                     4.4,
                                     4.6,
                                     4.8,
                                     5.0,
                                     5.2,
                                     5.4,
                                     5.6,
                                     5.8,
                                     6.0,
                                     6.2,
                                     6.4,
                                     6.6,
                                     6.8,
                                     7.0,
                                     7.2,
                                     7.4,
                                     7.6,
                                     7.8,
                                     8.0,
                                     8.2,
                                     8.4,
                                     8.6,
                                     8.8,
                                     9.0,
                                     9.2,
                                     9.4,
                                     9.6,
                                     9.8,
                                     10.0,
                                     10.2,
                                     10.4,
                                     10.6,
                                     10.8,
                                     11.0,
                                     11.2,
                                     11.4,
                                     11.6,
                                     11.8,
                                     12.0,
                                     12.2,
                                     12.4,
                                     12.6,
                                     12.8,
                                     13.0,
                                     13.2,
                                     13.4,
                                     13.6,
                                     13.8,
                                     14.0,
                                     14.2,
                                     14.4,
                                     14.6,
                                     14.8,
                                     15.0,
                                     15.2,
                                     15.4,
                                     15.6,
                                     15.8,
                                     16.0,
                                     16.2,
                                     16.4,
                                     16.6,
                                     16.8,
                                     17.0,
                                     17.2,
                                     17.4,
                                     17.6,
                                     17.8,
                                     18.0,
                                     18.2,
                                     18.4,
                                     18.6,
                                     18.8,
                                     19.0,
                                     19.2,
                                     19.4,
                                     19.6,
                                     19.8,
                                     20.0,
                                     20.2,
                                     20.4,
                                     20.6,
                                     20.8,
                                     21.0,
                                     21.2,
                                     21.4,
                                     21.6,
                                     21.8,
                                     22.0,
                                     22.2,
                                     22.4,
                                     22.6,
                                     22.8,
                                     23.0,
                                     23.2,
                                     23.4,
                                     23.6,
                                     23.8,
                                     24.0,
                                     24.2,
                                     24.4,
                                     24.6,
                                     24.8,
                                     25.0,
                                     25.2,
                                     25.4,
                                     25.6,
                                     25.8,
                                     26.0,
                                     26.2,
                                     26.4,
                                     26.6,
                                     26.8,
                                     27.0,
                                     27.2,
                                     27.4,
                                     27.6,
                                     27.8,
                                     28.0,
                                     28.2,
                                     28.4,
                                     28.6,
                                     28.8,
                                     29.0,
                                     29.2,
                                     29.4,
                                     29.6,
                                     29.8,
                                     30.0,
                                     30.2,
                                     30.4,
                                     30.6,
                                     30.8,
                                     31.0,
                                     31.2,
                                     31.4,
                                     31.6,
                                     31.8,
                                     32.0,
                                     32.2,
                                     32.4,
                                     32.6,
                                     32.8,
                                     33.0,
                                     33.2,
                                     33.4,
                                     33.6,
                                     33.8,
                                     34.0,
                                     34.2,
                                     34.4,
                                     34.6,
                                     34.8,
                                     35.0,
                                     35.2,
                                     35.4,
                                     35.6,
                                     35.8,
                                     36.0,
                                     36.2,
                                     36.4,
                                     36.6,
                                     36.8,
                                     37.0,
                                     37.2,
                                     37.4,
                                     37.6,
                                     37.8,
                                     38.0,
                                     38.2,
                                     38.4,
                                     38.6,
                                     38.8,
                                     39.0,
                                     39.2,
                                     39.4,
                                     39.6,
                                     39.8,
                                     40.0,
                                     40.2,
                                     40.4,
                                     40.6,
                                     40.8,
                                     41.0,
                                     41.2,
                                     41.4,
                                     41.6,
                                     41.8,
                                     42.0,
                                     42.2,
                                     42.4,
                                     42.6,
                                     42.8,
                                     43.0,
                                     43.2,
                                     43.4,
                                     43.6,
                                     43.8,
                                     44.0,
                                     44.2,
                                     44.4,
                                     44.6,
                                     44.8,
                                     45.0,
                                     45.2,
                                     45.4,
                                     45.6,
                                     45.8,
                                     46.0,
                                     46.2,
                                     46.4,
                                     46.6,
                                     46.8,
                                     47.0,
                                     47.2,
                                     47.4,
                                     47.6,
                                     47.8,
                                     48.0,
                                     48.2,
                                     48.4,
                                     48.6,
                                     48.8,
                                     49.0,
                                     49.2,
                                     49.4,
                                     49.6,
                                     49.8,
                                     50.0,
                                     50.2,
                                     50.4,
                                     50.6,
                                     50.8,
                                     51.0,
                                     51.2,
                                     51.4,
                                     51.6,
                                     51.8,
                                     52.0,
                                     52.2,
                                     52.4,
                                     52.6,
                                     52.8,
                                     53.0,
                                     53.2,
                                     53.4,
                                     53.6,
                                     53.8,
                                     54.0,
                                     54.2,
                                     54.4,
                                     54.6,
                                     54.8,
                                     55.0,
                                     55.2,
                                     55.4,
                                     55.6,
                                     55.8,
                                     56.0,
                                     56.2,
                                     56.4,
                                     56.6,
                                     56.8,
                                     57.0,
                                     57.2,
                                     57.4,
                                     57.6,
                                     57.8,
                                     58.0,
                                     58.2,
                                     58.4,
                                     58.6,
                                     58.8,
                                     59.0,
                                     59.2,
                                     59.4,
                                     59.6,
                                     59.8,
                                     60.0,
                                     60.2,
                                     60.4,
                                     60.6,
                                     60.8,
                                     61.0,
                                     61.2,
                                     61.4,
                                     61.6,
                                     61.8,
                                     62.0,
                                     62.2,
                                     62.4,
                                     62.6,
                                     62.8,
                                     63.0,
                                     63.2,
                                     63.4,
                                     63.6,
                                     63.8,
                                     64.0,
                                     64.2,
                                     64.4,
                                     64.6,
                                     64.8,
                                     65.0,
                                     65.2,
                                     65.4,
                                     65.6,
                                     65.8,
                                     66.0,
                                     66.2,
                                     66.4,
                                     66.6,
                                     66.8,
                                     67.0,
                                     67.2,
                                     67.4,
                                     67.6,
                                     67.8,
                                     68.0,
                                     68.2,
                                     68.4,
                                     68.6,
                                     68.8,
                                     69.0,
                                     69.2,
                                     69.4,
                                     69.6,
                                     69.8,
                                     70.0,
                                     70.2,
                                     70.4,
                                     70.6,
                                     70.8,
                                     71.0,
                                     71.2,
                                     71.4,
                                     71.6,
                                     71.8,
                                     72.0,
                                     72.2,
                                     72.4,
                                     72.6,
                                     72.8,
                                     73.0,
                                     73.2,
                                     73.4,
                                     73.6,
                                     73.8,
                                     74.0,
                                     74.2,
                                     74.4,
                                     74.6,
                                     74.8,
                                     75.0,
                                     75.2,
                                     75.4,
                                     75.6,
                                     75.8,
                                     76.0,
                                     76.2,
                                     76.4,
                                     76.6,
                                     76.8,
                                     77.0,
                                     77.2,
                                     77.4,
                                     77.6,
                                     77.8,
                                     78.0,
                                     78.2,
                                     78.4,
                                     78.6,
                                     78.8,
                                     79.0,
                                     79.2,
                                     79.4,
                                     79.6,
                                     79.8,
                                     80.0,
                                     80.2,
                                     80.4,
                                     80.6,
                                     80.8,
                                     81.0,
                                     81.2,
                                     81.4,
                                     81.6,
                                     81.8,
                                     82.0,
                                     82.2,
                                     82.4,
                                     82.6,
                                     82.8,
                                     83.0,
                                     83.2,
                                     83.4,
                                     83.6,
                                     83.8,
                                     84.0,
                                     84.2,
                                     84.4,
                                     84.6,
                                     84.8,
                                     85.0,
                                     85.2,
                                     85.4,
                                     85.6,
                                     85.8,
                                     86.0,
                                     86.2,
                                     86.4,
                                     86.6,
                                     86.8,
                                     87.0,
                                     87.2,
                                     87.4,
                                     87.6,
                                     87.8,
                                     87.8,
                                     87.8,
                                     87.8],
                          'time_at_umax': 0.0}}}

Extract Growth Statistics#

# Extract stats from each non-parametric fit
stats_spline = gc.inference.extract_stats(
    fit_spline,
    t,
    ln_N,
    phase_boundary_method="tangent",
)

stats_sliding_window = gc.inference.extract_stats(
    fit_sliding_window,
    t,
    ln_N,
    phase_boundary_method="tangent",
)

# Combine stats into a dictionary
phenom_nonparam_stats = {
    "spline": stats_spline,
    "sliding_window": stats_sliding_window,
}

# Create comparison dataframe
print("=== Phenomenological Non-Parametric Models Comparison ===")
phenom_nonparam_df = pd.DataFrame(phenom_nonparam_stats).T[
    [
        "mu_max",
        "intrinsic_growth_rate",
        "doubling_time",
        "time_at_umax",
        "exp_phase_start",
        "exp_phase_end",
        "model_rmse",
    ]
]
phenom_nonparam_df
=== Phenomenological Non-Parametric Models Comparison ===
mu_max intrinsic_growth_rate doubling_time time_at_umax exp_phase_start exp_phase_end model_rmse
spline 0.1493 None 4.642648 0.0 0.0 36.00422 0.0
sliding_window 0.149241 None 4.644497 0.6 0.0 36.018475 0.000008

Customizing Phase Boundary Detection#

Two methods are available for determining exponential phase boundaries:

1. Threshold Method#

  • Tracks the instantaneous specific growth rate μ(t)

  • exp_phase_start: First time when μ exceeds a fraction of μ_max (default: 15%)

  • exp_phase_end: First time after peak when μ drops below the threshold

2. Tangent Method#

  • Constructs a tangent line in log space at the point of maximum growth rate

  • Extends this tangent to intersect baseline (exp_phase_start) and plateau (exp_phase_end)

# Compare phase-boundary methods on the same fit
phase_boundary_rows = []

# Tangent method
stats_tangent = gc.inference.extract_stats(
    fit_spline,
    t,
    ln_N,
    phase_boundary_method="tangent",
)
phase_boundary_rows.append(
    {
        "label": "tangent",
        "method": "tangent",
        "lag_threshold": np.nan,
        "exp_threshold": np.nan,
        "stats": stats_tangent,
    }
)

# Threshold method at different cutoffs
for frac, label in [
    (0.10, "threshold_low"),
    (0.15, "threshold_default"),
    (0.30, "threshold_high"),
]:
    stats_threshold = gc.inference.extract_stats(
        fit_spline,
        t,
        ln_N,
        phase_boundary_method="threshold",
        lag_threshold=frac,
        exp_threshold=frac,
    )
    phase_boundary_rows.append(
        {
            "label": label,
            "method": "threshold",
            "lag_threshold": frac,
            "exp_threshold": frac,
            "stats": stats_threshold,
        }
    )

# Create comparison dataframe
print("=== Phase Boundary Method Comparison ===")
phase_boundary_df = pd.DataFrame(
    [
        {
            "label": row["label"],
            "method": row["method"],
            "lag_threshold": row["lag_threshold"],
            "exp_threshold": row["exp_threshold"],
            "exp_phase_start": row["stats"]["exp_phase_start"],
            "exp_phase_end": row["stats"]["exp_phase_end"],
        }
        for row in phase_boundary_rows
    ]
)
phase_boundary_df
=== Phase Boundary Method Comparison ===
label method lag_threshold exp_threshold exp_phase_start exp_phase_end
0 tangent tangent NaN NaN 0.0 36.004220
1 threshold_low threshold 0.10 0.10 0.0 50.527874
2 threshold_default threshold 0.15 0.15 0.0 47.433286
3 threshold_high threshold 0.30 0.30 0.0 41.489259

See more details on the phase boundary methods in the next tutorial notebook: plotting.ipynb (Visualize fitted growth curves, derivatives, and growth statistics)