#!/usr/bin/env python3
"""Educational process-metrology model summaries for SemiAgora replays.

This script documents compact calculations used by the public metrology packet.
It does not write recipes, control equipment, release wafers, or qualify any
process.
"""

from __future__ import annotations

import math


def mean(samples: list[float]) -> float:
    return sum(samples) / len(samples)


def sample_std(samples: list[float]) -> float:
    mu = mean(samples)
    return math.sqrt(sum((x - mu) ** 2 for x in samples) / (len(samples) - 1))


def half_range_nonuniformity_percent(samples: list[float]) -> float:
    mu = mean(samples)
    return (max(samples) - min(samples)) / (2 * mu) * 100


def linear_fit(x: list[float], y: list[float]) -> tuple[float, float]:
    x_bar = mean(x)
    y_bar = mean(y)
    numerator = sum((xi - x_bar) * (yi - y_bar) for xi, yi in zip(x, y))
    denominator = sum((xi - x_bar) ** 2 for xi in x)
    slope = numerator / denominator
    intercept = y_bar - slope * x_bar
    return slope, intercept


def cp_cpk(samples: list[float], lsl: float, usl: float) -> tuple[float, float]:
    mu = mean(samples)
    sigma = sample_std(samples)
    cp = (usl - lsl) / (6 * sigma)
    cpk = min((usl - mu) / (3 * sigma), (mu - lsl) / (3 * sigma))
    return cp, cpk


def vector_magnitude(dx: float, dy: float) -> float:
    return math.sqrt(dx * dx + dy * dy)


def main() -> None:
    sheet_map = [
        [52, 51, 50, 51, 52],
        [51, 50, 49, 50, 51],
        [50, 49, 48, 49, 50],
        [51, 50, 49, 50, 51],
        [52, 51, 50, 51, 52],
    ]
    sheet_samples = [x for row in sheet_map for x in row]
    gap_um = [5, 10, 20, 40, 80]
    resistance_ohm = [12, 16, 24, 40, 72]
    cd_samples = [
        100.2, 99.1, 101.3, 100.6, 98.9,
        100.8, 101.1, 99.7, 100.4, 102.0,
        98.7, 99.8, 100.1, 101.5, 100.9,
        99.5, 100.7, 101.8, 98.8, 100.0,
        99.3, 100.5, 101.0, 100.6, 99.9,
    ]
    rate_grid = [
        [35, 42, 44],
        [48, 56, 55],
        [58, 64, 61],
    ]

    slope, intercept = linear_fit(gap_um, resistance_ohm)
    cp, cpk = cp_cpk(cd_samples, 96, 104)
    best_rate = max(x for row in rate_grid for x in row)
    overlay = vector_magnitude(2.7, 1.8)

    print("sheet resistance mean ohm/sq:", round(mean(sheet_samples), 2))
    print("sheet resistance half-range nonuniformity %:", round(half_range_nonuniformity_percent(sheet_samples), 2))
    print("tlm slope/intercept:", round(slope, 2), round(intercept, 2))
    print("spc Cp/Cpk:", round(cp, 2), round(cpk, 2))
    print("worst overlay vector nm:", round(overlay, 2))
    print("doe best rate nm/min:", best_rate)


if __name__ == "__main__":
    main()
