# Results and Measurements Measurements turn waveform data into design metrics. Specs turn those metrics into pass/fail decisions. ```text SimResult -> metric function -> Spec -> SpecTable -> corner/report view ``` ## Measurement Functions Monata groups measurement helpers by domain: | Module | Use | | --- | --- | | `monata.measure.time_domain` | delay, rise/fall time, overshoot, settling | | `monata.measure.freq_domain` | gain, bandwidth, phase margin, unity-gain frequency | | `monata.measure.statistics` | histogram, yield, sensitivity, worst-case analysis | | `monata.measure.spec` | pass/fail specification evaluation | A metric function should accept a `SimResult` and return a scalar. ```python def propagation_delay(result): time = result.sweep_var vin = result.waveforms["in"] vout = result.waveforms["out"] return delay(time, vin, vout, threshold=0.6) ``` ## Specs Use `Spec` for one measurement and `SpecTable` for a group of checks. ```python from monata.measure.spec import SpecTable specs = SpecTable() specs.add("tpd", propagation_delay, max=80e-12, unit="s") specs.add("voh", lambda r: max(r.waveforms["out"]), min=1.1, unit="V") ``` Evaluate specs after simulation: ```python table = specs.evaluate_all(corner_results) worst_corner, worst_value = specs.worst_corner("tpd", corner_results) ``` ## Design Guidance Keep metric functions small and explicit. They are the bridge between simulation and optimization, so they should not hide simulator setup or mutate the circuit. Good metric functions: - read only from `SimResult` - return one number - handle missing or failed data deliberately - use clear units in the spec table Avoid mixing backend-specific parsing into metric functions. If a backend needs special handling, normalize it when creating the `SimResult`.