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_TEMPFILESfor 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:
ToplevelTop-level log window that captures and displays stdout/stderr.
LogWindowcreates a simple resizable Toplevel containing a TkTextwidget and installsTextRedirectorinstances onsys.stdoutandsys.stderrso that all subsequentprintoutput and uncaught exception tracebacks are visible in the GUI. The window restores the original streams when closed.Behaviour#
- Creating an instance replaces
sys.stdoutandsys.stderrin the running interpreter until the window is closed (
on_close).
- Creating an instance replaces
- The window configures a separate text tag for
stderrso error messages are coloured differently.
- The window configures a separate text tag for
Example
>>> log = LogWindow(root) >>> log.deiconify() # show the window
- class songs.gui.SONGSGUI(theme: str = 'dark')[source]#
Bases:
TkMain 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. CallingGenerateruns the generator in a background daemon thread so the UI remains responsive; generated results become available viaself.generator.results.
- Visualisation buttons call into functions defined in
songs.visualisewhich 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_TEMPFILESlist and cleaned up when the GUI is closed via_on_close.
- Temporary files created by
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_closeaccordingly.
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
SONGSobject 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.
- 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.generatorreference 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.
- class songs.gui.TextRedirector(widget, tag='stdout')[source]#
Bases:
objectRedirect writes into a Tk
Textwidget 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).
TextRedirectorimplements a minimal stream interface (writeandflush) so it can be assigned directly tosys.stdoutorsys.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')
- 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:
Initialisation Parameters — grid size, number of spectral channels, number of galaxies, random seed, output directory.
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.
Satellite Properties — satellite offset (pixels), satellite systemic velocity offset, beam parameters (bmin, bmaj, BPA).
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 masterenabledtoggle. 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.
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.