File imdmeas_core.h¶
FileList > imdmeas > imdmeas_core.h
Go to the source code of this file
IMDMeasure — two-tone intermodulation (IMD2/IMD3) and intercept. More...
#include "clib_common.h"#include "jm_perf.h"#include "measure/measure_core.h"#include "psd/psd_core.h"#include <complex.h>
Classes¶
| Type | Name |
|---|---|
| struct | imdmeas_state_t IMDMeasure state: owned window, FFT plan and one-sided power scratch. |
Public Functions¶
| Type | Name |
|---|---|
| imd_meas_t | imdmeas_analyze (imdmeas_state_t * state, const float * x, size_t n_in) Two-tone IMD/TOI of a real capture (finds the two strongest tones). |
| imdmeas_state_t * | imdmeas_create (size_t n, double fs, double full_scale, size_t bits, double dynamic_range_db) Create an IMDMeasure analyser (auto Kaiser window). |
| void | imdmeas_destroy (imdmeas_state_t * state) Destroy an IMDMeasure analyser. |
| void | imdmeas_reset (imdmeas_state_t * state) Reset the analyser (a no-op: each analyze() call is independent). |
| size_t | imdmeas_spectrum_dbfs (imdmeas_state_t * state, const float * x, size_t x_len, float * out, size_t max_out) DC-centred dBFS magnitude spectrum of a capture (length nfft). |
| size_t | imdmeas_spectrum_dbfs_max_out (imdmeas_state_t * state) Capacity (== nfft) of the spectrum_dbfs output buffer. |
Detailed Description¶
Drive two equal-amplitude tones f1<f2; the analyser finds them as the two strongest lobes, integrates each fundamental and the intermodulation products (2f1-f2, 2f2-f1 for IMD3; f2-f1 for IMD2) over their window main lobes (folded into the analysed band), and reports the third/second-order intercepts.
Lifecycle: create -> [analyze]* -> destroy
Public Functions Documentation¶
function imdmeas_analyze¶
Two-tone IMD/TOI of a real capture (finds the two strongest tones).
Returns:
the IMD metric record (by value; zeroed if no two tones are found).
>>> from doppler.measure import IMDMeasure
>>> import numpy as np
>>> t = np.arange(4096)
>>> # two equal tones at 200 & 250 cycles, plus 3rd-order
>>> # products 40 dB down
>>> x = (np.cos(2*np.pi*200*t/4096) + np.cos(2*np.pi*250*t/4096)
... + 0.01*np.cos(2*np.pi*150*t/4096)
... + 0.01*np.cos(2*np.pi*300*t/4096)).astype(np.float32)
>>> r = IMDMeasure(n=4096, fs=1.0).analyze(x)
>>> round(r.f1, 4), round(r.f2, 4), round(r.imd3_dbc, 0)
(0.0488, 0.061, -40.0)
function imdmeas_create¶
Create an IMDMeasure analyser (auto Kaiser window).
imdmeas_state_t * imdmeas_create (
size_t n,
double fs,
double full_scale,
size_t bits,
double dynamic_range_db
)
The window is always Kaiser; its shape is auto-selected so the sidelobes sit below the requested dynamic range (see measure_resolve_dr()), keeping the resolution bandwidth as fine as n allows.
Parameters:
nCapture/frame length (>= 2).fsSample rate (Hz, > 0).full_scaleAmplitude that equals 0 dBFS (> 0). Ignored if bits > 0.bitsADC depth: bits>0 sets the 0-dBFS reference to 2^(bits-1) and, unless overridden, the dynamic-range target.dynamic_range_dbExplicit sidelobe/dynamic-range target (dB); used when > 0, else derived frombits.
Returns:
Heap state, or NULL on bad args / allocation failure.
function imdmeas_destroy¶
Destroy an IMDMeasure analyser.
Parameters:
stateMay be NULL.
function imdmeas_reset¶
Reset the analyser (a no-op: each analyze() call is independent).
Every analyze() / spectrum_dbfs() call re-windows and re-transforms its own capture from scratch, so nothing is carried between calls to clear. The method exists only so IMDMeasure honours the same reset() contract as every other doppler object, letting a generic pipeline reset each stage uniformly.
Parameters:
stateThe analyser (left unchanged).
>>> from doppler.measure import IMDMeasure
>>> m = IMDMeasure(n=4096, fs=1.0)
>>> m.reset() # stateless: provided only for API uniformity
>>> m.reset() is None # returns nothing; safe to call anytime
True
function imdmeas_spectrum_dbfs¶
DC-centred dBFS magnitude spectrum of a capture (length nfft).
size_t imdmeas_spectrum_dbfs (
imdmeas_state_t * state,
const float * x,
size_t x_len,
float * out,
size_t max_out
)
The same windowed, zero-padded PSD the IMD metrics are read off, laid out DC-centred (fftshifted) and normalised to dBFS for an analyzer-display backdrop. Use it to see the two fundamentals and the intermodulation products that analyze() integrates.
Parameters:
stateThe analyser.xReal time-domain capture (lengthx_len).x_lenNumber of input samples.outDestination buffer (length >=max_out).max_outCapacity ofout(== nfft).
Returns:
DC-centred dBFS magnitude spectrum, one value per FFT bin (nfft).
>>> from doppler.measure import IMDMeasure
>>> import numpy as np
>>> t = np.arange(4096)
>>> x = (0.5*np.cos(2*np.pi*200*t/4096)
... + 0.5*np.cos(2*np.pi*250*t/4096)).astype(np.float32)
>>> s = IMDMeasure(n=4096, fs=1.0).spectrum_dbfs(x) # DC-centred dBFS
>>> s.shape
(8192,)
>>> round(float(s.max()), 1) # each tone splits into two images
-12.0
function imdmeas_spectrum_dbfs_max_out¶
Capacity (== nfft) of the spectrum_dbfs output buffer.
The documentation for this class was generated from the following file native/inc/imdmeas/imdmeas_core.h