File detector2d_core.h¶
FileList > detector2d > detector2d_core.h
Go to the source code of this file
2-D streaming signal detector with FFT2D-based correlation, integrate-and-dump, and configurable noise-referenced threshold. More...
#include "doppler/corr2d/corr2d_core.h"#include "doppler/dp_state.h"#include "doppler/f32_buffer/f32_buffer_core.h"
Classes¶
| Type | Name |
|---|---|
| struct | det_peak_t |
| struct | det_result2d_t Detection event returned by dp_detector2d_push() . |
| struct | dp_detector2d_state_t 2-D signal detector state. |
Public Types¶
| Type | Name |
|---|---|
| enum | det_noise_mode_t |
Public Functions¶
| Type | Name |
|---|---|
| size_t | dp_detector2d_consumed (const dp_detector2d_state_t * state) Input samples the last dp_detector2d_push() took. |
| dp_detector2d_state_t * | dp_detector2d_create (const float _Complex * ref, size_t ny, size_t nx, size_t dwell, size_t noise_lo, size_t noise_hi, det_noise_mode_t noise_mode, float threshold, int nthreads) Allocate a 2-D streaming signal detector backed by a 2-D correlator. Two-dimensional extension of dp_detector_create() . Input frames are flat row-major CF32 arrays of length ny*nx, cut from the stream by the ring's framer. On every int-dump the peak flat index is decomposed into (row, col) and adet_result2d_t is emitted when test_stat > threshold. The Python wrapper accepts a (ny, nx) CF32 ndarray for both ref and the push input. |
| void | dp_detector2d_destroy (dp_detector2d_state_t * state) Destroy and free. |
| void | dp_detector2d_get_state (const dp_detector2d_state_t * state, void * blob) |
| size_t | dp_detector2d_push (dp_detector2d_state_t * state, const float _Complex * in, size_t n_in, det_result2d_t * result, size_t max_results) Stream an arbitrary-length CF32 chunk through the 2-D detector. The same pipeline as dp_detector_push() , except that frames are ny*nx complex samples and each detection event carries (row, col) for the peak location instead of a single lag index. In Python the result is always a list of (row, col, peak_mag, noise_est, test_stat) tuples. |
| void | dp_detector2d_reset (dp_detector2d_state_t * state) Reset the 2-D correlator, the carry, and last-corr flag. Discards any partial frame carried between pushes and zeroes the coherent accumulator. The reference spectrum and FFT plans are preserved. |
| int | dp_detector2d_set_ref (dp_detector2d_state_t * state, const float _Complex * ref) Replace the reference image and recompute its spectrum. |
| int | dp_detector2d_set_state (dp_detector2d_state_t * state, const void * blob) |
| void | dp_detector2d_set_threshold (dp_detector2d_state_t * state, float threshold) Change threshold without rebuilding. |
| size_t | dp_detector2d_state_bytes (const dp_detector2d_state_t * state) |
Macros¶
| Type | Name |
|---|---|
| define | DETECTOR2D_STATE_MAGIC [**DP\_FOURCC**](dp__state_8h.md#define-dp_fourcc) ('D','E','T','2') |
| define | DETECTOR2D_STATE_VERSION 2u |
| define | DET_NOISE_MODE_T_DEFINED |
| define | DET_PEAK_T_DEFINED One listed peak of a surface: a cell and its value, in the surface's own units (a magnitude on a coherent surface, a power on a non-coherent one). What det_peak_list() ( det_private.h ) returns, and what the acquisition engine keeps per dwell. |
Detailed Description¶
Two-dimensional extension of detector_core. The input stream is chunked into ny×nx frames (flat row-major CF32) by the ring's framed face (DECLARE_DP_BUFFER_FRAMES), so the detections are a function of the input stream, not of how it was split into calls. The test statistic and threshold semantics are identical to the 1-D variant; the only difference is that the peak index maps to a (row, col) pair instead of a single lag.
Detection events: det_result2d_t = { row, col, peak_mag, noise_est, test_stat }
Lifecycle:
float _Complex ref[NY * NX] = { ... };
dp_detector2d_state_t *det = dp_detector2d_create(ref, NY, NX, 1,
0, NY*NX-1, DET_NOISE_MEAN, 0.0f, 1);
det_result2d_t results[64];
// a full results[] stops a push, and the input it did not take is
// offered again -- dp_detector2d_consumed(det) says where it stopped
while (recv(chunk, CHUNK_SZ)) {
for (size_t off = 0; off < CHUNK_SZ;
off += dp_detector2d_consumed(det)) {
size_t n = dp_detector2d_push(det, chunk + off, CHUNK_SZ - off,
results, 64);
for (size_t i = 0; i < n; i++)
printf("row=%zu col=%zu stat=%.2f\n",
results[i].row, results[i].col, results[i].test_stat);
}
}
dp_detector2d_destroy(det);
Public Types Documentation¶
enum det_noise_mode_t¶
enum det_noise_mode_t {
DET_NOISE_MEAN = 0,
DET_NOISE_MEDIAN = 1,
DET_NOISE_MIN = 2,
DET_NOISE_MAX = 3
};
Public Functions Documentation¶
function dp_detector2d_consumed¶
Input samples the last dp_detector2d_push() took.
Equal to its n_in unless result filled up; then the caller resumes at in + consumed. 0 after create, reset, set_ref and set_state.
Parameters:
stateMust be non-NULL.
function dp_detector2d_create¶
Allocate a 2-D streaming signal detector backed by a 2-D correlator. Two-dimensional extension of dp_detector_create() . Input frames are flat row-major CF32 arrays of length ny*nx, cut from the stream by the ring's framer. On every int-dump the peak flat index is decomposed into (row, col) and adet_result2d_t is emitted when test_stat > threshold. The Python wrapper accepts a (ny, nx) CF32 ndarray for bothref and the push input.
dp_detector2d_state_t * dp_detector2d_create (
const float _Complex * ref,
size_t ny,
size_t nx,
size_t dwell,
size_t noise_lo,
size_t noise_hi,
det_noise_mode_t noise_mode,
float threshold,
int nthreads
)
Parameters:
ref2-D reference image, (ny, nx) CF32 ndarray in Python.nyNumber of rows in the reference and input frames.nxNumber of columns in the reference and input frames.dwellInt-dump depth; must be >= 1.noise_loLower flat-index noise bin (inclusive, 0-based).noise_hiUpper flat-index noise bin (inclusive, < ny*nx). A value at or beyond the window clamps to ny*nx - 1, so the default sentinel selects the full window.noise_modeNoise aggregation: "mean", "median", "min", or "max".thresholdTest-stat gate; 0.0 = always emit.nthreadsAccepted for API compatibility; ignored.
Returns:
Heap-allocated state, or NULL on allocation failure.
>>> from doppler.spectral import CorrDetector2D
>>> import numpy as np
>>> ref = np.zeros((4, 4), dtype=np.complex64); ref[0, 0] = 1.0
>>> det = CorrDetector2D(ref=ref, dwell=1, noise_lo=1, noise_hi=15,
... noise_mode="mean", threshold=0.0)
>>> det.ny, det.nx, det.n, det.dwell
(4, 4, 16, 1)
function dp_detector2d_destroy¶
Destroy and free.
Parameters:
stateMay be NULL.
function dp_detector2d_get_state¶
function dp_detector2d_push¶
Stream an arbitrary-length CF32 chunk through the 2-D detector. The same pipeline as dp_detector_push() , except that frames are ny*nx complex samples and each detection event carries (row, col) for the peak location instead of a single lag index. In Python the result is always a list of (row, col, peak_mag, noise_est, test_stat) tuples.
size_t dp_detector2d_push (
dp_detector2d_state_t * state,
const float _Complex * in,
size_t n_in,
det_result2d_t * result,
size_t max_results
)
Python's push() has room for 1024 detections a call, so a push that completes at most 1024 frames, counting the carry, loses nothing. One that fills the room loses the rest of its input, every later frame whether or not it would have made a detection, unless the rest is shorter than a frame: that is kept as the carry. The next push stays on the frame grid, its peaks at their own (row, col), only when what was lost is a whole number of frames; otherwise they are off by the remainder. Before v0.66 the room was 64, and a push past it kept up to ring_cap/n - 1 of those frames for the next call and dropped the rest. #1992 and just-buildit/just-makeit#2184 track sizing the list to the call.
Parameters:
stateAllocated 2-D detector (non-NULL).inCF32 input chunk of arbitrary length.n_inNumber of input samples inin.resultCaller-supplied array of at leastmax_resultsdet_result2d_t structs; filled on return.max_resultsCapacity ofresult(maximum detections to emit). A fullresultnever loses input: a frame yields at most one detection, and onceresultis full the push takes the rest of its input only if the rest completes no frame (it is then the carry); otherwise it takes nothing more, stopping on the boundary of its last frame. dp_detector2d_consumed() says how many samples it took, and the caller offers the rest again. Input that runs out mid-frame is the carry, held inside (fewer than ny*nx samples). With room 0 the push is full from the start, so a resume loop needs room for at least one; with that, a push of any input takes at least one sample.
Returns:
Number of det_result2d_t entries written to result.
>>> from doppler.spectral import CorrDetector2D
>>> import numpy as np
>>> ref = np.zeros((4, 4), dtype=np.complex64); ref[0, 0] = 1.0
>>> det = CorrDetector2D(ref=ref, dwell=1, noise_lo=1, noise_hi=15,
... noise_mode="mean", threshold=0.0)
>>> results = det.push(np.ones((4, 4), dtype=np.complex64))
>>> len(results)
1
>>> row, col, peak, noise, stat = results[0]
>>> row, col, round(peak, 4), round(noise, 4), round(stat, 4)
(0, 0, 1.0, 1.0, 1.0)
function dp_detector2d_reset¶
Reset the 2-D correlator, the carry, and last-corr flag. Discards any partial frame carried between pushes and zeroes the coherent accumulator. The reference spectrum and FFT plans are preserved.
>>> from doppler.spectral import CorrDetector2D
>>> import numpy as np
>>> ref = np.zeros((4, 4), dtype=np.complex64); ref[0, 0] = 1.0
>>> det = CorrDetector2D(ref=ref, dwell=1, noise_lo=1, noise_hi=15,
... noise_mode="mean", threshold=0.0)
>>> _ = det.push(np.ones((4, 4), dtype=np.complex64))
>>> det.reset()
>>> det.count
0
function dp_detector2d_set_ref¶
Replace the reference image and recompute its spectrum.
Always resets (the carry, corr2d accumulator, last-dump bookkeeping), even if the new reference is subsequently rejected. The new reference must have the same ny*nx total size; see dp_corr2d_set_ref() for the single-row-fast- path rejection rule this forwards.
Parameters:
stateMust be non-NULL.refNew reference, flat row-major CF32, length ny*nx.
Returns:
0 on success, -1 if rejected by dp_corr2d_set_ref().
function dp_detector2d_set_state¶
function dp_detector2d_set_threshold¶
Change threshold without rebuilding.
Parameters:
stateMust be non-NULL.thresholdNew threshold; 0.0 = always fire.
function dp_detector2d_state_bytes¶
Macro Definition Documentation¶
define DETECTOR2D_STATE_MAGIC¶
define DETECTOR2D_STATE_VERSION¶
define DET_NOISE_MODE_T_DEFINED¶
define DET_PEAK_T_DEFINED¶
One listed peak of a surface: a cell and its value, in the surface's own units (a magnitude on a coherent surface, a power on a non-coherent one). What det_peak_list() ( det_private.h ) returns, and what the acquisition engine keeps per dwell.
The documentation for this class was generated from the following file native/inc/doppler/detector2d/detector2d_core.h