# Data-generating model shared by make_data.py and simulation.py. Python 3.13, NumPy.
# A phenotype (for example mean neurite length per differentiation, log scale) in iPSC-derived cells.
import numpy as np
SD_DONOR, SD_CLONE, SD_DIFF = 0.30, 0.15, 0.10

def case_control(rng, effect=0.0, donors=3, clones=2, diffs=3):
    """Rows (status, donor, clone, differentiation, value): patient and control donors, several clones per donor,
    several differentiations per clone. Donor (genetic background) varies most, then clone, then differentiation."""
    out = []
    for status in ("control", "patient"):
        for d in range(donors):
            dv = rng.normal(0, SD_DONOR) + (effect if status == "patient" else 0)
            for c in range(clones):
                cv = dv + rng.normal(0, SD_CLONE)
                for k in range(diffs):
                    out.append((status, f"{status[0].upper()}{d + 1}", f"{status[0].upper()}{d + 1}-c{c + 1}", k + 1, cv + rng.normal(0, SD_DIFF)))
    return out

def isogenic(rng, effect=0.0, donors=3, diffs=3):
    """Rows (line, donor, differentiation, value): for each patient donor, the patient line and its gene-corrected
    (isogenic) line, differentiated together."""
    out = []
    for d in range(donors):
        dv = rng.normal(0, SD_DONOR)
        for line, e in (("corrected", 0.0), ("patient", effect)):
            cv = dv + e + rng.normal(0, SD_CLONE)
            for k in range(diffs):
                out.append((line, f"D{d + 1}", k + 1, cv + rng.normal(0, SD_DIFF)))
    return out
