Batched waveform analysis¶
striqt.analysis¶
implementations of channel analysis measurements packaged into xarray.DataArray and xarray.Dataset
- class striqt.analysis.AcquiredIQ(x: Array, capture: specs.Capture | None)¶
Bases:
objectan acquired IQ waveform x with the capture that describes the acquisition.
- capture: specs.Capture | None¶
the acquisition parameters of x, or None when not known
- property preprocess: Preprocessor¶
return the Preprocessor of this acquisition, one per instance.
A dataclasses.replace copy starts with a Preprocessor of its own.
- x: Array¶
the acquired waveform with shape (port, sample)
- class striqt.analysis.AnalysisRegistry¶
Bases:
dict[type[Analysis],AnalysisInfo]a registry of keyword-only arguments for decorated functions
- cache_context(capture: Capture, callback: Callable | None = None) AbstractContextManager[ExitStack]¶
- caches: dict[AnalysisFunc, list[KwArgCache]]¶
- measurement(spec_type: type[specs.Analysis], *, dtype: str, name: str | None = None, dims: tuple[str, ...] | str | None = None, coord_factories: Iterable[CoordFunc] | CoordFunc | None = None, depends: Iterable[Callable] | Callable = [], caches: Iterable[KwArgCache] | KwArgCache | None = None, store_compressed: bool = True, prefer_filtered: bool = True, prefer_aligned: bool = True, attrs: dict[str, Any] = {}, validate: AnalysisValidator | None = None, tolerance: AnalysisTolerance | None = None) AnalysisFuncWrapper[P]¶
register the decorated function as the measurement configured by spec_type.
Registration mutates this registry when the decorator is applied. A sweep enables the measurement through an
Optional[spec_type]field named name in an analysis group such as specs.BuiltinAnalyses.The decorated function is called as
func(x, capture, **spec.to_dict())with x an array of shape (port, sample), and returns an array with axes dims or an(array, attrs)tuple. The returned wrapper is called aswrapper(iq, capture, as_xarray=True, **kwargs)with the fields of spec_type as keywords. The __signature__ of the wrapper and the{args}placeholder in the docstring are filled from spec_type. An array iq is passed to the function as x. From an AcquiredIQ, AcquiredIQ.preprocess selects x as prefer_filtered and prefer_aligned request. validate runs before the IQ is read and raises specs.helpers.SpecValidationError on a rejected combination. The wrapper returns, by as_xarray:True, an xarray.DataArray with a leadingportdimension;'delayed', a DelayedDataArray;False, the(array, attrs)pair.- Parameters:
spec_type – the specs.Analysis subclass with the keyword arguments of the measurement as fields; one measurement per type
dtype – numpy dtype name of the output array
name – the output data variable name, or None for the function __name__
dims – dimension names of the output axes, or None for the dimensions of coord_factories, in order
coord_factories – functions registered with coordinates that produce the coordinate values along dims from
(capture, spec)depends – measurements with an intermediate this one reuses; recorded on the AnalysisInfo entry and not otherwise read
caches – KwArgCache instances that cache_context enables for one capture; shared with other measurements
store_compressed – False to store the output uncompressed in zarr
prefer_filtered – False to measure the waveform before the analysis_bandwidth low-pass; applies only when the acquisition filters
prefer_aligned – False to measure the waveform before the signal-trigger shift; applies only when the acquisition runs a trigger. A signal_trigger measurement must set False
attrs – attrs of the output xarray.DataArray; the spec fields and any attrs returned by the function take precedence
validate – a function of
(capture, spec)that raises on a rejected combination without reading IQ; capture is the specs.AnalysisCapture projection, and the return value is ignoredtolerance – a function of
(capture, spec, *, array_backend, input_error)that returns the specs.Tolerance of the output without reading IQ
- Returns:
a decorator that registers the decorated function and returns the wrapper
- Raises:
ValueError – when spec_type is already registered
TypeError – when a coord_factories entry is not callable; from the returned decorator, when name is already registered, when caches contains something other than KwArgCache instances, or when a field of spec_type shares a name with a field of another registered spec and differs in type
- parameter_defaults: dict[str, Any]¶
- parameter_fields: dict[str, 'msgspec.structs.FieldInfo|None']¶
- tolerances(capture: specs.Capture, analysis: specs.AnalysisGroup, *, array_backend: ArrayBackend = 'numpy', input_error: float = 0.0) dict[str, specs.Tolerance]¶
return the roundoff error budget of each measurement in analysis.
Results are cached on the specs.AnalysisCapture projection of capture.
- Parameters:
array_backend – the array namespace of the measurement evaluation; selects the roundoff model
input_error – relative rms amplitude error already present in the IQ handed to the measurements, as a ratio
- Returns:
a dict of specs.Tolerance keyed by measurement name; measurements left unset in analysis or registered without a tolerance= function are omitted
- validate(capture: Capture, analysis: AnalysisGroup) None¶
check each measurement in analysis against capture without IQ.
Measurements left unset in analysis, and those registered without a validate= function, are skipped. Results are cached on the specs.AnalysisCapture projection of capture. Captures equal in that projection share one entry.
- Raises:
specs.helpers.SpecValidationError – on the first invalid combination, with a field path rooted at
$.analysis
- class striqt.analysis.Capture(*, duration=0.1, sample_rate=15360000.0, analysis_bandwidth=inf)¶
Bases:
SpecBasebare minimum information about an IQ acquisition
- Parameters:
duration (float) – Duration of the analysis waveform (Constraints: units: s)
sample_rate (float) – Sample rate of the analyzed IQ waveform (Constraints: > 0, units: S/s)
analysis_bandwidth (float) – Analysis bandwidth (Constraints: units: Hz)
- class striqt.analysis.EvaluationOptions(as_xarray, registry, block_each=True, expand_dims=('port',))¶
Bases:
Struct,Generic[TAR]the result type and registry for one evaluation of an analysis group.
as_xarray selects the result type of analyze_by_spec:
Truefor an xarray.Dataset,'delayed'for DelayedDataArray results, orFalsefor the bare arrays in the array namespace of the input. registry supplies the measurement function of each spec type. block_each True materializes each result to numpy as soon as the measurement returns, when as_xarray isTrueor'delayed'. expand_dims names the leading dimension of each xarray.DataArray when as_xarray isTrue, and that dimension indexes the port axis of the input.- Raises:
TypeError – when as_xarray is not
True,False, or'delayed'- Parameters:
as_xarray (TAR)
registry (AnalysisRegistry)
block_each (bool)
expand_dims (Sequence[str])
- class striqt.analysis.Preprocessor(iq: AcquiredIQ)¶
Bases:
objectthe conditioned-waveform selector of one acquisition.
The base class returns x of the acquisition for every preference. A subclass that conditions the waveform lazily overrides __call__.
- __init__(iq: AcquiredIQ) None¶
store a weak reference to iq.
- property iq: AcquiredIQ¶
the acquisition that owns this preprocessor.
- Raises:
RuntimeError – when the acquisition has been garbage collected
- class striqt.analysis.Trigger(name_or_func: str | Callable, spec: Analysis, registry: AnalysisRegistry)¶
Bases:
object- classmethod from_spec(name: str, analysis: specs.AnalysisGroup, registry: AnalysisRegistry) Self¶
- info: SyncInfo¶
- striqt.analysis.analyze_by_spec(iq: Array | AcquiredIQ, spec: AnalysisGroup, capture: Capture, options: EvaluationOptions[Literal[True]] | None = None) Dataset¶
- striqt.analysis.analyze_by_spec(iq: Array | AcquiredIQ, spec: AnalysisGroup, capture: Capture, options: EvaluationOptions[Literal['delayed']]) dict[str, DelayedDataArray]
- striqt.analysis.analyze_by_spec(iq: Array | AcquiredIQ, spec: AnalysisGroup, capture: Capture, options: EvaluationOptions[Literal[False]]) dict[str, Array]
evaluate the enabled measurements of spec on the IQ waveform.
- Parameters:
iq – the waveform with shape (port, sample), or an AcquiredIQ from which each measurement selects the conditioned waveform
spec – an AnalysisGroup such as specs.BuiltinAnalyses; the
Nonefields are skippedcapture – the acquisition parameters of iq
options – the result type and the registry, or
Nonefor the default registry with as_xarrayTrue
- Returns:
True: an xarray.Dataset of the measurements, with the capture fields as attrs and options.expand_dims as the leading dimension'delayed': a dict of DelayedDataArray keyed by measurement nameFalse: a dict of bare arrays keyed by measurement name, in the array namespace of iq
- Return type:
by options.as_xarray
- Raises:
TypeError – when spec is not an AnalysisGroup
KeyError – when the spec type of an enabled field is not in options.registry
specs.helpers.SpecValidationError – when a measurement validator rejects the
(capture, spec)combination
- striqt.analysis.cellular_5g_pss_correlation(iq: Array | AcquiredIQ, capture: Capture, *, subcarrier_spacing: Meta(description='Subcarrier spacing (15e3, 30e3, 60e3, etc)', extra={'standard_name': 'Subcarrier spacing (15e3, 30e3, 60e3, etc)', 'units': 'Hz'})], sample_rate: float = 7680000.0, discovery_periodicity: float = 0.02, frequency_offset: float = 0, shared_spectrum: bool = False, delay: float = 0, symbol_indexes: 1)'})] = 'auto', max_lag_symbols: Meta(ge=1, le=6, description='limit the number of symbols of lag in the 5G sync correlator', extra={'standard_name': 'limit the number of symbols of lag in the 5G sync correlator'})] | None = None, max_block_count: int | None = 1)¶
correlate each port of the IQ against the 5G NR primary synchronization signal.
The input is the IQ before the analysis_bandwidth filter and before trigger alignment. The band at frequency_offset is shifted to baseband and resampled to sample_rate, then cross-correlated with the PSS sequence of each cell sector ID (3GPP TS 38.211 §7.4.2.2). Per capture, the output is the complex64 correlation (in √mW) with dimensions cellular_cell_id2, cellular_ssb_start_time (in s), cellular_ssb_beam_index, and cellular_ssb_lag (in s). The output keeps the first max_block_count sync blocks. A max_block_count of None keeps every block. The PSS template has unit energy over the 127 PSS subcarriers. The squared magnitude of a peak on a lag sample equals the received PSS symbol power. White noise with power spectral density N0 has a mean squared magnitude of
N0 * subcarrier_spacingin each lag. The noise_bandwidth attr is subcarrier_spacing.References
3GPP TS 38.211, “NR; Physical channels and modulation,” Table 7.4.3.1-1 and §7.4.2.2. https://www.3gpp.org/DynaReport/38211.htm
3GPP TS 38.213, “NR; Physical layer procedures for control,” §4.1. https://www.3gpp.org/DynaReport/38213.htm
- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraysubcarrier_spacing (float) – Subcarrier spacing (15e3, 30e3, 60e3, etc) (Constraints: units: Hz)
sample_rate (float)
discovery_periodicity (float)
frequency_offset (float)
shared_spectrum (bool)
delay (float)
symbol_indexes (one of ['auto', 'a', 'b', 'c', 'd', 'e', 'f', 'g'] | tuple[int, ...]) – index locations in the SSB, or a cell search case from 3GPP TS 38.213 Sec. 4.1)
max_lag_symbols (int | None) – limit the number of symbols of lag in the 5G sync correlator (Constraints: >= 1, <= 6)
max_block_count (int | None)
- striqt.analysis.cellular_5g_pss_sync(iq: Array | AcquiredIQ, capture: Capture, *, subcarrier_spacing: Meta(description='Subcarrier spacing (15e3, 30e3, 60e3, etc)', extra={'standard_name': 'Subcarrier spacing (15e3, 30e3, 60e3, etc)', 'units': 'Hz'})], sample_rate: float = 7680000.0, discovery_periodicity: float = 0.02, frequency_offset: float = 0, shared_spectrum: bool = False, delay: float = 0, symbol_indexes: 1)'})] = 'auto', max_lag_symbols: Meta(ge=1, le=6, description='limit the number of symbols of lag in the 5G sync correlator', extra={'standard_name': 'limit the number of symbols of lag in the 5G sync correlator'})] | None = None, window_fill: Meta(gt=0, le=1, description='Fraction of a symbol to fill with weighting function', extra={'standard_name': 'Fraction of a symbol to fill with weighting function'})] = 1, per_port: Meta(description='whether to evaluate signal synchronization separately on each port', extra={'standard_name': 'whether to evaluate signal synchronization separately on each port'})] = False, max_beams: Meta(gt=0, description='limit the beam count in 5G sync evaluation', extra={'standard_name': 'limit the beam count in 5G sync evaluation'})] | None = None)¶
return the start-of-waveform delay (in s) detected from the PSS correlation.
The input is the IQ before the analysis_bandwidth filter and before trigger alignment. Per capture, the output is one float32 value per port, or one value shared across the ports when per_port is False. The value is the lag chosen from the cellular_5g_pss_correlation output plus delay rounded to a sample at sample_rate. The output is a signal trigger: a source with
signal_triggerset to this measurement aligns the capture by the output.- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraysubcarrier_spacing (float) – Subcarrier spacing (15e3, 30e3, 60e3, etc) (Constraints: units: Hz)
sample_rate (float)
discovery_periodicity (float)
frequency_offset (float)
shared_spectrum (bool)
delay (float)
symbol_indexes (one of ['auto', 'a', 'b', 'c', 'd', 'e', 'f', 'g'] | tuple[int, ...]) – index locations in the SSB, or a cell search case from 3GPP TS 38.213 Sec. 4.1)
max_lag_symbols (int | None) – limit the number of symbols of lag in the 5G sync correlator (Constraints: >= 1, <= 6)
window_fill (float) – Fraction of a symbol to fill with weighting function (Constraints: > 0, <= 1)
per_port (bool) – whether to evaluate signal synchronization separately on each port
max_beams (int | None) – limit the beam count in 5G sync evaluation (Constraints: > 0)
- striqt.analysis.cellular_5g_ssb_spectrogram(iq: Array | AcquiredIQ, capture: Capture, *, subcarrier_spacing: Meta(description='Subcarrier spacing (15e3, 30e3, 60e3, etc)', extra={'standard_name': 'Subcarrier spacing (15e3, 30e3, 60e3, etc)', 'units': 'Hz'})], sample_rate: float = 7680000.0, discovery_periodicity: float = 0.02, frequency_offset: float = 0, max_block_count: int | None = None, window: get_window`'})] = 'blackmanharris', lo_bandstop: Meta(description='mask with float("nan") at this bandwidth centered at baseband DC', extra={'standard_name': 'mask with float("nan") at this bandwidth centered at baseband DC', 'units': 'Hz'})] | None = None)¶
evaluate a spectrogram of each 5G NR SSB burst set by OFDM symbol and subcarrier.
The input is the IQ before the analysis_bandwidth filter and after trigger alignment. The STFT hops once per OFDM symbol. Half-subcarrier bins are summed pairwise to one bin per subcarrier of subcarrier_spacing. The frequency axis is trimmed to the sample_rate band about frequency_offset. Only the symbols of the burst set in the first 2 ms of each discovery_periodicity are kept (3GPP TS 38.213 §4.1).
Per capture, the output is power per subcarrier in dBm in a noise bandwidth of one subcarrier_spacing, with dimensions cellular_ssb_index (burst set within the capture), cellular_ssb_symbol_index (OFDM symbol within the burst set), and cellular_ssb_baseband_frequency (in Hz, relative to frequency_offset). Values are rounded to 3 decimals and stored as float16. The noise_bandwidth and resolution_bandwidth attrs follow the spectrogram measurement.
References
3GPP TS 38.213, “NR; Physical layer procedures for control,” §4.1. https://www.3gpp.org/DynaReport/38213.htm
- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraysubcarrier_spacing (float) – Subcarrier spacing (15e3, 30e3, 60e3, etc) (Constraints: units: Hz)
sample_rate (float)
discovery_periodicity (float)
frequency_offset (float)
max_block_count (int | None)
window (str | tuple[str, float]) – window function specification following scipy.signal.get_window
lo_bandstop (float | None) – mask with float(“nan”) at this bandwidth centered at baseband DC (Constraints: units: Hz)
- striqt.analysis.cellular_5g_sss_correlation(iq: Array | AcquiredIQ, capture: Capture, *, subcarrier_spacing: Meta(description='Subcarrier spacing (15e3, 30e3, 60e3, etc)', extra={'standard_name': 'Subcarrier spacing (15e3, 30e3, 60e3, etc)', 'units': 'Hz'})], sample_rate: float = 7680000.0, discovery_periodicity: float = 0.02, frequency_offset: float = 0, shared_spectrum: bool = False, delay: float = 0, symbol_indexes: 1)'})] = 'auto', max_lag_symbols: Meta(ge=1, le=6, description='limit the number of symbols of lag in the 5G sync correlator', extra={'standard_name': 'limit the number of symbols of lag in the 5G sync correlator'})] | None = None, max_block_count: int | None = 1)¶
correlate each port of the IQ against the 5G NR secondary synchronization signal.
The input is the IQ before the analysis_bandwidth filter and before trigger alignment. The band at frequency_offset is shifted to baseband and resampled to sample_rate, then cross-correlated with the SSS sequences (3GPP TS 38.211 §7.4.2.3). Per capture, the output is the complex64 correlation (in √mW) with dimensions cellular_cell_id2, cellular_ssb_start_time (in s), cellular_ssb_beam_index, and cellular_ssb_lag (in s). The output keeps the first max_block_count sync blocks. A max_block_count of None keeps every block. The SSS template has unit energy over the 127 SSS subcarriers. The squared magnitude of a peak on a lag sample equals the received SSS symbol power. White noise with power spectral density N0 has a mean squared magnitude of
N0 * subcarrier_spacingin each lag. The noise_bandwidth attr is subcarrier_spacing.References
3GPP TS 38.211, “NR; Physical channels and modulation,” Table 7.4.3.1-1 and §7.4.2.3. https://www.3gpp.org/DynaReport/38211.htm
3GPP TS 38.213, “NR; Physical layer procedures for control,” §4.1. https://www.3gpp.org/DynaReport/38213.htm
- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraysubcarrier_spacing (float) – Subcarrier spacing (15e3, 30e3, 60e3, etc) (Constraints: units: Hz)
sample_rate (float)
discovery_periodicity (float)
frequency_offset (float)
shared_spectrum (bool)
delay (float)
symbol_indexes (one of ['auto', 'a', 'b', 'c', 'd', 'e', 'f', 'g'] | tuple[int, ...]) – index locations in the SSB, or a cell search case from 3GPP TS 38.213 Sec. 4.1)
max_lag_symbols (int | None) – limit the number of symbols of lag in the 5G sync correlator (Constraints: >= 1, <= 6)
max_block_count (int | None)
- striqt.analysis.cellular_cyclic_autocorrelation(iq: Array | AcquiredIQ, capture: Capture, *, subcarrier_spacings: Meta(description='One or more subcarrier spacings (15e3, 30e3, 60e3, etc)', extra={'standard_name': 'One or more subcarrier spacings (15e3, 30e3, 60e3, etc)', 'units': 'Hz'})] = (15000.0, 30000.0, 60000.0), frame_range: int | tuple[int, int] = (0, 1), frame_slots: Meta(description="string composed of ('d', 'u', 's') specifying the sequence of slots in 1 TDD cellular frame, or None to fill with downlink", extra={'standard_name': "string composed of ('d', 'u', 's') specifying the sequence of slots in 1 TDD cellular frame, or None to fill with downlink"})] = None, symbol_range: int | tuple[int, int | None] = (0, None), generation: Literal['4G', '5G'] = '5G')¶
evaluate the cyclic-prefix autocorrelation of the IQ at each 4G or 5G symbol lag.
The input is the IQ after the analysis_bandwidth filter and before trigger alignment. For each spacing in subcarrier_spacings, the IQ is correlated with a copy of the IQ delayed by the OFDM symbol length, summed over the cyclic-prefix samples of the symbols that frame_range and symbol_range select. The downlink slots and the uplink slots of frame_slots are summed separately. Per capture, the output is the correlation magnitude in mW as float32 with dimensions
(link_direction, subcarrier_spacing, cyclic_sample_lag). cyclic_sample_lag (in s) spans the longest symbol over the spacings. Entries past the symbol length of a spacing arenan, as is the'uplink'row when frame_slots has no uplink slot. frame_range and symbol_range are a count of indexes from 0, or a(start, stop)pair as for the Python builtin range.- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraysubcarrier_spacings (float | tuple[float, ...]) – One or more subcarrier spacings (15e3, 30e3, 60e3, etc) (Constraints: units: Hz)
frame_range (int | tuple[int, int])
frame_slots (str | None) – string composed of (‘d’, ‘u’, ‘s’) specifying the sequence of slots in 1 TDD cellular frame, or None to fill with downlink
symbol_range (int | tuple[int, int | None])
generation (one of ['4G', '5G'])
- striqt.analysis.cellular_resource_power_histogram(iq: Array | AcquiredIQ, capture: Capture, *, window: get_window`'})], subcarrier_spacing: Meta(description='Subcarrier spacing (15e3, 30e3, 60e3, etc)', extra={'standard_name': 'Subcarrier spacing (15e3, 30e3, 60e3, etc)', 'units': 'Hz'})], power_low: Meta(description='Minimum power bin', extra={'standard_name': 'Minimum power bin', 'units': 'dB power'})], power_high: Meta(description='Maximum power bin', extra={'standard_name': 'Maximum power bin', 'units': 'dB power'})], power_resolution: Meta(description='Power bin resolution', extra={'standard_name': 'Power bin resolution', 'units': 'dB'})], average_rbs: Meta(description="frequency resolution of the spectrogram: False for 1 subcarrier, True for 1 resource block (12 subcarriers), or 'half' for 6 subcarriers", extra={'standard_name': "frequency resolution of the spectrogram: False for 1 subcarrier, True for 1 resource block (12 subcarriers), or 'half' for 6 subcarriers"})] = False, average_slots: Meta(description='True to coarsen spectrogram bins by averaging 1-symbol time resolution', extra={'standard_name': 'True to coarsen spectrogram bins by averaging 1-symbol time resolution'})] = False, guard_bandwidths: Meta(description='Bandwidths excluded at the (low, high) edges of the analysis band', extra={'standard_name': 'Bandwidths excluded at the (low, high) edges of the analysis band', 'units': 'Hz'})] = (0, 0), frame_slots: Meta(description="string composed of ('d', 'u', 's') specifying the sequence of slots in 1 TDD cellular frame, or None to fill with downlink", extra={'standard_name': "string composed of ('d', 'u', 's') specifying the sequence of slots in 1 TDD cellular frame, or None to fill with downlink"})] = None, special_symbols: Meta(description="string composed of the characters ('d', 'u', 'f') indicating the sequence of symbol types (when 's' is in frame_slots)", extra={'standard_name': "string composed of the characters ('d', 'u', 'f') indicating the sequence of symbol types (when 's' is in frame_slots)"})] = None, cyclic_prefix: 2-1)'})] = 'normal', lo_bandstop: Meta(description='mask with float("nan") at this bandwidth centered at baseband DC', extra={'standard_name': 'mask with float("nan") at this bandwidth centered at baseband DC', 'units': 'Hz'})] | None = None)¶
evaluate the fraction of resource grid elements in each power bin per link.
The input is the IQ before the analysis_bandwidth filter and after trigger alignment. A spectrogram with one bin per subcarrier (or per resource block, with average_rbs) and one hop per OFDM symbol is split into downlink and uplink symbols by frame_slots and special_symbols. With average_slots, the power is averaged over each slot. The power is converted to dBm before binning. Per capture, the output is float32 with dimensions link_direction and cellular_resource_power_bin (in dBm per bin bandwidth). The fractions of both link directions together sum to 1 on each port. Subcarriers inside the guard_bandwidths and flexible symbols are excluded from the count.
- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraywindow (str | tuple[str, float]) – window function specification following scipy.signal.get_window
subcarrier_spacing (float) – Subcarrier spacing (15e3, 30e3, 60e3, etc) (Constraints: units: Hz)
power_low (float) – Minimum power bin (Constraints: units: dB power)
power_high (float) – Maximum power bin (Constraints: units: dB power)
power_resolution (float) – Power bin resolution (Constraints: units: dB)
average_rbs (bool | one of ['half']) – frequency resolution of the spectrogram: False for 1 subcarrier, True for 1 resource block (12 subcarriers), or ‘half’ for 6 subcarriers
average_slots (bool) – True to coarsen spectrogram bins by averaging 1-symbol time resolution
guard_bandwidths (tuple[float, float]) – Bandwidths excluded at the (low, high) edges of the analysis band (Constraints: units: Hz)
frame_slots (str | None) – string composed of (‘d’, ‘u’, ‘s’) specifying the sequence of slots in 1 TDD cellular frame, or None to fill with downlink
special_symbols (str | None) – string composed of the characters (‘d’, ‘u’, ‘f’) indicating the sequence of symbol types (when ‘s’ is in frame_slots)
cyclic_prefix (one of ['normal', 'extended']) – cyclic prefix length of the 3GPP numerology (TS 38.211 Table 4.2-1)
lo_bandstop (float | None) – mask with float(“nan”) at this bandwidth centered at baseband DC (Constraints: units: Hz)
- striqt.analysis.channel_power_histogram(iq: Array | AcquiredIQ, capture: Capture, *, detector_period: Meta(description='Power detector bin duration, a whole multiple of the sample period', extra={'standard_name': 'Power detector bin duration, a whole multiple of the sample period', 'units': 's'})], power_detectors: Meta(description="Power detectors evaluated in each bin: 'rms', 'peak', or both", extra={'standard_name': "Power detectors evaluated in each bin: 'rms', 'peak', or both"})] = ('rms', 'peak'), power_low: Meta(description='Minimum power bin', extra={'standard_name': 'Minimum power bin', 'units': 'dB power'})], power_high: Meta(description='Maximum power bin', extra={'standard_name': 'Maximum power bin', 'units': 'dB power'})], power_resolution: Meta(description='Power bin resolution', extra={'standard_name': 'Power bin resolution', 'units': 'dB'})])¶
evaluate the fraction of channel power readings that fall in each power bin.
The input is the IQ after the analysis_bandwidth filter and trigger alignment. The readings are those of channel_power_time_series with the same detector fields. Per capture, the output has dimensions
(power_detector, channel_power_bin)as float32 and sums to 1 over the bins of each detector. channel_power_bin is the bin centers in dBm. The-infandinfentries collect the readings more than half a bin below power_low or above power_high. Neither the output nor the bin coordinate has a noise_bandwidth attr. The noise bandwidth of each capture is the analysis_bandwidth coordinate, or sample_rate where analysis_bandwidth is infinite.- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraydetector_period (Fraction) – Power detector bin duration, a whole multiple of the sample period (Constraints: units: s)
power_detectors (tuple[str, ...]) – Power detectors evaluated in each bin: ‘rms’, ‘peak’, or both
power_low (float) – Minimum power bin (Constraints: units: dB power)
power_high (float) – Maximum power bin (Constraints: units: dB power)
power_resolution (float) – Power bin resolution (Constraints: units: dB)
- striqt.analysis.channel_power_time_series(iq: Array | AcquiredIQ, capture: Capture, *, detector_period: Meta(description='Power detector bin duration, a whole multiple of the sample period', extra={'standard_name': 'Power detector bin duration, a whole multiple of the sample period', 'units': 's'})], power_detectors: Meta(description="Power detectors evaluated in each bin: 'rms', 'peak', or both", extra={'standard_name': "Power detectors evaluated in each bin: 'rms', 'peak', or both"})] = ('rms', 'peak'))¶
evaluate a time series of binned channel power for each power detector.
The input is the IQ after the analysis_bandwidth filter and trigger alignment. Each detector reduces the instantaneous power
|iq|**2over consecutive blocks of detector_period:'rms'is the mean and'peak'the maximum. Per capture, the output has dimensions(power_detector, time_elapsed)in dBm as float32. time_elapsed is in s from the start of the capture in steps of detector_period. The capture duration must be a whole number of detector periods. detector_period must be a whole number of samples at sample_rate. The output has no noise_bandwidth attr. The noise bandwidth of each capture is the analysis_bandwidth coordinate, or sample_rate where analysis_bandwidth is infinite.- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraydetector_period (Fraction) – Power detector bin duration, a whole multiple of the sample period (Constraints: units: s)
power_detectors (tuple[str, ...]) – Power detectors evaluated in each bin: ‘rms’, ‘peak’, or both
- striqt.analysis.cyclic_channel_power(iq: Array | AcquiredIQ, capture: Capture, *, cyclic_period: Meta(description='Cycle period of the channel power statistics, a whole multiple of `detector_period` and a common multiple of the expected signal periods', extra={'standard_name': 'Cycle period of the channel power statistics, a whole multiple of `detector_period` and a common multiple of the expected signal periods', 'units': 's'})], detector_period: Meta(description='Power detector bin duration, a whole multiple of the sample period', extra={'standard_name': 'Power detector bin duration, a whole multiple of the sample period', 'units': 's'})], power_detectors: Meta(description="Power detectors evaluated in each bin: 'rms', 'peak', or both", extra={'standard_name': "Power detectors evaluated in each bin: 'rms', 'peak', or both"})] = ('rms', 'peak'), cyclic_statistics: Meta(description="Statistics evaluated across cycles at each cycle lag: 'min', 'mean', 'max', 'median', or a quantile in (0, 1)", extra={'standard_name': "Statistics evaluated across cycles at each cycle lag: 'min', 'mean', 'max', 'median', or a quantile in (0, 1)"})] = ('min', 'mean', 'max'))¶
evaluate cyclic statistics of channel power across the cycles in a capture.
The input is the IQ after the analysis_bandwidth filter and trigger alignment. Each power detector bins the capture on detector_period. The binned series is folded into cycles of cyclic_period. Each cyclic statistic reduces across the cycles (Kuester et al.). Per capture, the output has dimensions
(power_detector, cyclic_statistic, cyclic_lag)in dBm as float32. The cyclic_lag coordinate in s starts at 0 and spans one cyclic_period in steps of detector_period. Those 2 fields alone set the trace length, independent of the capture duration.A signal with a period that divides cyclic_period (10 ms covers TDD cellular frames, 5 ms WiMAX frames, and the 1 ms CBRS test
bin 1pulse repetition interval) resolves at fixed lags with little spread between the'min'and'max'statistics. The uplink and downlink levels of a TDD network then occupy disjoint lag windows. Occupancy with an incommensurate period smears across all lags.Statistics are evaluated in linear power and converted to dBm afterward. The capture duration must be a whole number of cycles. cyclic_period must be a whole number of detector periods, and detector_period a whole number of samples at sample_rate. A detector_period written as a fraction (
1/28000s is one OFDM symbol at 30 kHz subcarrier spacing) stays exact. The output has no noise_bandwidth attr, as for channel_power_time_series.References
Kuester et al., “Cyclic Analysis of Power in Radio Channels.”
- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraycyclic_period (float) – Cycle period of the channel power statistics, a whole multiple of detector_period and a common multiple of the expected signal periods (Constraints: units: s)
detector_period (Fraction) – Power detector bin duration, a whole multiple of the sample period (Constraints: units: s)
power_detectors (tuple[str, ...]) – Power detectors evaluated in each bin: ‘rms’, ‘peak’, or both
cyclic_statistics (tuple[str | float, ...]) – Statistics evaluated across cycles at each cycle lag: ‘min’, ‘mean’, ‘max’, ‘median’, or a quantile in (0, 1)
- striqt.analysis.dBlinmean(x_dB: _ALD, axis: Dims | int | Sequence[int] | None = None, overwrite_x: bool = False, min_dtype: DTypeLike = 'float32') _ALD¶
evaluate the mean in linear power space given power in dB.
- This is equivalent to:
powtodB(dBtopow(x).mean(axis))
- Returns:
array-like object with same shape as x_dB, reduced by the dimension at the specified axes
- striqt.analysis.dBlinsum(x_dB: _ALD, axis: Dims | int | Sequence[int] | None = None, overwrite_x: bool = False, min_dtype: DTypeLike = 'float32') _ALD¶
evaluate the sum in linear power space given power in dB.
- This is equivalent to:
powtodB(dBtopow(x).sum(axis))
- Returns:
array-like object with same shape as x_dB, reduced by the dimension at the specified axes
- striqt.analysis.dBtopow(x: _ALN, *, overwrite_x: bool = False, min_dtype: DTypeLike = 'float32') _ALN¶
compute
10**(x/10).The computation is elementwise in a floating-point dtype no narrower than min_dtype.
- Parameters:
x – values in dB, as a number, array, or pandas/xarray object
overwrite_x – True to write the result into x when the dtype of x is at least min_dtype
min_dtype – the narrowest floating-point dtype of the computation; a narrower x is widened to min_dtype
- Returns:
a Python number for a number, otherwise the array, pandas, or xarray type of x. An xarray
unitsattribute is converted from dB to linear power.- Return type:
the values in linear power units, in the container type of x
- Raises:
TypeError – if min_dtype is None or narrower than float32, or if no array can be associated with the type of x
- striqt.analysis.dump(store: ZarrStore, data: xr.DataArray | xr.Dataset, *, append_dim: str = 'capture', compression: bool = True, zarr_format: ZarrFormat = 'auto', compute: bool = True, chunk_bytes: ChunksSize = 50000000, max_threads: int | None = None, **kwargs) ZarrStore¶
serialize a dataset into a zarr directory or zipfile
- striqt.analysis.envtodB(x: _ALN, *, abs: bool = True, bounded: bool = False, overwrite_x: bool = False, min_dtype: DTypeLike = 'float32') _ALN¶
compute
20*log10(abs(x)), or20*log10(x)when abs is False.The computation is elementwise in a floating-point dtype no narrower than min_dtype.
- Parameters:
x – values in linear amplitude (envelope) units, as a number, array, or pandas/xarray object
abs – True to convert
abs(x); a complex x is converted by magnitude in either casebounded – True to floor the result at the same dB value as powtodB with bounded,
10*log10(tiny)for the smallest normal valuetinyof the computation dtype; zeros then map to the floor instead of-infoverwrite_x – True to write the result into x when the dtype of x is at least min_dtype; a complex x is then returned as the real view of the buffer of x
min_dtype – the narrowest floating-point dtype of the computation; a narrower x is widened to min_dtype
- Returns:
a Python number for a number, otherwise the array, pandas, or xarray type of x. An xarray
unitsattribute is converted from amplitude to dB.- Return type:
the dB values, real-valued, in the container type of x
- Raises:
TypeError – if min_dtype is None or narrower than float32, or if no array can be associated with the type of x
- striqt.analysis.envtopow(x: _ALN, *, overwrite_x: bool = False, min_dtype: DTypeLike = 'float32') _ALN¶
compute
abs(x)**2.The computation is elementwise in a floating-point dtype no narrower than min_dtype.
- Parameters:
x – values in linear amplitude (envelope) units, real or complex, as a number, array, or pandas/xarray object
overwrite_x – True to write the result into x when the dtype of x is at least min_dtype; a complex x is then returned as the real view of the buffer of x
min_dtype – the narrowest floating-point dtype of the computation; a narrower x is widened to min_dtype
- Returns:
a Python number for a number, otherwise the array, pandas, or xarray type of x. An xarray
unitsattribute is converted from amplitude to linear power.- Return type:
the power values, real-valued, in the container type of x
- Raises:
TypeError – if min_dtype is None or narrower than float32, or if no array can be associated with the type of x
- striqt.analysis.iq_waveform(iq: Array | AcquiredIQ, capture: Capture, *, start_time_sec: float | None = None, stop_time_sec: float | None = None)¶
return the IQ samples between start_time_sec and stop_time_sec.
The input is the IQ after the analysis_bandwidth filter and trigger alignment. Per capture, the output has the dimension
(iq_index,)of sample indexes into the capture. The values are complex64 in √mW. The squared magnitude|iq|**2is power in mW. A None time bound selects the start or the end of the capture. A bound outside the capture is clamped to the capture. The output has no noise_bandwidth attr. The noise bandwidth of each capture is the analysis_bandwidth coordinate, or sample_rate where analysis_bandwidth is infinite.- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraystart_time_sec (float | None)
stop_time_sec (float | None)
- striqt.analysis.load(path: str | Path, chunks: ChunksSize = None, **kwargs) xr.Dataset¶
load and return a dataset or data array.
- Parameters:
path – location of the data store, potentially an fsspec string
chunks – None to load the file without dask, or ‘auto’ to return a dask array with automatically selected chunk sizes
kwargs – Additional arguments passed into xr.open_dataset
- Returns:
The opened dataset object.
- striqt.analysis.open_store(target: str | Path, *, mode: Literal['r', 'w', 'a']) ZarrStore¶
- striqt.analysis.power_spectral_density(iq: Array | AcquiredIQ, capture: Capture, *, window: get_window`'})], frequency_resolution: float, fractional_overlap: Fraction = 0, window_fill: Fraction = 1, integration_bandwidth: float | None = None, trim_stopband: bool = True, lo_bandstop: Meta(description='mask with float("nan") at this bandwidth centered at baseband DC', extra={'standard_name': 'mask with float("nan") at this bandwidth centered at baseband DC', 'units': 'Hz'})] | None = None, time_statistic: tuple[str | float, ...] = ('mean',))¶
estimate the power spectral density from time statistics of the spectrogram.
The input is the IQ before the analysis_bandwidth filter and after trigger alignment. Each time_statistic reduces the spectrogram output with the same STFT fields (linear power, unrounded) over the STFT windows at each frequency bin.
'mean'is the Welch estimate (Welch, 1967). A float in[0, 1]is a quantile. Per capture, the output has dimensions(time_statistic, baseband_frequency)in dBm per noise bandwidth as float32. The noise_bandwidth attr is that bandwidth in Hz. A power spectral density in dBm/Hz is the output minus10 * log10(noise_bandwidth).References
P. D. Welch, “The use of fast Fourier transform for the estimation of power spectra: A method based on time averaging over short, modified periodograms,” IEEE Trans. Audio Electroacoust., vol. 15, no. 2, pp. 70-73, 1967. doi:10.1109/TAU.1967.1161901
- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraywindow (str | tuple[str, float]) – window function specification following scipy.signal.get_window
frequency_resolution (float)
fractional_overlap (Fraction)
window_fill (Fraction)
integration_bandwidth (float | None)
trim_stopband (bool)
lo_bandstop (float | None) – mask with float(“nan”) at this bandwidth centered at baseband DC (Constraints: units: Hz)
time_statistic (tuple[str | float, ...])
- striqt.analysis.powtodB(x: _ALN, *, abs: bool = True, bounded: bool = False, overwrite_x: bool = False, min_dtype: DTypeLike = 'float32') _ALN¶
compute
10*log10(abs(x)), or10*log10(x)when abs is False.The computation is elementwise in a floating-point dtype no narrower than min_dtype.
- Parameters:
x – values in linear power units, as a number, array, or pandas/xarray object
abs – True to convert
abs(x); a complex x is converted by magnitude in either casebounded – True to floor the result at
10*log10(tiny), wheretinyis the smallest normal value of the computation dtype (about -379 dB in float32 and -3077 dB in float64); zeros then map to the floor instead of-infoverwrite_x – True to write the result into x when the dtype of x is at least min_dtype; a complex x is then returned as the real view of the buffer of x
min_dtype – the narrowest floating-point dtype of the computation; a narrower x is widened to min_dtype
- Returns:
a Python number for a number, otherwise the array, pandas, or xarray type of x. An xarray
unitsattribute is converted from linear power to dB.- Return type:
the dB values, real-valued, in the container type of x
- Raises:
TypeError – if min_dtype is None or narrower than float32, or if no array can be associated with the type of x
- striqt.analysis.spectrogram(iq: Array | AcquiredIQ, capture: Capture, *, window: get_window`'})], frequency_resolution: float, fractional_overlap: Fraction = 0, window_fill: Fraction = 1, integration_bandwidth: float | None = None, trim_stopband: bool = True, lo_bandstop: Meta(description='mask with float("nan") at this bandwidth centered at baseband DC', extra={'standard_name': 'mask with float("nan") at this bandwidth centered at baseband DC', 'units': 'Hz'})] | None = None, time_aperture: float | None = None)¶
evaluate a power spectrogram of the IQ by STFT.
The input is the IQ before the analysis_bandwidth filter and after trigger alignment. The output array namespace (numpy or cupy) follows the input. Per capture, the output has dimensions
(spectrogram_time, spectrogram_baseband_frequency). spectrogram_time in s runs from the start of the capture at the STFT hop, which fractional_overlap and frequency_resolution set. spectrogram_baseband_frequency in Hz is the FFT grid at frequency_resolution, truncated to the analysis_bandwidth about DC when trim_stopband is set and the bandwidth is finite. Values are power in dBm per noise bandwidth, which is frequency_resolution or, when set, integration_bandwidth. The noise_bandwidth attr is that bandwidth in Hz. long_name names the bandwidth. White noise with power spectral density N0 has a mean ofN0 * noise_bandwidthin every bin for every window. A CW tone hasfrequency_resolution / resolution_bandwidthof the tone power in one bin, where the resolution_bandwidth attr is the equivalent noise bandwidth (in Hz) of the zero-padded window. Values are rounded to 2 decimals and stored as float16.- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraywindow (str | tuple[str, float]) – window function specification following scipy.signal.get_window
frequency_resolution (float)
fractional_overlap (Fraction)
window_fill (Fraction)
integration_bandwidth (float | None)
trim_stopband (bool)
lo_bandstop (float | None) – mask with float(“nan”) at this bandwidth centered at baseband DC (Constraints: units: Hz)
time_aperture (float | None)
- striqt.analysis.spectrogram_histogram(iq: Array | AcquiredIQ, capture: Capture, *, window: get_window`'})], frequency_resolution: float, fractional_overlap: Fraction = 0, window_fill: Fraction = 1, integration_bandwidth: float | None = None, trim_stopband: bool = True, lo_bandstop: Meta(description='mask with float("nan") at this bandwidth centered at baseband DC', extra={'standard_name': 'mask with float("nan") at this bandwidth centered at baseband DC', 'units': 'Hz'})] | None = None, time_aperture: float | None = None, power_low: Meta(description='Minimum power bin', extra={'standard_name': 'Minimum power bin', 'units': 'dB power'})], power_high: Meta(description='Maximum power bin', extra={'standard_name': 'Maximum power bin', 'units': 'dB power'})], power_resolution: Meta(description='Power bin resolution', extra={'standard_name': 'Power bin resolution', 'units': 'dB'})])¶
evaluate the fraction of spectrogram pixels that fall in each power bin.
The input is the IQ before the analysis_bandwidth filter and after trigger alignment. The pixels are those of the spectrogram output with the same STFT fields (float32, unrounded), flattened over time and frequency. Per capture, the output has the dimension
(spectrogram_power_bin,)as float32 and sums to 1. spectrogram_power_bin is the bin centers in dBm per noise bandwidth. The-infandinfentries collect the pixels more than half a bin below power_low or above power_high. The noise_bandwidth attr (in Hz) is set on the output and on the bin coordinate.- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraywindow (str | tuple[str, float]) – window function specification following scipy.signal.get_window
frequency_resolution (float)
fractional_overlap (Fraction)
window_fill (Fraction)
integration_bandwidth (float | None)
trim_stopband (bool)
lo_bandstop (float | None) – mask with float(“nan”) at this bandwidth centered at baseband DC (Constraints: units: Hz)
time_aperture (float | None)
power_low (float) – Minimum power bin (Constraints: units: dB power)
power_high (float) – Maximum power bin (Constraints: units: dB power)
power_resolution (float) – Power bin resolution (Constraints: units: dB)
- striqt.analysis.spectrogram_ratio_histogram(iq: Array | AcquiredIQ, capture: Capture, *, window: get_window`'})], frequency_resolution: float, fractional_overlap: Fraction = 0, window_fill: Fraction = 1, integration_bandwidth: float | None = None, trim_stopband: bool = True, lo_bandstop: Meta(description='mask with float("nan") at this bandwidth centered at baseband DC', extra={'standard_name': 'mask with float("nan") at this bandwidth centered at baseband DC', 'units': 'Hz'})] | None = None, time_aperture: float | None = None, power_low: Meta(description='Minimum power bin', extra={'standard_name': 'Minimum power bin', 'units': 'dB power'})], power_high: Meta(description='Maximum power bin', extra={'standard_name': 'Maximum power bin', 'units': 'dB power'})], power_resolution: Meta(description='Power bin resolution', extra={'standard_name': 'Power bin resolution', 'units': 'dB'})])¶
evaluate a histogram of the spectrogram power ratio between 2 ports.
The input is the IQ before the analysis_bandwidth filter and after trigger alignment. The spectrograms are the spectrogram output with the same STFT fields (float32, unrounded). The ratio is the pixel-by-pixel difference of the two spectrograms in dB. Per capture, the output has the dimension
(spectrogram_ratio_power_bin,)as float32, with bin centers in dB. The first output port is the ratio of the first input port to the second. The second output port is the negative of the first. Normalization and the catch-all bins follow spectrogram_histogram. Neither the output nor the bin coordinate has a noise_bandwidth attr.- Raises:
ValueError – if the capture has a port count other than 2
- Parameters:
iq (Array or AcquiredIQ) – IQ waveform of shape (port, sample), or an AcquiredIQ from which the conditioned waveform is selected
capture (striqt.analysis.specs.Capture) – the acquisition parameters of iq
as_xarray ((bool or 'delayed')) – True for an xarray.DataArray, False for an
(array, attrs)tuple, or ‘delayed’ for a DelayedDataArraywindow (str | tuple[str, float]) – window function specification following scipy.signal.get_window
frequency_resolution (float)
fractional_overlap (Fraction)
window_fill (Fraction)
integration_bandwidth (float | None)
trim_stopband (bool)
lo_bandstop (float | None) – mask with float(“nan”) at this bandwidth centered at baseband DC (Constraints: units: Hz)
time_aperture (float | None)
power_low (float) – Minimum power bin (Constraints: units: dB power)
power_high (float) – Maximum power bin (Constraints: units: dB power)
power_resolution (float) – Power bin resolution (Constraints: units: dB)
striqt.analysis.specs¶
- class striqt.analysis.specs.Analysis¶
Bases:
SpecBasethe base of every measurement spec.
The fields of a subclass are the keyword arguments of one measurement.
- class striqt.analysis.specs.AnalysisCapture(*, duration=0.1, sample_rate=15360000.0, analysis_bandwidth=inf, center_frequency=None)¶
Bases:
Capturethe projection of a capture onto the fields that a measurement may read.
Two captures with equal values in these fields project to equal instances.
- Parameters:
duration (float) – Duration of the analysis waveform (Constraints: units: s)
sample_rate (float) – Sample rate of the analyzed IQ waveform (Constraints: > 0, units: S/s)
analysis_bandwidth (float) – Analysis bandwidth (Constraints: units: Hz)
center_frequency (float | tuple[float, ...] | None) – Center frequency for each port (Constraints: units: Hz, > 0, units: Hz, > 0, units: Hz)
- class striqt.analysis.specs.AnalysisFilter(*, nfft=8192, window='hamming', nfft_out=None)¶
Bases:
SpecBase- Parameters:
nfft (int)
window (str | tuple[str, float]) – window function specification following scipy.signal.get_window
nfft_out (int | None)
- class striqt.analysis.specs.AnalysisGroup¶
Bases:
SpecBasebase class for a defining set of Analysis specs
- class striqt.analysis.specs.BuiltinAnalyses(*, channel_power_time_series=None, channel_power_histogram=None, cyclic_channel_power=None, spectrogram=None, power_spectral_density=None, spectrogram_histogram=None, spectrogram_ratio_histogram=None, cellular_5g_pss_sync=None, cellular_5g_pss_correlation=None, cellular_5g_sss_sync=None, cellular_5g_sss_correlation=None, cellular_5g_ssb_spectrogram=None, cellular_cyclic_autocorrelation=None, cellular_resource_power_histogram=None, iq_waveform=None)¶
Bases:
AnalysisGroupthe
analysis:block of a sweep: one optional field per registered measurement.A field set to a spec enables the measurement with those parameters, and
Noneleaves the measurement out. to_dict omits theNonefields.- Parameters:
channel_power_time_series (ChannelPowerTimeSeries | None)
channel_power_histogram (ChannelPowerHistogram | None)
cyclic_channel_power (CyclicChannelPower | None)
spectrogram (Spectrogram | None)
power_spectral_density (PowerSpectralDensity | None)
spectrogram_histogram (SpectrogramHistogram | None)
spectrogram_ratio_histogram (SpectrogramHistogramRatio | None)
cellular_5g_pss_sync (Cellular5GNPSSSync | None)
cellular_5g_pss_correlation (Cellular5GNRPSSCorrelator | None)
cellular_5g_sss_sync (Cellular5GNSSSSync | None)
cellular_5g_sss_correlation (Cellular5GNRSSSCorrelator | None)
cellular_5g_ssb_spectrogram (Cellular5GNRSSBSpectrogram | None)
cellular_cyclic_autocorrelation (CellularCyclicAutocorrelator | None)
cellular_resource_power_histogram (CellularResourcePowerHistogram | None)
iq_waveform (IQWaveform | None)
- class striqt.analysis.specs.BuiltinTriggers(*, cellular_5g_pss_sync=None, cellular_5g_sss_sync=None)¶
Bases:
AnalysisGroupthe struct form of the
signal_trigger:field of a source.One optional field per trigger, and exactly one is set. The set field names the trigger, and the value is the spec of the trigger measurement. With this form, the
analysis:block need not enable the trigger measurement. The string form ofsignal_triggernames a registered trigger and takes the spec from theanalysis:block.- Parameters:
cellular_5g_pss_sync (Cellular5GNPSSSync | None)
cellular_5g_sss_sync (Cellular5GNSSSSync | None)
- class striqt.analysis.specs.Capture(*, duration=0.1, sample_rate=15360000.0, analysis_bandwidth=inf)¶
Bases:
SpecBasebare minimum information about an IQ acquisition
- Parameters:
duration (float) – Duration of the analysis waveform (Constraints: units: s)
sample_rate (float) – Sample rate of the analyzed IQ waveform (Constraints: > 0, units: S/s)
analysis_bandwidth (float) – Analysis bandwidth (Constraints: units: Hz)
- class striqt.analysis.specs.Cellular5GNPSSSync(*, subcarrier_spacing, sample_rate=7680000.0, discovery_periodicity=0.02, frequency_offset=0, shared_spectrum=False, delay=0, symbol_indexes='auto', max_lag_symbols=None, window_fill=1, per_port=False, max_beams=None)¶
Bases:
_Cellular5GNRSSBSync- Parameters:
subcarrier_spacing (float) – Subcarrier spacing (15e3, 30e3, 60e3, etc) (Constraints: units: Hz)
sample_rate (float)
discovery_periodicity (float)
frequency_offset (float)
shared_spectrum (bool)
delay (float)
symbol_indexes (one of ['auto', 'a', 'b', 'c', 'd', 'e', 'f', 'g'] | tuple[int, ...]) – index locations in the SSB, or a cell search case from 3GPP TS 38.213 Sec. 4.1)
max_lag_symbols (int | None) – limit the number of symbols of lag in the 5G sync correlator (Constraints: >= 1, <= 6)
window_fill (float) – Fraction of a symbol to fill with weighting function (Constraints: > 0, <= 1)
per_port (bool) – whether to evaluate signal synchronization separately on each port
max_beams (int | None) – limit the beam count in 5G sync evaluation (Constraints: > 0)
- class striqt.analysis.specs.Cellular5GNRPSSCorrelator(*, subcarrier_spacing, sample_rate=7680000.0, discovery_periodicity=0.02, frequency_offset=0, shared_spectrum=False, delay=0, symbol_indexes='auto', max_lag_symbols=None, max_block_count=1)¶
Bases:
_Cellular5GNRSSBCorrelator- Parameters:
subcarrier_spacing (float) – Subcarrier spacing (15e3, 30e3, 60e3, etc) (Constraints: units: Hz)
sample_rate (float)
discovery_periodicity (float)
frequency_offset (float)
shared_spectrum (bool)
delay (float)
symbol_indexes (one of ['auto', 'a', 'b', 'c', 'd', 'e', 'f', 'g'] | tuple[int, ...]) – index locations in the SSB, or a cell search case from 3GPP TS 38.213 Sec. 4.1)
max_lag_symbols (int | None) – limit the number of symbols of lag in the 5G sync correlator (Constraints: >= 1, <= 6)
max_block_count (int | None)
- class striqt.analysis.specs.Cellular5GNRSSBSpectrogram(*, subcarrier_spacing, sample_rate=7680000.0, discovery_periodicity=0.02, frequency_offset=0, max_block_count=None, window='blackmanharris', lo_bandstop=None)¶
Bases:
Analysissample_rate (float): output sample rate for the resampled synchronization waveform (samples/s) discovery_periodicity (float): time period between synchronization blocks (s) frequency_offset (float or dict[float, float]):
center frequency offset (see notes)
max_block_count: number of synchronization blocks to evaluate
- Parameters:
subcarrier_spacing (float) – Subcarrier spacing (15e3, 30e3, 60e3, etc) (Constraints: units: Hz)
sample_rate (float)
discovery_periodicity (float)
frequency_offset (float)
max_block_count (int | None)
window (str | tuple[str, float]) – window function specification following scipy.signal.get_window
lo_bandstop (float | None) – mask with float(“nan”) at this bandwidth centered at baseband DC (Constraints: units: Hz)
- class striqt.analysis.specs.Cellular5GNRSSSCorrelator(*, subcarrier_spacing, sample_rate=7680000.0, discovery_periodicity=0.02, frequency_offset=0, shared_spectrum=False, delay=0, symbol_indexes='auto', max_lag_symbols=None, max_block_count=1)¶
Bases:
_Cellular5GNRSSBCorrelator- Parameters:
subcarrier_spacing (float) – Subcarrier spacing (15e3, 30e3, 60e3, etc) (Constraints: units: Hz)
sample_rate (float)
discovery_periodicity (float)
frequency_offset (float)
shared_spectrum (bool)
delay (float)
symbol_indexes (one of ['auto', 'a', 'b', 'c', 'd', 'e', 'f', 'g'] | tuple[int, ...]) – index locations in the SSB, or a cell search case from 3GPP TS 38.213 Sec. 4.1)
max_lag_symbols (int | None) – limit the number of symbols of lag in the 5G sync correlator (Constraints: >= 1, <= 6)
max_block_count (int | None)
- class striqt.analysis.specs.Cellular5GNSSSSync(*, subcarrier_spacing, sample_rate=7680000.0, discovery_periodicity=0.02, frequency_offset=0, shared_spectrum=False, delay=0, symbol_indexes='auto', max_lag_symbols=None, window_fill=1, per_port=False, max_beams=None)¶
Bases:
_Cellular5GNRSSBSync- Parameters:
subcarrier_spacing (float) – Subcarrier spacing (15e3, 30e3, 60e3, etc) (Constraints: units: Hz)
sample_rate (float)
discovery_periodicity (float)
frequency_offset (float)
shared_spectrum (bool)
delay (float)
symbol_indexes (one of ['auto', 'a', 'b', 'c', 'd', 'e', 'f', 'g'] | tuple[int, ...]) – index locations in the SSB, or a cell search case from 3GPP TS 38.213 Sec. 4.1)
max_lag_symbols (int | None) – limit the number of symbols of lag in the 5G sync correlator (Constraints: >= 1, <= 6)
window_fill (float) – Fraction of a symbol to fill with weighting function (Constraints: > 0, <= 1)
per_port (bool) – whether to evaluate signal synchronization separately on each port
max_beams (int | None) – limit the beam count in 5G sync evaluation (Constraints: > 0)
- class striqt.analysis.specs.CellularCyclicAutocorrelator(*, subcarrier_spacings=(15000.0, 30000.0, 60000.0), frame_range=(0, 1), frame_slots=None, symbol_range=(0, None), generation='5G')¶
Bases:
Analysis- Parameters:
subcarrier_spacings (float | tuple[float, ...]) – One or more subcarrier spacings (15e3, 30e3, 60e3, etc) (Constraints: units: Hz)
frame_range (int | tuple[int, int])
frame_slots (str | None) – string composed of (‘d’, ‘u’, ‘s’) specifying the sequence of slots in 1 TDD cellular frame, or None to fill with downlink
symbol_range (int | tuple[int, int | None])
generation (one of ['4G', '5G'])
- class striqt.analysis.specs.CellularResourcePowerHistogram(*, window, subcarrier_spacing, power_low, power_high, power_resolution, average_rbs=False, average_slots=False, guard_bandwidths=(0, 0), frame_slots=None, special_symbols=None, cyclic_prefix='normal', lo_bandstop=None)¶
Bases:
Analysis- Parameters:
window (str | tuple[str, float]) – window function specification following scipy.signal.get_window
subcarrier_spacing (float) – Subcarrier spacing (15e3, 30e3, 60e3, etc) (Constraints: units: Hz)
power_low (float) – Minimum power bin (Constraints: units: dB power)
power_high (float) – Maximum power bin (Constraints: units: dB power)
power_resolution (float) – Power bin resolution (Constraints: units: dB)
average_rbs (bool | one of ['half']) – frequency resolution of the spectrogram: False for 1 subcarrier, True for 1 resource block (12 subcarriers), or ‘half’ for 6 subcarriers
average_slots (bool) – True to coarsen spectrogram bins by averaging 1-symbol time resolution
guard_bandwidths (tuple[float, float]) – Bandwidths excluded at the (low, high) edges of the analysis band (Constraints: units: Hz)
frame_slots (str | None) – string composed of (‘d’, ‘u’, ‘s’) specifying the sequence of slots in 1 TDD cellular frame, or None to fill with downlink
special_symbols (str | None) – string composed of the characters (‘d’, ‘u’, ‘f’) indicating the sequence of symbol types (when ‘s’ is in frame_slots)
cyclic_prefix (one of ['normal', 'extended']) – cyclic prefix length of the 3GPP numerology (TS 38.211 Table 4.2-1)
lo_bandstop (float | None) – mask with float(“nan”) at this bandwidth centered at baseband DC (Constraints: units: Hz)
- class striqt.analysis.specs.ChannelPowerHistogram(*, detector_period, power_detectors=('rms', 'peak'), power_low, power_high, power_resolution)¶
Bases:
ChannelPowerTimeSeries- Parameters:
detector_period (Fraction) – Power detector bin duration, a whole multiple of the sample period (Constraints: units: s)
power_detectors (tuple[str, ...]) – Power detectors evaluated in each bin: ‘rms’, ‘peak’, or both
power_low (float) – Minimum power bin (Constraints: units: dB power)
power_high (float) – Maximum power bin (Constraints: units: dB power)
power_resolution (float) – Power bin resolution (Constraints: units: dB)
- class striqt.analysis.specs.ChannelPowerTimeSeries(*, detector_period, power_detectors=('rms', 'peak'))¶
Bases:
Analysis- Parameters:
detector_period (Fraction) – Power detector bin duration, a whole multiple of the sample period (Constraints: units: s)
power_detectors (tuple[str, ...]) – Power detectors evaluated in each bin: ‘rms’, ‘peak’, or both
- class striqt.analysis.specs.CyclicChannelPower(*, cyclic_period, detector_period, power_detectors=('rms', 'peak'), cyclic_statistics=('min', 'mean', 'max'))¶
Bases:
Analysis- Parameters:
cyclic_period (float) – Cycle period of the channel power statistics, a whole multiple of detector_period and a common multiple of the expected signal periods (Constraints: units: s)
detector_period (Fraction) – Power detector bin duration, a whole multiple of the sample period (Constraints: units: s)
power_detectors (tuple[str, ...]) – Power detectors evaluated in each bin: ‘rms’, ‘peak’, or both
cyclic_statistics (tuple[str | float, ...]) – Statistics evaluated across cycles at each cycle lag: ‘min’, ‘mean’, ‘max’, ‘median’, or a quantile in (0, 1)
- class striqt.analysis.specs.ErrorBound(*, rms, peak)¶
Bases:
SpecBasean error bound on the elements of one output.
rms bounds the error over all elements and peak the error at any one element, both in the units of the Tolerance field.
- Parameters:
rms (float)
peak (float)
- class striqt.analysis.specs.FilteredCapture(*, duration=0.1, sample_rate=15360000.0, analysis_bandwidth=inf, analysis_filter=AnalysisFilter(nfft=8192, window='hamming', nfft_out=None))¶
Bases:
Capture- Parameters:
duration (float) – Duration of the analysis waveform (Constraints: units: s)
sample_rate (float) – Sample rate of the analyzed IQ waveform (Constraints: > 0, units: S/s)
analysis_bandwidth (float) – Analysis bandwidth (Constraints: units: Hz)
analysis_filter (AnalysisFilter)
- class striqt.analysis.specs.FrequencyAnalysisSpecBase(*, window, frequency_resolution, fractional_overlap=0, window_fill=1, integration_bandwidth=None, trim_stopband=True, lo_bandstop=None)¶
Bases:
Analysisthe STFT settings shared by the spectrum measurements.
The FFT size is the capture sample_rate divided by frequency_resolution, and the quotient must be a whole number. fractional_overlap and window_fill are the hop and the zero padding of each window as fractions of that size. integration_bandwidth is the width of the adjacent bins summed after the FFT, a multiple of frequency_resolution, or None for no summing. trim_stopband True limits the frequency axis to the analysis_bandwidth of the capture when that bandwidth is finite.
- Parameters:
window (str | tuple[str, float]) – window function specification following scipy.signal.get_window
frequency_resolution (float)
fractional_overlap (Fraction)
window_fill (Fraction)
integration_bandwidth (float | None)
trim_stopband (bool)
lo_bandstop (float | None) – mask with float(“nan”) at this bandwidth centered at baseband DC (Constraints: units: Hz)
- class striqt.analysis.specs.IQWaveform(*, start_time_sec=None, stop_time_sec=None)¶
Bases:
Analysis- Parameters:
start_time_sec (float | None)
stop_time_sec (float | None)
- striqt.analysis.specs.Meta(standard_name: str, units: str | None = None, **kws) Meta¶
annotation that is used to generate ‘standard_name’ and ‘units’ fields of xarray attrs objects
- class striqt.analysis.specs.PowerSpectralDensity(*, window, frequency_resolution, fractional_overlap=0, window_fill=1, integration_bandwidth=None, trim_stopband=True, lo_bandstop=None, time_statistic=('mean',))¶
Bases:
FrequencyAnalysisSpecBase- Parameters:
window (str | tuple[str, float]) – window function specification following scipy.signal.get_window
frequency_resolution (float)
fractional_overlap (Fraction)
window_fill (Fraction)
integration_bandwidth (float | None)
trim_stopband (bool)
lo_bandstop (float | None) – mask with float(“nan”) at this bandwidth centered at baseband DC (Constraints: units: Hz)
time_statistic (tuple[str | float, ...])
- class striqt.analysis.specs.SpecBase¶
Bases:
Structthe base of every spec struct.
An instance is a frozen, keyword-only msgspec.Struct that rejects unknown fields. Construction converts list and dict field values to tuple and frozendict. An instance round-trips through to_dict and from_dict unchanged.
- classmethod from_dict(d: dict | frozendict) _T¶
return an instance of cls converted from the field values in d.
- Parameters:
d – field values keyed by name; a float for a fractions.Fraction field converts to the fraction of its decimal representation
- Raises:
msgspec.ValidationError – when a required field is missing, a key is not a field, or a value does not convert to the annotated type
- replace(**attrs) Self¶
returns a copy of self with changed attributes.
See also
Python standard library copy.replace
- to_dict(unfreeze: bool = False, allow_tuple_keys: bool = True) dict¶
return the field values of self as a dict of builtin values.
- Parameters:
unfreeze – True converts nested tuple and frozendict values to list and dict
allow_tuple_keys – False renders tuple dict keys as JSON array strings
- Returns:
a dict keyed by field name; fractions.Fraction values are strings and frozendict values are dicts
- validate() Self¶
return an equal instance rebuilt through to_dict and from_dict.
- Raises:
msgspec.ValidationError – when a field value does not satisfy the annotated type or constraints
- class striqt.analysis.specs.Spectrogram(*, window, frequency_resolution, fractional_overlap=0, window_fill=1, integration_bandwidth=None, trim_stopband=True, lo_bandstop=None, time_aperture=None)¶
Bases:
FrequencyAnalysisSpecBase- time_aperture (float):
if specified, binned RMS averaging is applied along time axis in the spectrogram to yield this coarser resolution (s)
- Parameters:
window (str | tuple[str, float]) – window function specification following scipy.signal.get_window
frequency_resolution (float)
fractional_overlap (Fraction)
window_fill (Fraction)
integration_bandwidth (float | None)
trim_stopband (bool)
lo_bandstop (float | None) – mask with float(“nan”) at this bandwidth centered at baseband DC (Constraints: units: Hz)
time_aperture (float | None)
- class striqt.analysis.specs.SpectrogramHistogram(*, window, frequency_resolution, fractional_overlap=0, window_fill=1, integration_bandwidth=None, trim_stopband=True, lo_bandstop=None, time_aperture=None, power_low, power_high, power_resolution)¶
Bases:
Spectrogram- Parameters:
window (str | tuple[str, float]) – window function specification following scipy.signal.get_window
frequency_resolution (float)
fractional_overlap (Fraction)
window_fill (Fraction)
integration_bandwidth (float | None)
trim_stopband (bool)
lo_bandstop (float | None) – mask with float(“nan”) at this bandwidth centered at baseband DC (Constraints: units: Hz)
time_aperture (float | None)
power_low (float) – Minimum power bin (Constraints: units: dB power)
power_high (float) – Maximum power bin (Constraints: units: dB power)
power_resolution (float) – Power bin resolution (Constraints: units: dB)
- class striqt.analysis.specs.SpectrogramHistogramRatio(*, window, frequency_resolution, fractional_overlap=0, window_fill=1, integration_bandwidth=None, trim_stopband=True, lo_bandstop=None, time_aperture=None, power_low, power_high, power_resolution)¶
Bases:
SpectrogramHistogram- Parameters:
window (str | tuple[str, float]) – window function specification following scipy.signal.get_window
frequency_resolution (float)
fractional_overlap (Fraction)
window_fill (Fraction)
integration_bandwidth (float | None)
trim_stopband (bool)
lo_bandstop (float | None) – mask with float(“nan”) at this bandwidth centered at baseband DC (Constraints: units: Hz)
time_aperture (float | None)
power_low (float) – Minimum power bin (Constraints: units: dB power)
power_high (float) – Maximum power bin (Constraints: units: dB power)
power_resolution (float) – Power bin resolution (Constraints: units: dB)
- class striqt.analysis.specs.Tolerance(*, units, rtol, on_peak, off_peak_dBc=None)¶
Bases:
SpecBasethe roundoff error budget of one measurement output.
The budget depends on the capture and the spec alone, not on the output values. on_peak bounds the error of the elements at the peak of the output. off_peak_dBc bounds the error of the other elements as a function of the level of each below the peak. Elements more than off_peak_dBc.peak below the peak are not bounded. The peak is the matched-filter bin of the matched input, e.g., the FFT bin at the frequency of a tone or the detector sample at the time of an impulse.
- Parameters:
units (str) – units of on_peak: ‘dB’, or the linear units of the output
rtol (float) – relative error bound on each output value, as a ratio
on_peak (ErrorBound) – absolute error bound, in units, on the elements at the peak of the output
off_peak_dBc (ErrorBound | None) – levels below the output peak, as negative values, at which the rms and the worst-case amplitude errors equal the amplitude of the element, or None to apply on_peak to every element (Constraints: units: dBc)
- class striqt.analysis.specs.frozendict(*args: Any, **kwargs: Any)¶
Bases:
Mapping[_K,_V]An immutable dictionary that supports hashing
- copy() frozendict[_K, _V]¶
- classmethod fromkeys(seq: Iterable[_K], value: _V | None = None) frozendict[_K, _V]¶
- items() a set-like object providing a view on D's items¶
- keys() a set-like object providing a view on D's keys¶
- update(other: dict[_K, _V], /)¶
- values() an object providing a view on D's values¶