# Data-generating model shared by make_data.py and simulation.py. Python 3.13, NumPy.
# Immunofluorescence: in each independent experiment, one coverslip per condition is imaged at 5 random fields with
# identical settings, and every cell is outlined (about 10 per image). For each cell, ImageJ gives the area (pixels)
# and integrated density (sum of pixel values); for each image, mean background is read from 3 cell-free regions.
# Cell signal varies between experiments, between the two coverslips of one experiment, between images and between
# cells; background adds to every pixel.
import numpy as np
IMAGES = 5

def experiment(rng, kd_ratio=1.0, signal=400.0, bg=150.0, sd_exp=0.3, sd_cs=0.10, sd_img=0.10, sd_cell=0.45):
    rows = []; e = rng.normal(0, sd_exp)
    for cond, r in (("control", 1.0), ("knockdown", kd_ratio)):
        cs = e + rng.normal(0, sd_cs)
        for i in range(IMAGES):
            im = cs + rng.normal(0, sd_img); b = bg * np.exp(rng.normal(0, 0.15))          # background per pixel in this image
            b_read = b + rng.normal(0, 3)                                                   # mean of 3 background regions
            for c in range(max(3, rng.poisson(10))):
                area = float(np.round(np.exp(rng.normal(np.log(1500), 0.3))))
                per_px = signal * r * np.exp(im + rng.normal(0, sd_cell))
                rows.append((cond, i + 1, c + 1, area, round(area * (per_px + b) + rng.normal(0, 2000)), round(b_read, 1)))
    return rows
