GUI Reference#

SONGS GUI

Compact Tkinter-based GUI to interactively configure and run the SONGS generator. Provides a three-column layout of parameter frames, crisp LaTeX-rendered labels, convenience sliders, and utility buttons (Generate, Slice, Moments, Spectrum, Save, New). Plotting and file I/O are intentionally kept out of the generator core; the GUI imports top-level visualisation helpers (moment0, moment1, spectrum, slice_view) to display results.

Design notes#

  • Lightweight: the GUI focuses on inspection and quick interactive

    experimentation, not production batch runs.

  • Threading: generation runs in a background thread so the UI remains

    responsive; generated figures are produced by the visualise helpers.

  • Cleanup: LaTeX labels are rendered to temporary PNG files (via

    matplotlib) and tracked in _MATH_TEMPFILES for removal when the application exits.

Usage#

Run the module as a script to display the GUI:

python -m songs.gui

Or instantiate SONGSGUI and call mainloop(). The GUI expects the package to be importable (it will try a fallback path insertion when executed as a script).

class songs.gui.LogWindow(master)[source]#

Bases: Toplevel

Top-level log window that captures and displays stdout/stderr.

LogWindow creates a simple resizable Toplevel containing a Tk Text widget and installs TextRedirector instances on sys.stdout and sys.stderr so that all subsequent print output and uncaught exception tracebacks are visible in the GUI. The window restores the original streams when closed.

Behaviour#

  • Creating an instance replaces sys.stdout and sys.stderr in

    the running interpreter until the window is closed (on_close).

  • The window configures a separate text tag for stderr so error

    messages are coloured differently.

Example

>>> log = LogWindow(root)
>>> log.deiconify()  # show the window
on_close()[source]#
class songs.gui.SONGSGUI(theme: str = 'dark')[source]#

Bases: Tk

Main GUI application for interactively configuring and running SONGS simulations.

This class implements a compact, self-contained Tk application that exposes the most commonly-used parameters of the generator via a three-column layout of parameter panels. Controls include numeric sliders, textual inputs and convenience buttons that invoke high-level visualisation helpers (moment0, moment1, spectrum) or persist generated results to disk.

Key behaviour#

  • The generator is constructed from the current UI values and stored

    on self.generator. Calling Generate runs the generator in a background daemon thread so the UI remains responsive; generated results become available via self.generator.results.

  • Visualisation buttons call into functions defined in

    songs.visualise which create Matplotlib figures; these functions are intentionally separate from the generator core so the GUI remains a thin orchestration layer.

  • Temporary files created by latex_label() are tracked in the

    module-level _MATH_TEMPFILES list and cleaned up when the GUI is closed via _on_close.

Threading and shutdown#

  • Generation and save operations spawn background daemon threads. The

    UI schedules finalisation callbacks back on the main thread using self.after(...) when worker threads complete.

  • Closing the main window triggers a cleanup of temporary files and

    forces process termination to avoid orphaned interpreters. If you prefer a softer shutdown that joins worker threads, modify _on_close accordingly.

Usage example#

Run the GUI as a script:

python -m songs.gui

Or instantiate from Python:

from songs.gui import SONGSGUI
app = SONGSGUI()
app.mainloop()
create_generator()[source]#

Instantiate a SONGS object from current UI values.

The method calls _collect_parameters() to assemble a parameter dictionary and then constructs a single-cube generator instance with sensible defaults for fields not exposed directly in the GUI. After construction the per-galaxy attributes on the generator are filled from the collected parameters so the generator is ready to run.

generate()[source]#
make_slider(parent, label, var, from_, to, resolution=0.01, fmt='{:.2f}', integer=False)[source]#

Create a labelled slider widget with snapping and a value label.

reset_instance()[source]#

Reset the GUI to a fresh state and disable visualisation/save.

This clears the in-memory self.generator reference so that the next generate action will create a new instance from current UI values. Buttons that depend on generated results are disabled.

save_sim()[source]#

Generate (if needed) and save the sim tuple (cube, params).

This runs generation in a background thread and then opens a Save-As dialog on the main thread to let the user choose where to store the result. We support .npz (numpy savez) and .pkl (pickle) formats; complex parameter dicts fall back to pickle.

show_analysis()[source]#

Open the combined Analysis viewer (moments + spectrum + source checkboxes).

show_logs()[source]#
show_slice()[source]#

Open the SONGS SliceViewer for the first generated cube.

class songs.gui.TextRedirector(widget, tag='stdout')[source]#

Bases: object

Redirect writes into a Tk Text widget behaving like a stream.

Use this helper to capture and display program output inside the GUI (for example, to show progress logs, exceptions, or print() output). TextRedirector implements a minimal stream interface (write and flush) so it can be assigned directly to sys.stdout or sys.stderr; written text is inserted into the provided Tk Text widget and scrolled to the end so the latest output is visible.

Threading note#

  • The class itself is not thread-safe: writes coming from background threads should be marshalled to the Tk mainloop (e.g. via widget.after(...)) if there is a risk of concurrent access.

param widget:

The Tk Text widget where text will be appended.

type widget:

tk.Text

param tag:

Optional text tag name to apply to inserted text (default 'stdout').

type tag:

str, optional

Example

Redirect stdout into a Text widget:

txt = tk.Text(root)
txt.pack()
sys.stdout = TextRedirector(txt, tag='log')
flush()[source]#
write(string)[source]#
songs.gui.main()[source]#
songs.gui.param_frame(parent, padding=8, border_color='#797979', bg='#303030', width=None, height=80, do_pack=True)[source]#

Create a framed parameter panel used throughout the GUI.

songs.gui.rich_label(parent, segments, bg=None, fg='white')[source]#

Render a symbol with superscript/subscript on a tk.Canvas.

Uses exact pixel placement so subscript descenders are never clipped.

Parameters:
  • parent (tk.Widget)

  • segments (list of (str, str) where the second element is one of:) – 'n' — normal baseline 's' — subscript (small, lowered) 'p' — superscript (small, raised)

  • bg (str or None Background colour; defaults to parent's background.)

  • fg (str Foreground (text) colour.)

Return type:

tk.Canvas Sized exactly to the rendered content.

Overview#

The SONGS GUI (src/songs/gui.py) is a Tkinter-based interactive front end for generating and inspecting synthetic spectral cubes. It features a 4-column dark-themed card layout with the SONGS banner across the top.

Layout#

Controls are grouped into four card columns:

  1. Initialisation Parameters — grid size, number of spectral channels, number of galaxies, random seed, output directory.

  2. Central Galaxy Properties — Sérsic index \(n\), effective radius \(R_e\) (via resolution parameter r), scale height \(h_z\), central flux density \(S_e\), inclination, position angle.

  3. Satellite Properties — satellite offset (pixels), satellite systemic velocity offset, beam parameters (bmin, bmaj, BPA).

  4. Diffuse Features — interactive sliders and entry fields that map directly to DEFAULT_DIFFUSE_PARAMS: halo amplitude (halo_Se_factor), bridge amplitude (bridge_Se_factor), streamer/tail amplitude (tail_Se_factor), tail velocity gradient (tail_vel_gradient), tail decay scale (tail_decay_scale), and the master enabled toggle. See Generator Reference for the full parameter reference.

All parameter changes take effect immediately when the user clicks Generate.

Launch Instructions#

From the package root:

python -m songs.gui

Or directly:

cd src/songs
python gui.py

Generation runs in a background thread so the interface remains responsive. Progress is streamed to the built-in Log window.

SliceViewer#

After a cube has been generated the Open SliceViewer button launches the built-in IFU SliceViewer:

  • Per-source sidebar — select which galaxy component (central, satellite 1, satellite 2, …) to highlight; switching sources updates all overlays instantly.

  • Contour overlays — per-source emission contours drawn at a configurable fraction of the peak channel intensity.

  • Bounding boxes — axis-aligned bounding boxes around each detected source region for quick spatial extent assessment.

  • Intensity threshold masking — a threshold slider suppresses low-surface- brightness residuals below a chosen fraction of the peak without re-generating the cube.

Visualisation Buttons#

Once generation has completed the following buttons become active:

  • Moment-0 — integrated intensity map (sum along spectral axis).

  • Moment-1 — intensity-weighted velocity map with beam marker overlay.

  • Spectrum — integrated line-of-sight flux vs velocity.

These open interactive Matplotlib figures; use the standard toolbar to pan, zoom, and save.

Saving#

The Save button writes the current cube and parameter dictionary to disk without re-running generation. Supported formats: .npz (compressed NumPy archive) and .pkl (Python pickle). Saved contents include the spectral cube array, beam information, pixel spatial scale, and average velocity values.