Example 4 — CSV workflow#

Demonstrates the full plate-reader CSV round-trip: load → subset → fit → save.

Full script: examples/scripts/05_from_csv.py

CSV format#

pykinbiont expects a CSV where:

  • The first column contains time values (any column name is fine)

  • Remaining columns are OD curves, one per well

  • Column headers become the curve labels

time,Well_A1,Well_A2,Well_A3
0.0,0.012,0.011,0.013
0.5,0.014,0.013,0.015
1.0,0.017,0.016,0.018
...

Load from CSV#

import pykinbiont
from pykinbiont import GrowthData, FitOptions, ModelSpec, MODEL_REGISTRY, fit, save_results

pykinbiont.configure("/path/to/KinBiont.jl")

data = GrowthData.from_csv("plate_reader.csv")
print(f"Loaded: {len(data.labels)} curves, {len(data.times)} time points")
print(f"Labels: {data.labels}")

Load from a DataFrame#

import pandas as pd
from pykinbiont import GrowthData

df = pd.read_excel("plate_reader.xlsx")   # or any DataFrame source
data = GrowthData.from_dataframe(df)

Subset wells of interest#

subset = data[["Well_A1", "Well_B1", "Well_A2"]]
print(f"Subset: {subset.labels}")

Fit#

logistic = MODEL_REGISTRY["NL_logistic"]
spec = ModelSpec(
    models=[logistic],
    params=[[1.2, 0.01, 0.5]],
    lower=[[0.0, 0.0, 0.0]],
    upper=[[5.0, 1.0, 5.0]],
)
opts = FitOptions(smooth=True, smooth_method="rolling_avg")

results = fit(data, spec, opts)
print(results.to_dataframe()[["label", "best_model", "aic"]].to_string(index=False))

Save results#

paths = save_results(results, "output/", prefix="my_experiment")

print("Results saved:")
for key, path in paths.items():
    n_rows = pd.read_csv(path).shape[0]
    print(f"  {key:15s}: {path}  ({n_rows} rows)")

Read results back#

import pandas as pd

summary = pd.read_csv(paths["summary"])
fitted  = pd.read_csv(paths["fitted_curves"])

# Plot one well
import matplotlib.pyplot as plt

well = summary.iloc[0]["label"]
wdf  = fitted[fitted["label"] == well]

plt.plot(wdf["time"], wdf["observed"], ".", label="observed")
plt.plot(wdf["time"], wdf["fitted"],   "-", label="fitted")
plt.title(well)
plt.xlabel("Time (h)")
plt.ylabel("OD")
plt.legend()
plt.show()