Visualisation#
Plotting and visualisation support for SONGS-generated spectral cubes.
This module provides small, focused plotting utilities that operate on the
results list produced by generate_cubes().
Each public helper accepts the results container and an index selecting
which generated cube to visualise. The functions are intentionally lightweight
and return a Matplotlib (fig, ax) pair so callers (GUIs, scripts, tests)
can further customise or save figures. It also provides the interactive
Tkinter viewer windows (SliceViewer, AnalysisViewer) used
by the SONGS GUI to inspect generated cubes channel-by-channel and to browse
per-source moment maps and spectra.
Dependencies#
- matplotlib (this module sets the
TkAggbackend by default, unless an inline backend is already active).
- matplotlib (this module sets the
- astrodendro, used to compute a coarse dendrogram-based mask that highlights
contiguous emission for the moment-map helpers.
Notes
_prepare_cube()extracts the cube and its metadata and computes thedendrogram-based mask shared by the moment-map helpers. The dendrogram parameters are deliberately conservative and may need tuning for different signal-to-noise regimes.
- The plotting functions attempt to save to
figures/<shape>/when save=Trueis passed; save failures are intentionally ignored to keep UI flows robust.
- The plotting functions attempt to save to
- class songs.visualise.AnalysisViewer(master, data, idx: int = 0, noisy_data=None)[source]#
Bases:
ToplevelCombined analysis viewer: Moment 0, Moment 1, and integrated spectrum.
Source checkboxes (one per galaxy) and diffuse-component checkboxes let the user select which components contribute to all three panels. The layout mirrors the nemo analysis viewer: two moment maps side-by-side on top, spectrum spanning the full width below.
- Parameters:
master (tkinter widget) – Parent window this viewer is opened as a
Toplevelof.data (sequence) – The
resultscontainer produced bySONGS.generate_cubes.data[idx]must be a(cube, meta)tuple wherecubeis a NumPy array of shape(n_vel, ny, nx)in Jy/beam andmetais a dict with keys including'average_vels'(km/s),'beam_info','pix_spatial_scale'(kpc/pixel), and optionally'per_galaxy_cubes','halo_cube', and'bridges_cube'.idx (int, optional) – Index of the cube to display (default 0).
noisy_data (sequence or None, optional) – A
results-like container in the same shape/idx convention asdata, holding the noisy version of the same cube (present only when noise was simulated at generation time). When given, the viewer defaults to displaying the noisy cube and exposes a Clean/Noisy toggle; per-source and diffuse component arrays remain the clean ground truth either way, since noise is an instrument effect on the observed total rather than a per-source quantity.
- class songs.visualise.SliceViewer(master, data, idx: int = 0, noisy_data=None)[source]#
Bases:
ToplevelChannel-by-channel IFU slice viewer matching nemo aesthetics.
Displays the full spectral cube with colormap / normalization controls, vmin/vmax sliders, and (when per-galaxy cubes are available) a sources sidebar with per-source contours, bounding boxes, and intensity-threshold masks whose threshold percentage is tunable via a dedicated slider.
- Parameters:
master (tkinter widget) – Parent window this viewer is opened as a
Toplevelof.data (sequence) – The
resultscontainer produced bySONGS.generate_cubes.data[idx]must be a(cube, meta)tuple wherecubeis a NumPy array of shape(n_vel, ny, nx)in Jy/beam andmetais a dict with keys including'average_vels'(km/s),'beam_info','pix_spatial_scale'(kpc/pixel), and optionally'per_galaxy_cubes'(shape(n_gal, n_vel, ny, nx)).idx (int, optional) – Index of the cube to display (default 0).
noisy_data (sequence or None, optional) – A
results-like container in the same shape/idx convention asdata, holding the noisy version of the same cube (present only when noise was simulated at generation time). When given, the viewer defaults to displaying the noisy cube and exposes a Clean/Noisy toggle; per-source component arrays remain the clean ground truth either way, since noise is an instrument effect on the observed total rather than a per-source quantity.
- songs.visualise.moment0(data, idx, save=False, fname_save=None, inline=False)[source]#
Plot the zeroth moment (integrated intensity) of a spectral cube.
- Parameters:
data (sequence) – The
resultscontainer produced bySONGS.generate_cubes.idx (int) – Index selecting which cube to plot.
save (bool, optional) – If True, attempt to save the figure to
figures/<shape>/moment0.pdf.fname_save (str or None, optional) – Optional directory to save the figure. If None a path under the current working directory is chosen automatically.
- Returns:
fig, ax – Matplotlib figure and axes objects containing the rendered moment map.
- Return type:
(Figure, Axes)
- songs.visualise.moment1(data, idx, save=False, fname_save=None)[source]#
Plot the first moment (intensity-weighted velocity) of a spectral cube.
- Parameters:
data (sequence) – The
resultscontainer produced bySONGS.generate_cubes.idx (int) – Index selecting which cube to plot.
save (bool, optional) – If True, attempt to save the figure to
figures/<shape>/moment1.pdf.fname_save (str or None, optional) – Optional directory to save the figure. If None a path under the current working directory is chosen automatically.
- Returns:
fig, ax – Matplotlib figure and axes objects containing the rendered moment map.
- Return type:
(Figure, Axes)
- songs.visualise.slice_view(data, idx=0, channel=None, cmap='viridis', parent=None)[source]#
Show a per-channel slice viewer embedded in a Tk window.
This viewer embeds the Matplotlib figure into a Tk Toplevel and uses a ttk-styled slider to step through spectral channels. The viewer keeps the lower colour limit fixed at 0 and computes an upper limit per slice so contrast adapts to the currently displayed channel.
- Parameters:
data (sequence) – The
resultscontainer produced bySONGS.generate_cubes.idx (int, optional) – Index of the cube within
datato display (default 0).channel (int, optional) – Initial spectral channel index to show. If
None(the default) the viewer will open on the central spectral channel (int(n/2)).cmap (str, optional) – Matplotlib colormap to use for imshow.
parent (tkinter widget, optional) – If provided, the slice viewer will be a child Toplevel of this widget. Otherwise a new Toplevel (or root) is used.
- Returns:
fig, ax – The Matplotlib figure and axes used by the embedded viewer.
- Return type:
(Figure, Axes)
- songs.visualise.spectrum(data, idx, save=False, fname_save=None)[source]#
Plot the integrated spectrum (total flux vs velocity) for a cube.
- Parameters:
data (sequence) – The
resultscontainer produced bySONGS.generate_cubes.idx (int) – Index selecting which cube to plot.
save (bool, optional) – If True, save the figure as
spectrum.pdfunderfigures/<shape>/unlessfname_saveoverrides the path.fname_save (str or None, optional) – Optional directory to save the figure.
- Returns:
fig, ax – The Matplotlib figure and axes containing the spectrum.
- Return type:
(Figure, Axes)
Helper Functions#
The songs.visualise module provides lightweight wrappers around Matplotlib
for the most common cube inspection tasks.
moment0#
from songs.visualise import moment0
moment0(cube, save=False, fname=None)
Computes and displays the moment-0 (integrated intensity) map by summing the cube along the spectral axis. Optionally saves the figure to fname as a PDF.
moment1#
from songs.visualise import moment1
moment1(cube, vels, beam_info=None, save=False, fname=None)
Computes the intensity-weighted velocity map:
An optional beam marker (ellipse) is overlaid when beam_info is provided.
spectrum#
from songs.visualise import spectrum
spectrum(cube, vels, save=False, fname=None)
Plots the spatially-integrated line-of-sight spectrum: flux summed over the spatial axes as a function of velocity channel.
SliceViewer Class#
SliceViewer provides an interactive channel-by-channel viewer launched
either from the GUI or standalone:
from songs.visualise import SliceViewer
viewer = SliceViewer(cube, sources=sources_list, vels=vels)
viewer.show()
sources mode: when sources is a list of per-source component cubes,
the viewer activates the per-source sidebar so that contours, bounding boxes
and threshold masks are computed independently for each source component.
Key interactive controls:
Channel slider — step through spectral slices.
Source selector sidebar — toggle which source’s overlays are shown.
Contour level spinner — set contour threshold as a fraction of the channel peak.
Threshold slider — mask voxels below a chosen intensity fraction.
Bounding-box toggle — show/hide axis-aligned bounding boxes per source.