rm_lite.utils.clean¶
RM-CLEAN utils
Attributes¶
Classes¶
Results of the RM-CLEAN loop |
|
Arrays for the RM-CLEAN minor loop |
|
Options for the RM-CLEAN minor loop |
|
Results of the RM-CLEAN minor loop |
|
Options for multiscale RM-CLEAN. |
|
Options for RM-CLEAN, shared by the 1D and 3D tools |
|
Results of the RM-CLEAN calculation |
|
Arrays for RM-synthesis |
|
Per-scale RMSF responses for one spectrum (Offringa & Smirnov 2017). |
Functions¶
|
Phase-2 per-scale masks: each scale's phase-1 centres dilated by |
|
Classify the source once on the DIRTY spectrum for "hybrid" selection. |
|
Half-max width of a peaked profile; on |RMSF| this is the measured |
|
Width-gated snr selection. |
One phase of multiscale minor cycles, restricted to allowed_supports. |
|
|
Robust (MAD) RMS of the residual outside the current mask region. |
|
Footprint of a sparse delta model in the dirty FDF: sum_i m_i * RMSF@i. |
|
Convolve the model with a unit-peak clean beam. |
|
Tight adaptive-mask seed: just the brightest allowed channel, if it clears |
Opening-filter scale supports (eye-patch flint-crew, 1D RM analogue). |
|
|
Precompute the per-scale RMSF responses for one spectrum. |
|
Convolve an FDF (complex or real) with a real scale kernel. |
|
Scales (RMSF FWHM units): explicit if given, else WSClean-style auto. |
|
Index of the most-significant scale (Offringa & Smirnov 2017). |
Gaussian scale kernel; sigma = (3/16) * scale (Offringa & Smirnov 2017). |
|
|
Hanning window function. |
|
Scale set: 0, 3, then geometric doubling from 6 to max_scale. |
|
Single-scale CLEAN one spectrum: an initial masked loop to threshold, then |
|
Hogbom minor loop: shift-subtract the RMSF at each residual peak within the |
Multiscale CLEAN one FDF spectrum (Offringa & Smirnov 2017). |
|
|
Restore a delta model with a unit-peak clean beam (one pass). |
|
Validate array shapes and CLEAN each pixel (single- or multi-scale). |
|
Roll the double-length RMSF so its peak sits at FDF channel fdf_index, |
Tapered quadratic scale kernel (Offringa & Smirnov 2017, eq. 2). |
Module Contents¶
- class rm_lite.utils.clean.CleanLoopResults¶
Bases:
NamedTupleResults of the RM-CLEAN loop
- clean_fdf_spectrum: numpy.typing.NDArray[numpy.complex128]¶
The cleaned Faraday dispersion function cube
- model_fdf_spectrum: numpy.typing.NDArray[numpy.complex128]¶
The clean components cube
- resid_fdf_spectrum: numpy.typing.NDArray[numpy.complex128]¶
The residual Faraday dispersion function cube
- class rm_lite.utils.clean.MinorLoopArrays¶
Bases:
NamedTupleArrays for the RM-CLEAN minor loop
- phi_arr_radm2: numpy.typing.NDArray[numpy.float64]¶
Faraday depth array in rad/m^2
- phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64]¶
Double-length Faraday depth array in rad/m^2
- resid_fdf_spectrum_mask: numpy.ma.MaskedArray¶
Residual Faraday dispersion function spectrum
- rmsf_spectrum: numpy.typing.NDArray[numpy.complex128]¶
RMSF spectrum
- class rm_lite.utils.clean.MinorLoopOptions¶
Options for the RM-CLEAN minor loop
- class rm_lite.utils.clean.MinorLoopResults¶
Bases:
NamedTupleResults of the RM-CLEAN minor loop
- model_fdf_spectrum: numpy.typing.NDArray[numpy.complex128]¶
The clean components cube
- resid_fdf_spectrum: numpy.typing.NDArray[numpy.complex128]¶
The residual Faraday dispersion function cube
- resid_fdf_spectrum_mask: numpy.ma.MaskedArray¶
The masked residual Faraday dispersion function cube
- class rm_lite.utils.clean.MultiscaleOptions¶
Options for multiscale RM-CLEAN.
- kernel: KernelType = 'tapered_quad'¶
Scale kernel shape
- scales: numpy.typing.NDArray[numpy.float64] | None = None¶
Explicit scales (RMSF FWHM units); None auto-selects WSClean-style
- selection: SelectionType = 'hybrid'¶
Scale selector (default “hybrid”). “snr” = matched filter max|R conv K_s| / sigma_s; “hybrid” = width-gated snr: engages extended scales only when the residual peak fits wider than the measured dirty beam and the extended score competes with scale 0, else behaves as “snr”. Plain “snr” scores are near scale-degenerate under correlated FDF noise, so with the default margin it almost never engages; “hybrid” does while staying point-safe.
- class rm_lite.utils.clean.RMCleanOptions¶
Options for RM-CLEAN, shared by the 1D and 3D tools
- class rm_lite.utils.clean.RMCleanResults¶
Bases:
NamedTupleResults of the RM-CLEAN calculation
- clean_fdf_arr: numpy.typing.NDArray[numpy.complex128]¶
The cleaned Faraday dispersion function cube
- clean_iter_arr: numpy.typing.NDArray[numpy.int64]¶
minor iterations (one component each). Multiscale: minor cycles (scale re-selections); see sub_minor_iter_arr for the comparable component count.
- Type:
CLEAN iterations per pixel. Single-scale
- model_fdf_arr: numpy.typing.NDArray[numpy.complex128]¶
The clean components cube
- resid_fdf_arr: numpy.typing.NDArray[numpy.complex128]¶
The residual Faraday dispersion function cube
- sub_minor_iter_arr: numpy.typing.NDArray[numpy.int64]¶
single-scale equals clean_iter_arr; multiscale sums the sub-minor (per-scale Hogbom) iterations over all minor cycles. This is the count comparable to single-scale.
- Type:
Total component-placement steps per pixel
- class rm_lite.utils.clean.RMSynthArrays¶
Bases:
NamedTupleArrays for RM-synthesis
- dirty_fdf_arr: numpy.typing.NDArray[numpy.complex128]¶
Dirty Faraday dispersion function array
- fwhm_rmsf_arr: numpy.typing.NDArray[numpy.float64]¶
FWHM of the RMSF array
- phi_arr_radm2: numpy.typing.NDArray[numpy.float64]¶
Faraday depth array in rad/m^2
- phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64]¶
Double-length Faraday depth array in rad/m^2
- rmsf_arr: numpy.typing.NDArray[numpy.complex128]¶
RMSF array
- class rm_lite.utils.clean.ScaleKernels¶
Bases:
NamedTuplePer-scale RMSF responses for one spectrum (Offringa & Smirnov 2017).
The scale kernel K_s (eq. 2) is the extended shape a scale-s component is built from. A scale-s structure appears in the residual as RMSF conv K_s, and in the scale-convolved residual (which the sub-minor loop works in) as RMSF conv K_s conv K_s: the RMSF picks up the scale twice, once from the structure and once from convolving the residual (Section 2.2).
- fwhm_conv_scale_twice: numpy.typing.NDArray[numpy.float64]¶
Fitted FWHM of |RMSF conv K_s conv K_s| per scale (sub-minor restore width).
- peak_response: numpy.typing.NDArray[numpy.float64]¶
peak of the scale-convolved response, dividing it out recovers the true scale-s amplitude (cf. the per-scale gain, eq. 4).
- Type:
max|RMSF conv K_s conv K_s| per scale
- point_width: float¶
the dirty-beam width a delta presents in the dirty |FDF|, near-in sidelobe shoulders included. Wider than the theoretical fwhm under non-uniform lambda^2 sampling; the hybrid selector’s width test calibrates against this, never the fwhm.
- Type:
Measured half-max width of |RMSF| in rad/m^2
- rmsf_conv_scale: list[numpy.typing.NDArray[numpy.complex128]]¶
the scale-s response in the full-res residual, used for the residual subtraction. On the double phi axis.
- Type:
RMSF conv K_s per scale
- rmsf_conv_scale_twice: list[numpy.typing.NDArray[numpy.complex128]]¶
the scale-s response in the scale-convolved residual, i.e. the effective RMSF the sub-minor loop cleans against (Section 2.2).
- Type:
RMSF conv K_s conv K_s per scale
- scales: numpy.typing.NDArray[numpy.float64]¶
Scales (RMSF FWHM units)
- sigma_s: numpy.typing.NDArray[numpy.float64]¶
Per-scale FDF noise std relative to scale 0 under correlated FDF noise, for the matched-filter (snr) score inside hybrid selection: sqrt((K_s conv K_s conv RMSF)(0) / RMSF(0)). sigma_s[0] == 1.
- rm_lite.utils.clean._build_scale_masks(record: list[list[int]], scales: numpy.typing.NDArray[numpy.float64], phi_len: int, rmsf_fwhm: float, d_phi: float) list[numpy.typing.NDArray[numpy.bool_]]¶
Phase-2 per-scale masks: each scale’s phase-1 centres dilated by scale*fwhm/2 each side (WSClean 2.2.3 scale-dependent masking); empty for a scale that cleaned nothing.
The dilation is the scale’s own extent only, with no added RMSF core: the core over-dilated the delta scale into the RMSF sidelobes on wide-RMSF narrowband cells. At scale 0 this confines phase 2 to the exact phase-1 footprint, like single-scale’s frozen deep clean.
- rm_lite.utils.clean._classify_hybrid_source(dirty_fdf_spectrum: numpy.typing.NDArray[numpy.complex128], phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64], kernels: ScaleKernels, multiscale_options: MultiscaleOptions) MultiscaleOptions¶
Classify the source once on the DIRTY spectrum for “hybrid” selection.
A peak that fits at beam width is a point source: lock the whole clean to “snr” so mid-clean sidelobe pedestals (which can fit wide while the peak is still above the engage floor) never re-open extended selection. A wide fit keeps “hybrid” with its per-cycle gates. No-op for other selectors.
- rm_lite.utils.clean._halfmax_width_radm2(profile: numpy.typing.NDArray[numpy.float64], d_phi: float) float¶
Half-max width of a peaked profile; on |RMSF| this is the measured dirty-beam width (>> theoretical fwhm under non-uniform lambda^2 sampling).
- rm_lite.utils.clean._hybrid_scale_selection(resid_fdf_spectrum: numpy.typing.NDArray[numpy.complex128], scale_kernels: ScaleKernels, rmsf_fwhm: float, phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64], kernel: KernelType, active: numpy.typing.NDArray[numpy.bool_] | None, selection_margin: float, engage_floor: float) int¶
Width-gated snr selection.
Engage an extended scale only when two independent tests agree, else fall back to plain snr selection with selection_margin: 1. Width: bounded half-max fit of the residual peak wider than
HYBRID_WIDTH_FACTOR x the measured dirty-beam width (a delta fits 1.0x, the narrowest genuinely extended source ~2x).
Score: best active extended matched-filter score at least HYBRID_SCORE_FACTOR x the scale-0 score (kills residual junk that fits wide but scores poorly at wide scales).
Engagement takes the argmax score among active extended scales. Below engage_floor (endgame) always falls back.
- rm_lite.utils.clean._multiscale_minor_cycles(resid_fdf_spectrum: numpy.typing.NDArray[numpy.complex128], model_fdf_spectrum: numpy.typing.NDArray[numpy.complex128], *, kernels: ScaleKernels, scales: numpy.typing.NDArray[numpy.float64], allowed_supports: list[numpy.typing.NDArray[numpy.bool_]], phi_arr_radm2: numpy.typing.NDArray[numpy.float64], phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64], rmsf_fwhm: float, clean_options: RMCleanOptions, multiscale_options: MultiscaleOptions, stop_threshold: float, record: list[list[int]] | None) tuple[numpy.typing.NDArray[numpy.complex128], numpy.typing.NDArray[numpy.complex128], int, int]¶
One phase of multiscale minor cycles, restricted to allowed_supports.
Cleans down to stop_threshold with the O&S divergence and stall guards. A scale that exhausts its allowed region is retired (not reselected). If record is given, appends the cleaned channel indices per scale, to build the phase-2 auto-mask. Returns (resid, model, n_iter, sub_minor_total).
- rm_lite.utils.clean._offsource_rms(resid_fdf_spectrum: numpy.typing.NDArray[numpy.complex128], mask_arr: numpy.typing.NDArray[numpy.bool_]) float¶
Robust (MAD) RMS of the residual outside the current mask region.
Sidelobe-inflated while a bright source remains, falling to the noise floor once it subtracts; this is what makes the auto-mask contract off the RMSF sidelobes. Returns 0.0 when too few off-source channels remain (the caller floors it at the FDF noise).
- rm_lite.utils.clean._reconvolve_model(model_fdf_spectrum: numpy.typing.NDArray[numpy.complex128], rmsf_spectrum: numpy.typing.NDArray[numpy.complex128], phi_arr_radm2: numpy.typing.NDArray[numpy.float64], phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64]) numpy.typing.NDArray[numpy.complex128]¶
Footprint of a sparse delta model in the dirty FDF: sum_i m_i * RMSF@i.
Same shift-and-add primitive as minor_loop, so the multiscale residual update matches how single-scale CLEAN subtracts components.
- rm_lite.utils.clean._restore_multiscale(model_fdf_spectrum: numpy.typing.NDArray[numpy.complex128], phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64], rmsf_fwhm: float) numpy.typing.NDArray[numpy.complex128]¶
Convolve the model with a unit-peak clean beam.
Matches single-scale minor_loop, so calc_faraday_moments mom0 normalisation recovers the component flux.
- rm_lite.utils.clean._seed_mask(resid_fdf_spectrum: numpy.typing.NDArray[numpy.complex128], cap_arr: numpy.typing.NDArray[numpy.bool_], floor: float) numpy.typing.NDArray[numpy.bool_]¶
Tight adaptive-mask seed: just the brightest allowed channel, if it clears the mask floor. Below the floor (noise-only) the seed is empty, so nothing cleans. The global peak is always real emission, so seeding it is safe.
- rm_lite.utils.clean.adaptive_scale_supports(dirty_fdf_spectrum: numpy.typing.NDArray[numpy.complex128], source_region: numpy.typing.NDArray[numpy.bool_], kernels: ScaleKernels, scales: numpy.typing.NDArray[numpy.float64], phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64], kernel: KernelType, rmsf_fwhm: float, mask: float) list[numpy.typing.NDArray[numpy.bool_]]¶
Opening-filter scale supports (eye-patch flint-crew, 1D RM analogue).
Per scale: scale-convolve the dirty FDF, morphologically OPEN it (min then max filter of the scale width) to isolate structure at least that wide, gate at the flux-correct amplitude mask * peak_response, and confine to source_region dilated by the scale width. source_region is the tight adaptive mask from the single-scale off-source pre-pass; dilating per scale is the eye-patch beam-shape-erosion analogue and keeps extended scales from spreading onto the RMSF sidelobe islands (the pond). A scale with an empty support is inactive.
- rm_lite.utils.clean.compute_scale_kernels(scales: numpy.typing.NDArray[numpy.float64], rmsf_spectrum: numpy.typing.NDArray[numpy.complex128], rmsf_fwhm: float, phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64], kernel: KernelType) ScaleKernels¶
Precompute the per-scale RMSF responses for one spectrum.
Follows Offringa & Smirnov (2017), Section 2.2; see ScaleKernels.
- Parameters:
scales (NDArray[np.float64]) – Scales in RMSF FWHM units.
rmsf_spectrum (NDArray[np.complex128]) – RMSF on the double-phi axis.
rmsf_fwhm (float) – RMSF FWHM in rad/m^2.
phi_double_arr_radm2 (NDArray[np.float64]) – Double-phi axis.
kernel (KernelType) – Scale-kernel shape.
- Returns:
Per-scale responses (see that type).
- Return type:
- rm_lite.utils.clean.convolve_fdf_scale(scale: float, fwhm: float, fdf_arr: numpy.typing.NDArray[numpy.complex128] | numpy.typing.NDArray[numpy.float64], phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64], kernel: KernelType = 'gaussian', sum_normalised: bool = True) numpy.typing.NDArray[numpy.complex128] | numpy.typing.NDArray[numpy.float64]¶
Convolve an FDF (complex or real) with a real scale kernel.
The real and imaginary parts are convolved separately, since scipy.ndimage.convolve drops the imaginary part of complex input.
- Parameters:
scale (float) – Scale in RMSF FWHM units; 0 returns the input unchanged.
fwhm (float) – RMSF FWHM in rad/m^2.
fdf_arr (NDArray) – FDF (or RMSF) to convolve.
phi_double_arr_radm2 (NDArray[np.float64]) – Sets the sample spacing d_phi.
kernel (KernelType) – Scale-kernel shape.
sum_normalised (bool) – Normalise the kernel to unit sum (else unit peak).
- Returns:
The scale-convolved FDF, same length as fdf_arr.
- Return type:
NDArray
- rm_lite.utils.clean.default_scales(phi_arr_radm2: numpy.typing.NDArray[numpy.float64], rmsf_fwhm: float, multiscale_options: MultiscaleOptions, phi_max_scale_radm2: float | None = None) numpy.typing.NDArray[numpy.float64]¶
Scales (RMSF FWHM units): explicit if given, else WSClean-style auto.
The auto max scale is phi_max_scale_radm2 (pi / lambda_sq_min) when given, capped at the FDF phi window: a kernel wider than the window is meaningless (its response flattens, its normalisation blows up). Uses the make_fine_scales grid.
- Parameters:
phi_arr_radm2 (NDArray[np.float64]) – Faraday depth axis (sets the window cap).
rmsf_fwhm (float) – RMSF FWHM in rad/m^2.
multiscale_options (MultiscaleOptions) – Selector, explicit scales, count cap.
phi_max_scale_radm2 (float | None) – Largest recoverable scale; None uses the window.
- Returns:
Scales in RMSF FWHM units.
- Return type:
NDArray[np.float64]
- rm_lite.utils.clean.find_significant_scale(resid_fdf_spectrum: numpy.typing.NDArray[numpy.complex128], scale_kernels: ScaleKernels, rmsf_fwhm: float, phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64], kernel: KernelType, active: numpy.typing.NDArray[numpy.bool_] | None = None, selection: SelectionType = 'snr', selection_margin: float = 0.0, engage_floor: float = 0.0) int¶
Index of the most-significant scale (Offringa & Smirnov 2017).
“snr” scores the matched filter max|resid conv K_s| / sigma_s, with selection_margin preferring the smallest scale within that margin of the best. “hybrid” is width-gated snr: engage an extended scale only when the residual peak fits wider than the measured dirty beam AND its score competes with scale 0, else fall back to “snr” (see _hybrid_scale_selection).
- Parameters:
resid_fdf_spectrum (NDArray[np.complex128]) – Current residual FDF.
scale_kernels (ScaleKernels) – Precomputed per-scale responses.
rmsf_fwhm (float) – RMSF FWHM in rad/m^2.
phi_double_arr_radm2 (NDArray[np.float64]) – Double-phi axis.
kernel (KernelType) – Scale-kernel shape.
active (NDArray[np.bool_] | None) – Scales still allowed to be selected.
selection ("snr" | "hybrid") – Scale selector.
selection_margin (float) – SNR parsimony margin (see MultiscaleOptions); for “hybrid” it applies to the snr fallback.
engage_floor (float) – Hybrid only: below this residual peak (absolute FDF units) always fall back to snr. 0 disables the gate.
- Returns:
Index into scale_kernels.scales of the selected scale.
- Return type:
- rm_lite.utils.clean.gaussian_scale_kernel_function(phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64], scale: float, rmsf_fwhm: float, sum_normalised: bool = True) numpy.typing.NDArray[numpy.float64]¶
Gaussian scale kernel; sigma = (3/16) * scale (Offringa & Smirnov 2017).
O&S define sigma = (3/16) * alpha with alpha the scale in physical units; here that is scale * rmsf_fwhm, matching the tapered_quad width.
- rm_lite.utils.clean.hanning(x_arr: numpy.typing.NDArray[numpy.float64], length: float) numpy.typing.NDArray[numpy.float64]¶
Hanning window function.
- rm_lite.utils.clean.make_fine_scales(max_scale: float, n_scales: int | None = None) numpy.typing.NDArray[numpy.float64]¶
Scale set: 0, 3, then geometric doubling from 6 to max_scale.
The first anchor is 3, not 1.5: a point’s matched-filter score at s=1.5 is only ~1% below scale 0, so noise flipped bright points onto it.
- rm_lite.utils.clean.minor_cycle(rm_synth_1d_arrays: RMSynthArrays, clean_options: RMCleanOptions) CleanLoopResults¶
Single-scale CLEAN one spectrum: an initial masked loop to threshold, then a deep loop frozen to the cleaned footprint.
- Parameters:
rm_synth_1d_arrays (RMSynthArrays) – 1D dirty FDF, phi axes, RMSF, optional mask.
clean_options (RMCleanOptions) – Mask, threshold, gain, max_iter.
- Raises:
ValueError – If any input array is not 1D.
- Returns:
Clean, residual, and model spectra and the iteration count.
- Return type:
- rm_lite.utils.clean.minor_loop(minor_loop_arrays: MinorLoopArrays, minor_loop_options: MinorLoopOptions) MinorLoopResults¶
Hogbom minor loop: shift-subtract the RMSF at each residual peak within the mask until the peak drops below threshold (or max_iter).
- Parameters:
minor_loop_arrays (MinorLoopArrays) – Masked residual, phi axes, RMSF, FWHM.
minor_loop_options (MinorLoopOptions) – Gain, mask, threshold, max_iter, mask update.
- Returns:
Clean, residual, model, masked residual, and iteration count.
- Return type:
- rm_lite.utils.clean.multiscale_clean_spectrum(dirty_fdf_spectrum: numpy.typing.NDArray[numpy.complex128], phi_arr_radm2: numpy.typing.NDArray[numpy.float64], phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64], rmsf_spectrum: numpy.typing.NDArray[numpy.complex128], rmsf_fwhm: float, scales: numpy.typing.NDArray[numpy.float64], clean_options: RMCleanOptions, multiscale_options: MultiscaleOptions) tuple[numpy.typing.NDArray[numpy.complex128], numpy.typing.NDArray[numpy.complex128], numpy.typing.NDArray[numpy.complex128], int, int]¶
Multiscale CLEAN one FDF spectrum (Offringa & Smirnov 2017).
Two-phase auto-mask (Section 2.2.3): phase 1 cleans to mask and records where each scale places flux; phase 2 deep-cleans to threshold, restricting each scale to its dilated phase-1 footprint (stops a scale smearing flux across the window). Give a generous phi window, as scale kernels wider than it pick up reflect-mode boundary artefacts.
- Parameters:
dirty_fdf_spectrum (NDArray[np.complex128]) – Dirty FDF on the phi axis.
phi_arr_radm2 (NDArray[np.float64]) – Faraday depth axis in rad/m^2.
phi_double_arr_radm2 (NDArray[np.float64]) – Double-phi axis (RMSF length).
rmsf_spectrum (NDArray[np.complex128]) – RMSF on the double-phi axis.
rmsf_fwhm (float) – RMSF FWHM in rad/m^2.
scales (NDArray[np.float64]) – Scales in RMSF FWHM units.
clean_options (RMCleanOptions) – Mask, threshold, gain, max_iter.
multiscale_options (MultiscaleOptions) – Kernel, selector, sub-minor settings.
- Returns:
minor_iters counts minor cycles (scale re-selections); sub_minor_iters the per-scale Hogbom steps (comparable to single-scale’s iteration count).
- Return type:
(clean, resid, model, minor_iters, sub_minor_iters)
- rm_lite.utils.clean.restore_model(model_fdf_spectrum: numpy.typing.NDArray[numpy.complex128], phi_arr_radm2: numpy.typing.NDArray[numpy.float64], rmsf_fwhm: float) numpy.typing.NDArray[numpy.complex128]¶
Restore a delta model with a unit-peak clean beam (one pass).
Sum of per-component Gaussians == the delta model convolved with the clean beam; doing it once from the final model is identical to the old per-iteration restore but avoids a full-array Gaussian every minor iteration. Distinct component channels are bounded by the FDF length, so the outer sum is at most len(phi)^2.
- rm_lite.utils.clean.rmclean(rm_synth_arrays: RMSynthArrays, clean_options: RMCleanOptions, multiscale_options: MultiscaleOptions | None = None, phi_max_scale_radm2: float | None = None) RMCleanResults¶
Validate array shapes and CLEAN each pixel (single- or multi-scale).
- Parameters:
rm_synth_arrays (RMSynthArrays) – Dirty FDF cube, phi axes, RMSF, masks.
clean_options (RMCleanOptions) – Mask, threshold, gain, max_iter, FDF noise.
multiscale_options (MultiscaleOptions | None) – Multiscale RM-CLEAN settings (recovers Faraday-thick structure). None runs single-scale RM-CLEAN.
phi_max_scale_radm2 (float | None) – Largest recoverable Faraday scale (pi / lambda_sq_min); sets the auto scale range. None falls back to the phi window.
- Raises:
ValueError – If the input array shapes are inconsistent.
- Returns:
Per-pixel clean/model/resid cubes and iteration counts.
- Return type:
- rm_lite.utils.clean.shift_rmsf(rmsf_spectrum: numpy.typing.NDArray[numpy.complex128], fdf_index: int, n_phi_pad: int, max_rmsf_index: int) numpy.typing.NDArray[numpy.complex128]¶
Roll the double-length RMSF so its peak sits at FDF channel fdf_index, then clip to FDF length.
Shared shift-and-subtract primitive (Hogbom and multiscale); assumes integer shifts and a symmetric RMSF.
- Parameters:
- Returns:
RMSF shifted to fdf_index, clipped to FDF length.
- Return type:
NDArray[np.complex128]
- rm_lite.utils.clean.tapered_quad_kernel_function(phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64], scale: float, rmsf_fwhm: float, sum_normalised: bool = True) numpy.typing.NDArray[numpy.float64]¶
Tapered quadratic scale kernel (Offringa & Smirnov 2017, eq. 2).
- rm_lite.utils.clean.DIVERGENCE_FACTOR = 2.0¶
- rm_lite.utils.clean.DType¶
- rm_lite.utils.clean.HYBRID_ENGAGE_MASK_FACTOR = 2.0¶
- rm_lite.utils.clean.HYBRID_SCORE_FACTOR = 0.85¶
- rm_lite.utils.clean.HYBRID_WIDTH_FACTOR = 1.2¶
- rm_lite.utils.clean.KERNEL_FUNCS: dict[str, collections.abc.Callable[Ellipsis, numpy.typing.NDArray[numpy.float64]]]¶
- type rm_lite.utils.clean.KernelType = Literal['tapered_quad', 'gaussian']¶
- rm_lite.utils.clean.STALL_PATIENCE = 5¶
- rm_lite.utils.clean.STALL_REL_IMPROVEMENT = 0.01¶
- type rm_lite.utils.clean.SelectionType = Literal['snr', 'hybrid']¶
- rm_lite.utils.clean.TQDM_OUT¶