Source code for quchip.results.input_output

"""Results for continuous-wave port scattering calculations."""

from __future__ import annotations

from dataclasses import dataclass, field
from types import MappingProxyType
from typing import Any, Mapping

import numpy as np

from quchip.utils.labeling import resolve_label


[docs] @dataclass(frozen=True) class SParameterResult: """Complex port response over a declared VNA sweep grid.""" frequencies: Any input_port: str output_ports: tuple[str, ...] input_amplitudes: Any | None input_photon_fluxes: Any | None input_powers: Any | None axes: tuple[tuple[str, Any], ...] shape: tuple[int, ...] steady_states: tuple[Any, ...] diagnostics: tuple[Mapping[str, Any], ...] _response: Mapping[tuple[str, str], Any] = field(repr=False) @property def input_power_unit(self) -> str: """Unit of :attr:`input_powers`.""" return "W" def __post_init__(self) -> None: object.__setattr__(self, "_response", MappingProxyType(dict(self._response))) object.__setattr__( self, "diagnostics", tuple(MappingProxyType(dict(item)) for item in self.diagnostics), ) @property def axis_names(self) -> tuple[str, ...]: """Names of the result axes, in array order.""" return tuple(name for name, _ in self.axes)
[docs] def s(self, output: Any, input: Any | None = None) -> Any: """Return one complex ``S(output, input)`` array.""" output_label = resolve_label(output) input_label = self.input_port if input is None else resolve_label(input) try: return self._response[(output_label, input_label)] except KeyError: available = [key for key in self._response] raise KeyError(f"S({output_label!r}, {input_label!r}) is unavailable. Available: {available}") from None
@property def s11(self) -> Any: """Reflection at the swept input port.""" return self.s(self.input_port, self.input_port) @property def s21(self) -> Any: """Transmission to the first requested output distinct from the input.""" output = next((label for label in self.output_ports if label != self.input_port), None) if output is None: raise AttributeError("s21 requires an output port distinct from the swept input port.") return self.s(output, self.input_port) def __array__(self) -> np.ndarray: return np.asarray(self.s11)
[docs] @dataclass(frozen=True) class OutputSpectrumResult: """Normally ordered stationary output-field fluctuation spectrum.""" port: str frequencies: Any fluctuation_spectrum: Any output_photon_flux: Any coherent_flux: Any incoherent_flux: Any steady_state: Any fourier_convention: str = "2 Re integral_0^inf d tau exp(+i 2 pi f tau) C(tau)" @property def total_flux(self) -> Any: """Mean normally ordered output photon flux.""" return self.output_photon_flux
[docs] @dataclass(frozen=True) class OutputCorrelationResult: """Normalized stationary output-field correlation versus delay.""" order: int input_port: str output_port: str delays: Any values: Any unnormalized: Any input_intensity: Any output_intensity: Any steady_state: Any normalization: str @property def port(self) -> str: """Delayed output port, retained for single-port result code.""" return self.output_port @property def intensity(self) -> Any: """Delayed output intensity, retained for single-port result code.""" return self.output_intensity