# Constructed ELISA plate: 8 standards and 6 samples, each in duplicate wells.
# True curve (4PL): OD = top + (bottom - top) / (1 + (conc / ec50) ** slope), bottom 0.05, top 2.8, ec50 150 pg/mL,
# slope 1.2; well-to-well noise 4% (multiplicative). True sample concentrations 5, 20, 80, 300, 700 and 1500 pg/mL.
# The seed (1) was the first one run; it was not selected.
import numpy as np, pandas as pd
rng = np.random.default_rng(1)
f = lambda x: 2.8 + (0.05 - 2.8) / (1 + (x / 150) ** 1.2)
std = [1000, 500, 250, 125, 62.5, 31.25, 15.625, 7.8125]
smp = {"S1": 5, "S2": 20, "S3": 80, "S4": 300, "S5": 700, "S6": 1500}
rows = [("standard", f"Std{i+1}", c, round(f(c) * (1 + rng.normal(0, 0.04)), 4)) for i, c in enumerate(std) for _ in range(2)]
rows += [("sample", k, np.nan, round(f(c) * (1 + rng.normal(0, 0.04)), 4)) for k, c in smp.items() for _ in range(2)]
pd.DataFrame(rows, columns=["type", "id", "conc_pg_ml", "od"]).to_csv("plate.csv", index=False)
