# Results and Observables

Channel: release; package: 1.8.0; source: 7d1e97331656dd74ad0f5471653ac0c5effdff70

Page: https://remilab.ai/rfx/versions/v1.8.0/api/results-observables/
Source: https://github.com/bk-squared/rfx/blob/7d1e97331656dd74ad0f5471653ac0c5effdff70/docs/public/api/results-observables.mdx

`Result` is the object returned by `Simulation.run()`.

## Primary fields

| Field | Meaning | Public use |
|---|---|---|
| `state` | final solver state / checkpoint payload | inspection, checkpoint export, and debugging; no high-level resume API accepts it as an initial state |
| `time_series` | recorded probe values over time | ringdown, transient response, Harminv |
| `s_params` | lumped/wire port S-matrix | matching, filters, de-embedding |
| `freqs` | frequency axis paired with `Result.s_params` | lumped/wire S-parameter output; DFT-plane and flux-monitor objects carry their own frequency axes |
| `ntff_data` | near-to-far-field accumulation | radiation patterns where documented |
| `dft_planes` | frequency-domain plane observables | slices and field maps |
| `flux_monitors` | plane flux accumulations | transmission / reflection analysis |
| `waveguide_sparams` | per-port waveguide diagnostics | waveguide workflows |
| `snapshots` | saved field snapshots | visualization and post-processing |
| `grid` | mesh metadata | reproducibility checks |
| `dt` | timestep | time-axis conversion |

## S-parameter result schemas

| Calculator | Result object | Public status |
|---|---|---|
| `run(compute_s_params=True)` with lumped/wire `add_port(...)` | `Result.s_params`, `Result.freqs` | documented path for the matching port family |
| `forward(port_s11_freqs=...)` with lumped/wire `add_port(...)` | `ForwardResult.s_params`, `ForwardResult.freqs` | differentiable S11 vectors, not a full multi-port matrix |
| `compute_msl_s_matrix(...)` | `MSLSMatrixResult` with `.S`, `.freqs`, `.Z0`, `.beta`, `.port_names`, `.reliable`, `.settling_db`, `.S_raw`, `.passivity_correction` | specialized microstrip-line calculation. `.S` is passivity-enforced by default (`||S||₂ ≤ 1` per frequency; raw extraction kept in `.S_raw`, per-bin clip in `.passivity_correction` — large corrections mark measurement artifacts, not certified values; skipped on the `eps_override` channel so gradients see the raw function). Exclude the whole frequency slice `S[:, :, k]` wherever any `reliable[p, k]` is false — not just that port's column, since S is solved jointly across drives — and check `.settling_db` (< −40 dB) before quoting any value. `.assembly` records which rule produced `.S`; `.cond_a` bounds drive-system degeneracy only |
| `compute_waveguide_s_matrix(...)` | `WaveguideSMatrixResult` | rectangular waveguide workflow |
| `compute_coaxial_line_reflection(...)` | `CoaxialLineReflectionResult` | reflection with float32 precision, a nonperiodic 3D second-order uniform Yee grid, CPML on all six boundary faces with positive thickness on both z faces, `cpml_axes="z"`, and exactly one `face="top"` coaxial port; see [Sources and Ports](https://remilab.ai/rfx/versions/v1.8.0/api/sources-ports/) for the self-contained model limits |
| `run(...)` with a single waveguide port | `Result.waveguide_sparams[name]` | diagnostic per-port output |

Sources, TFSF, probes, DFT planes, and flux monitors do not automatically define a high-level S-matrix workflow. Coaxial reports should use the documented line-reflection method.

## Observable builders that feed `Result`

| Builder | Result field | Typical use |
|---|---|---|
| `add_probe(...)` / `add_vector_probe(...)` | `time_series` | transient response, ringdown, local field traces |
| `add_dft_plane_probe(...)` | `dft_planes` | frequency-domain field slices |
| `add_flux_monitor(...)` | `flux_monitors` | reflection / transmission bookkeeping |
| `add_ntff_box(...)` | `ntff_data`, `ntff_box` | far-field accumulation |

Finite-size flux monitors use the same per-cell Poynting integrand as full-plane monitors. When both are summed over the same index window, they agree to machine precision; differences from `size=None` full-plane monitors are coverage choices, not a separate stability model.

## Resonance extraction

`Result.find_resonances()` runs Harminv-style mode extraction on a probe time series.

Setup used by the snippets below:

```python
from rfx import Box, GaussianPulse, Simulation

sim = Simulation(
    freq_max=4e9,
    domain=(0.04, 0.03, 0.02),
    dx=2e-3,
    boundary="cpml",
    cpml_layers=6,
)
sim.add_material("slab", eps_r=4.0, sigma=0.01)
sim.add(Box((0.014, 0.010, 0.006), (0.026, 0.020, 0.014)), material="slab")
sim.add_port(
    (0.008, 0.015, 0.010),
    "ez",
    impedance=50.0,
    waveform=GaussianPulse(f0=2e9, bandwidth=0.8),
)
sim.add_probe((0.032, 0.015, 0.010), "ez")
```

```python
result = sim.run(n_steps=8000)
modes = result.find_resonances(freq_range=(1.5e9, 3.5e9))
```

Use this on a clean probe signal when you want a resonance estimate that is less dependent on port calibration than S-parameters.

## Port-observable helpers

`rfx.validation` provides helper functions for checking S-matrix-like arrays for shape, finite values, frequency metadata, port names, and caller-selected passivity / reciprocity limits.

```python
from rfx import validate_port_smatrix, assert_port_smatrix_valid

report = validate_port_smatrix(result, check_passivity=True, passivity_tol=0.02)
print(report.summary())
```

These helpers are useful for regression checks. They do not turn an undocumented workflow into the recommended default path.

During normal Python execution outside JAX tracing, some calculation paths emit
warnings without changing the arrays. Coverage is deliberately narrow:

- the generic `run()` warning and uniform single-device `forward()` warning
  inspect `time_series` and lumped/wire `s_params`, not state, NTFF, DFT-plane,
  or flux arrays; non-uniform and distributed `forward()` paths do not invoke
  this guard;
- lumped/wire `run()` and uniform single-device `forward()` check individual
  entries for non-finite values or `|S| > 1.1`, but do not test total outgoing
  column power;
- MSL and waveguide full-matrix calculators apply per-entry and column-power
  checks with calculator-specific tolerances;
- `compute_coaxial_line_reflection()` requires float32 precision, a nonperiodic
  3D second-order uniform Yee grid, CPML on all six boundary faces with positive
  thickness on both z faces, `cpml_axes="z"`, and exactly one `face="top"`
  coaxial port. It builds its own line, source, probes, and termination and
  rejects unsupported registered objects. It returns `status`, fit/recurrence
  residuals, and `s11`, but does not run the shared passivity guard. See
  [Sources and Ports](https://remilab.ai/rfx/versions/v1.8.0/api/sources-ports/) before configuring this method.

The ring-down advisory likewise requires a probe time series and is not a
direct NTFF or DFT convergence test. Inspect unguarded arrays explicitly. The
absence of a warning is not a passivity, convergence, or accuracy result.

For MSL results, `reliable[p, k] = False` excludes the whole frequency slice
`S[:, :, k]` from physical interpretation — not just the driven-port column —
because S is solved jointly across drives (`S = B·A⁻¹`, #507); the mask covers
every driven/port record the solve consumes (#522). A `True` entry is not an
accuracy guarantee. See
[Probes and S-Parameters](https://remilab.ai/rfx/versions/v1.8.0/guide/probes-sparams/#low-signal-msl-bins) for the
threshold and filtering example.

## Validated observables

For public docs, describe observables in simple terms:

- `time_series` and Harminv are the recommended resonance path.
- lumped/wire, MSL, waveguide, and coaxial-line S-parameter/reflection workflows each have their own calculator and stated limits.
- NTFF/far-field outputs should be used where the relevant guide documents the workflow.
- Other fields are useful analysis outputs; apply the documented support status for the calculation that produced them.
