Source code for pipeline.hsd.cli.hsd_baseline

import pipeline.h.cli.utils as utils


# docstring and type hints: inherits from hsd.tasks.baseline.baseline.SDBaselineInputs.__init__
[docs] @utils.cli_wrapper def hsd_baseline( fitfunc=None, fitorder=None, switchpoly=None, linewindow=None, linewindowmode=None, edge=None, broadline=None, clusteringalgorithm=None, wave_number=None, deviationmask=None, deviationmask_sigma_threshold=None, parallel=None, infiles=None, field=None, antenna=None, spw=None, pol=None ): """Detect spectral line features and subtract the baseline from calibrated single-dish spectra. Generates baseline fitting tables and subtracts the baseline from the spectra by masking detected emission/absorption line regions. The WebLog shows three sections of spectral grid maps per source: 1. Spectra **before** baseline subtraction (red fitted curve overlaid on each grid cell). 2. **Averaged** spectra per grid cell (improves S/N to reveal line features). 3. Spectra **after** baseline subtraction (red line at zero level per grid cell). Cyan-shaded regions indicate the sum of all emission-line channels identified across the entire map (not just the individual grid cell). A spatially integrated spectrum per ASDM, antenna, spw, and polarization is shown above each grid, with the magenta curve indicating atmospheric transmission and thick red bars marking channels excluded by the ``deviation mask`` algorithm. Representative spectra in each cell correspond to the valid pointing nearest the mean coordinates of all pointings in that grid cell. .. figure:: /figures/hsd_baseline_representative.png :scale: 60% :alt: Representative position determination Examples of how representative positions are determined. Blue points are all pointings; brown crosses are the averaged coordinates; green circles mark the representative positions (nearest valid pointing to the averaged coordinates). .. figure:: /figures/guide-img036.jpg :scale: 60% :alt: hsd_baseline WebLog page Example of the ``hsd_baseline`` WebLog page showing the first three spectral grid rows (before subtraction, averaged, after subtraction) for one spw. Detailed per-antenna spectral maps can be accessed from the detail pages by clicking the **Spectral Window** link on each summary page. Filters by antenna, field, spectral window, and polarization are available in the upper part of the detail pages. **Fitting order determination**: The default function is a cubic spline. The number of spline segments (``N_segment``) is determined via FFT analysis of the power spectrum of grouped spectra: 1. ``1 < P_FFT < 3`` -- ``N_segment = 4`` 2. ``3 <= P_FFT < 5`` -- ``N_segment = 5`` 3. ``5 <= P_FFT < 10`` -- ``N_segment = 6`` 4. ``P_FFT >= 10`` -- ``N_segment = F_FFT * 2 + 2`` The final ``N_segment`` is scaled by ``(Nch - N_mask) / Nch`` to account for masked channels. Specifying a non-negative integer for ``fitorder`` disables auto-determination. **Mask range determination**: Emission/absorption channels are identified by comparing spectral deviation from the median against an MAD-based threshold. Up to 10 iterations are performed to detect weak lines; each detected range is extended while the intensity is monotonically decreasing/increasing. Binned spectra (widths 1, 4, 16, 64 for 4096-channel spws) are also analyzed for broad features, with threshold ``3.5 + sqrt(binning_width) * MAD``. **Baseline flatness evaluation** (fourth section of the WebLog page): Emission-free channels are divided into 10 or 20 bins. ``MAX(mean) - MIN(mean)`` across bins is compared to the spectral rms ``sigma``. .. figure:: /figures/guide-image-new-baselineflatness.png :scale: 60% :alt: Baseline flatness evaluation Example of baseline flatness evaluation. **Clustering analysis** for spectral line detection (developer plots, hidden by default; enable with ``plotlevel='all'`` in ``h_init``): *Detection*: grid cells with emission exceeding the threshold are identified. Yellow cells have a single time-domain group with detected emission; cyan cells have more than one. .. figure:: /figures/guide-img037.png :scale: 60% :alt: Clustering detection Clustering detection step. *Validation*: for each grid cell the ratio of spectra containing detected emission lines (``Nmember``) to total spectra in the cell (``Nspectra``) is computed: - **Validated** if ``Nmember/Nspectra > 0.5`` - **Marginally validated** if ``Nmember/Nspectra > 0.3`` - **Questionable** if ``Nmember/Nspectra > 0.2`` .. figure:: /figures/guide-img038.png :scale: 60% :alt: Clustering validation Clustering validation step. *Smoothing*: the per-cell ratio is convolved with a Gaussian-like grid function to suppress isolated single-line candidates and reinforce detections supported by neighboring cells. .. figure:: /figures/guide-img039.png :scale: 60% :alt: Clustering smoothing Clustering smoothing step. *Mask region determination*: in the validated area after smoothing, mask channel ranges are computed over the spatial domain by inter/extrapolating the mask ranges of the averaged spectra in validated cells and applied to each individual spectrum. .. figure:: /figures/guide-img040.png :scale: 60% :alt: Mask range calculation Mask range calculation — in blue squares the mask range is interpolated from validated cells. .. figure:: /figures/guide-img041.png :scale: 60% :alt: Clustering final Clustering final example. Notes: Three QA scores are computed: **Spectral line detection**: - QA = 1.0 if no edge-line and main line is narrow. - QA = 0.60 if no edge-line and main line is wide. - QA = 0.55 if edge-line detected (regardless of main line width). - QA = 0.80 if no spectral lines are detected. - QA = 0.88 if the deviation mask overlaps with spectral or atmospheric lines. **Baseline flatness** (MAX(mean) - MIN(mean) vs. sigma): - QA = 0.33 if MAX(mean) - MIN(mean) > 3.6 sigma. - QA = 0.33-1.0 if 1.8 sigma <= MAX(mean) - MIN(mean) < 3.6 sigma. - QA = 1.0 if MAX(mean) - MIN(mean) < 1.8 sigma. **Deviation from zero-baseline**: QA = 0.65 if significant deviation outside candidate line ranges is detected (triggering deviation masks). Warning: ``hsd_baseline`` overwrites results from previous runs. If processing spws separately, each spw must be taken through to the imaging stage before the next spw is processed:: hsd_baseline(spw='0'); hsd_blflag(spw='0'); hsd_imaging(spw='0') hsd_baseline(spw='1'); hsd_blflag(spw='1'); hsd_imaging(spw='1') Returns: The results object for the pipeline task is returned. Examples: 1. Basic usage with automatic line detection: >>> hsd_baseline(antenna='PM03', spw='17,19') 2. Use pre-defined line windows instead of automatic detection: >>> hsd_baseline(linewindow=[[100, 200], [1200, 1400]], linewindowmode='replace', edge=[10, 10]) 3. Per-spw pre-defined line windows merged with automatic detection: >>> hsd_baseline(linewindow={19: [[390, 550]], 23: [[100, 200], [1200, 1400]]}, ... linewindowmode='merge') """