"""Regenerate the three synthetic Peak & Mass HPLC detector traces.

Run: python3 simulate.py --output regenerated-data
Uses only the Python standard library. The scenarios are idealized and deterministic.
"""

import argparse
import csv
import math
from pathlib import Path

BASELINE = 0.04
SIGMA_MIN = 0.35
MOL_AMOUNTS_NMOL = (1.20, 0.80)
TIME_MIN = tuple(tick / 100 for tick in range(801))

# Each case specifies the model retention times and detector response factors.
CASES = {
    "a-separated": ((3.00, 5.10), (1.00, 1.00)),
    "b-overlap": ((3.00, 3.80), (1.00, 1.00)),
    "c-response": ((3.00, 5.10), (1.00, 2.00)),
}


def gaussian_signal(time_min, center_min, area_au_min):
    normalizer = SIGMA_MIN * math.sqrt(2 * math.pi)
    distance = (time_min - center_min) / SIGMA_MIN
    return area_au_min * math.exp(-0.5 * distance**2) / normalizer


def write_traces(output_dir):
    output_dir.mkdir(parents=True, exist_ok=True)
    for case, (centers, factors) in CASES.items():
        areas = [amount * factor for amount, factor in zip(MOL_AMOUNTS_NMOL, factors)]
        with (output_dir / f"synthetic-{case}.csv").open(
            "w", encoding="utf-8", newline=""
        ) as file:
            writer = csv.writer(file, lineterminator="\n")
            writer.writerow(["time_min", "detector_signal_au"])
            for time_min in TIME_MIN:
                components = (
                    gaussian_signal(time_min, center, area)
                    for center, area in zip(centers, areas)
                )
                signal = BASELINE + sum(components)
                writer.writerow([f"{time_min:.2f}", f"{signal:.8f}"])


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("--output", type=Path, default=Path("regenerated-data"))
    args = parser.parse_args()
    write_traces(args.output)
