Visual Inspection Tool for Quasar Spectra
This repository provides a visual inspection tool for quasar spectra. The tool enables you to load FITS spectra, interactively adjust the redshift using a non‐linear slider and spin box, and classify each spectrum using simple keyboard shortcuts. It also supports loading previous inspection results from a CSV history file so that already inspected spectra are skipped.
Online documentation (Read the Docs): https://specbox.readthedocs.io/en/latest/index.html
Citation:
@software{fu_2026_18642758,
author = {Fu, Yuming},
title = {specbox: A simple tool to manipulate and visualize
UV/optical/NIR spectra for astronomical research.
},
month = feb,
year = 2026,
publisher = {Zenodo},
version = {v1.0.0},
doi = {10.5281/zenodo.18642758},
url = {https://doi.org/10.5281/zenodo.18642758},
}
Table of Contents
Prerequisites and Installation of specbox
Python Version: Python 3
Dependencies:
Ensure that you have the following Python packages installed:PySide6
pyqtgraph
matplotlib
numpy
pandas
astropy
specutils
requests
pillow (PIL)
astroquery
You can create a new environment (e.g. euclid) and install the required packages using conda:
conda create -n euclid python=3.13
conda activate euclid
pip install PySide6 specutils pyqtgraph astropy pandas matplotlib requests pillow astroquery setuptools
Installation:
It is recommended to set up an isolated environment before installing (choose either option A or B):
# Option A: Python venv
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
# Option B: conda
conda create -n specbox python=3.13 -y
conda activate specbox
python -m pip install --upgrade pip
Install the stable release from PyPI (recommended):
python -m pip install specbox
To install a pre-release/development version from source:
git clone https://github.com/rudolffu/specbox.git
cd specbox
python -m pip install .
Project Structure:
The visual inspection tool is part of the packagespecboxwhich contains:qtmodule/qtsir1d.py– Main GUI code.basemodule.py– Contains classes (such asSpecEuclid1d) to read the FITS spectra.
Running the Tool
Test installation of specbox
To test the installation, you can run the following code snippet in a Python shell or script:
import matplotlib.pyplot as plt
from specbox.basemodule import SpecEuclid1d
sp1 = SpecEuclid1d(
'COMBINED_SPECS.fits',
ext=1,
good_pixels_only=True, # Keep only recommended bins from Euclid MASK flags
) # example path to the FITS file containing spectra
sp1.plot()
plt.show()
If the installation is successful, you should see a plot of the spectrum.
Notes:
SpecEuclid1dexposesmask,good_mask, andbad_mask(when theMASKcolumn is present).good_pixels_only=Trueapplies the Euclid recommendation to discard bins with oddMASKorMASK >= 64.
Reading SPARCL parquet spectra (dataframe-backed)
If your spectra are stored in a table file (e.g. parquet) where each row is a spectrum and the row contains array columns like wavelength, flux, and ivar, you can use SpecSparcl:
from specbox.basemodule import SpecSparcl
sp1 = SpecSparcl('outlier_sparcl_spectra.parquet', ext=1) # ext is 1-based row index
sp1.plot()
Parquet input requires either pyarrow or fastparquet to be installed.
To run the visual inspection GUI directly on such a multi-row parquet file:
from specbox.basemodule import SpecSparcl
from specbox.qtmodule import PGSpecPlotThreadEnhanced
viewer = PGSpecPlotThreadEnhanced(
spectra='outlier_sparcl_spectra.parquet',
SpecClass=SpecSparcl,
# Optional: overlay Euclid spectrum when the parquet has `euclid_object_id`
# and the Euclid combined FITS uses that ID as `EXTNAME`.
euclid_fits='COMBINED_EUCLID_SPECS.fits',
output_file='sparcl_vi_results.csv',
z_max=6.0,
load_history=True,
)
viewer.run()
Notes:
The results CSV includes
targetidanddata_releasewhen present in the input table.Use the
Save PNGbutton to save a screenshot to./saved_pngs/.
Running the Visual Inspection Tool
You can run the tool by creating an instance of the inspection thread. For example, create a Python script (my_vi_script.py) with the following code:
#!/usr/bin/env python
from specbox.qtmodule.qtsir1d import PGSpecPlotThread
a = PGSpecPlotThread(
specfile='COMBINED_SPECS.fits', # example path to the FITS file containing the spectra
output_file='vi_results.csv', # path to the output CSV file
z_max=5.0,
load_history=True
)
a.run()
Run the script in a terminal (ensure that the correct environment is activated):
python my_vi_script.py
The first time you run the tool in a new Python environment, matplotlib will take some time to build the font cache. Subsequent runs will be faster.
Parameter Explanation
specfile:
The path to the FITS file containing the spectra.output_file:
The CSV file where inspection results (object classification and redshift) are saved.z_max: The maximum redshift to be considered for the slider. The default is 5.0.
load_history:
If set toTrueand the CSV exists, the tool loads previous classifications and skips those spectra.
User Interface Overview
Layout
Plot Area:
The main window displays the current quasar spectrum.Slider:
A horizontal slider at the bottom controls the visually inspected redshift (z_vi). It uses a non-linear (1+z) mapping.Spin Box:
Next to the slider is a QDoubleSpinBox that shows the current redshift value. You can type a custom redshift here. Both controls are synchronized.
How the Slider Works
The slider’s mapping is given by:
[ z = \exp(\text{base_z_step} \times \text{slider_value}) \times (1 + z_{\min}) - 1 ]
This mapping allows the step size to increase with redshift, matching the natural (1+z) scaling of spectral features.
Keyboard Shortcuts and Actions
When the tool is active, use the following keys:
Q:
Loads the next spectrum. If only Q is pressed, the default classification QSO(Default) will be adopted. If the user chooses other classifications (keys below), using Q is also needed to load the next spectrum.S:
Classifies the spectrum as STAR (sets redshift to 0).G:
Classifies the spectrum as GALAXY.A:
Classifies the spectrum as QSO (AGN).U:
Classifies the spectrum as UNKNOWN.L:
Classifies the spectrum as LIKELY/Unusual QSO.M:
Prints the current mouse position in the plot (useful for measurements).Spacebar:
Prints the wavelength and flux at the mouse location and annotates the plot.R:
Resets the plot to its original state (undo zooming/panning).Ctrl+R: Resets the redshift (
z_vi) to the original value in the current plot.Left Arrow:
Loads the previous spectrum (useful for reviewing).Right Arrow:
Loads the next spectrum. Only for reviewing because this action does not save the classification and redshift of the current spectrum.Ctrl+Left Arrow:
Goes back to the first spectrum in the list.Ctrl+Right Arrow:
Goes to the last spectrum in the list.Ctrl+B:
Goes back to the last labeled spectrum.
History and Resuming Inspections
Saving Results:
The tool saves classifications to the specified CSV file (with columns for object ID, object name, RA, DEC, assigned class, and visually inspected redshiftz_vi) periodically and when exiting.Loading History:
Whenload_history=Trueis provided, the tool reads the CSV file and loads the object IDs into a dictionary. It then skips any spectrum whose ID already exists in the history, allowing you to resume from where you left off.
Tips for Effective Use
Adjust the Redshift:
Use the slider or spin box to fine-tune the redshift until the template (plotted in a contrasting color) aligns well with the observed spectrum.Keyboard Shortcuts:
Familiarize yourself with the key commands to quickly classify and navigate spectra without needing to use the mouse extensively.Review History:
Check the CSV file if you need to confirm that classifications are being saved correctly and that object IDs match.Customization:
You can modify parameterz_maxin the script if your spectral redshift range differs.