qsoabsfind is a Python module for detecting absorbers with doublet properties (absorbers with two close lines) in low-resolution quasar spectra (e.g. SDSS, DESI, MUSE, 4MOST, WAVES, WEAVE etc.). It identifies absorption systems using a convolution-based, adaptive signal-to-noise approach, followed by Gaussian fitting and a set of selection checks to eliminate false positives.
The module also calculates rest-frame equivalent widths (EWs), FWHM and line centers using a double-Gaussian model. Optionally, it can calculate the total column densities of metal absorbers using the apparent optical depth method (AODM). It can run with either the default search parameters or user-provided custom ones.
It also provides the ability to search for additional absorber systems at the redshifts of known absorbers. This is useful for constructing multi-line absorber catalogs and for validating detections using multiple transitions.
| Absorber | Line 1 (Ang) | Line 2 (Ang) | Comments |
|---|---|---|---|
| O VI (O⁵⁺) | 1031.93 | 1037.62 | Lines fall inside the Ly-alpha forest; makes detection and confirmation difficult |
| N V (N⁴⁺) | 1238.82 | 1242.80 | Lies near the red edge of the Ly-alpha forest; avoiding the forest leaves a very short absorber path length, but detection is feasible |
| Si IV (Si³⁺) | 1393.76 | 1402.77 | Searching outside the Ly-alpha forest; relatively clean spectral region, easier to detect and confirm |
| C IV (C³⁺) | 1548.20 | 1550.77 | Searching outside the Ly-alpha forest; one of the strongest UV doublets, easy to detect and confirm |
| Al III (Al²⁺) | 1854.72 | 1862.79 | Searching outside the Ly-alpha forest; clean region |
| Fe II (Fe⁺) | 2586.65 | 2600.17 | Searching outside the Ly-alpha forest; clean region; large line separation, easy to detect and confirm |
| Mg II (Mg⁺) | 2796.35 | 2803.52 | Searching outside the Ly-alpha forest; large line separation, easy to detect and confirm |
| CaII (Ca⁺) | 3934.78 | 3969.59 | Searching outside the Ly-alpha forest; though can lie in sky line region, which may make it difficult |
| NaI (Na⁰) | 5891.58 | 5897.57 | Searching outside the Ly-alpha forest; though can lie in sky line region, which may make it difficult |
Note on Absorbers: The pipeline is generic. Users can supply a custom constants file with your doublet's rest-frame wavelengths, oscillator strengths, and search bounds (see Parameter File), and the pipeline will search for it. Custom systems are functional but not as thoroughly tested as the default ones.
- Automated and Flexible Search Window: The code can dynamically define the observed-frame wavelength search window for each absorber system. Detailed definitions are provided in the Search Window Documentation. Additionally, user can also provide the wavelength boundaries to search for metal systems through the search parameter constants file.
- 9 built-in doublet systems: Automatic search-window calculation and line properties are pre-configured for MgII, CIV, OVI, NV, SiIV, AlIII, FeII, CaII, and NaI. OVI is very hard as it lies in the Ly-alpha forest. So use with caution.
-
Extensible to any doublet: The pipeline is generic. Users can supply a custom constants file (see
data/${survey}folder) with your doublet's rest-frame wavelengths, oscillator strengths, and search bounds, and the pipeline will search for it. (Custom systems are functional but not as thoroughly tested as the built-ins.) - Adaptive S/N convolution: Detects doublet absorbers in low-resolution quasar spectra using a convolution-based, adaptive signal-to-noise method.
- Gaussian profile fitting: Fits absorption lines with a double-Gaussian model to extract equivalent width, FWHM, and central wavelength.
-
Selection criteria: Identifies absorber candidates based on S/N thresholds and doublet properties. Optionally uses
$\chi^2$ statistics to get the confidence level of the selected candidates. - Pixel resolution correction: Corrects measured line widths for observed pixel resolution to infer intrinsic properties, assuming linear relation between spectral resolution and wavelength. Users can provide the linear relation parameters.
-
Known-redshift validation: When a prior absorber catalog (e.g. from another survey or absorber finder or catalog built from
qsoabsfind) is available,--zabs-known-fileskips the convolution search and runs Gaussian fitting and selection only at the supplied redshifts, allowing quick validation of known systems. -
Column Densities: Optionally estimates total column densities of detected absorbers using the apparent optical depth method (AODM; Savage & Sembach 1991). Can be turned on via
--coldens-dvto specify the velocity range for integration. -
Parallel processing: Runs across large datasets using Python's
multiprocessingmodule. - Detailed output: Catalogs with redshifts, equivalent widths, S/N ratios, and more.
- Verbose mode: Optionally prints each processing step for debugging.
-
Trapezoidal EW measurement: In addition to Gaussian-model EWs, the module computes rest-frame equivalent widths via direct trapezoidal integration (provided via
--trapz-ew-sigma) over a per-line window of$\pm n \cdot \sigma_{\rm line}$ centred on each Gaussian-fit line centre. For close doublets (e.g. C IV), the integration windows are automatically clipped at the doublet midpoint to prevent double-counting. Measurement windows and integrated areas can be visualised withplot_trapezoidal_ew_windows. EW errors also account for the systematic uncertainity in continuum placement. -
Visualization: Plot the full spectrum with all detected absorber systems marked, plus zoomed panels around each detection, using
plot_multiple_metal_systems.
- Large absorber catalog construction
- Metal-line evolution studies
- CGM/IGM absorber statistics
- Survey-scale quasar spectral analysis
The full documentation is available at https://qsoabsfind.readthedocs.io.
If you use this code in your analysis, please cite Anand, Nelson & Kauffmann 2021 and Anand et al. 2025. The BibTeX entries for these papers can be found here (2021 paper) and here (2025 paper).
Please also cite the associated Zenodo record. Consider starring the repository if you find it useful.
You can also copy the BibTeX entry directly from below.
@ARTICLE{2021MNRAS.504...65A,
author = {\{Anand}, Abhijeet and {Nelson}, Dylan and {Kauffmann}, Guinevere},
title = "{Characterizing the abundance, properties, and kinematics of the cool circumgalactic medium of galaxies in absorption with SDSS DR16}",
journal = {\mnras},
keywords = {galaxies: evolution, galaxies: formation, large-scale structure of Universe, Astrophysics - Astrophysics of Galaxies},
year = 2021,
month = jun,
volume = {504},
number = {1},
pages = {65-88},
doi = {10.1093/mnras/stab871},
archivePrefix = {arXiv},
eprint = {2103.15842},
primaryClass = {astro-ph.GA},
adsurl = {https://ui.adsabs.harvard.edu/abs/2021MNRAS.504...65A},
adsnote = {Provided by the SAO/NASA Astrophysics Data System}
}
@ARTICLE{2025ApJ...990..151A,
author = {\{Anand}, Abhijeet and {Aguilar}, J. and {Ahlen}, S. and {Bianchi}, D. and {Brodzeller}, A. and {Brooks}, D. and {Canning}, R. and {Claybaugh}, T. and {Cuceu}, A. and {de la Macorra}, A. and {Doel}, P. and {Ferraro}, S. and {Font-Ribera}, A. and {Forero-Romero}, J.~E. and {Gazta{\~n}aga}, E. and {Gontcho A Gontcho}, S. and {Gutierrez}, G. and {Guy}, J. and {Herrera-Alcantar}, H.~K. and {Ishak}, M. and {Juneau}, S. and {Kehoe}, R. and {Kremin}, A. and {Landriau}, M. and {Le Guillou}, L. and {Levi}, M.~E. and {Manera}, M. and {Meisner}, A. and {Miquel}, R. and {Moustakas}, J. and {Mu{\~n}oz-Guti{\'e}rrez}, A. and {Napolitano}, L. and {P{\'e}rez-R{\`a}fols}, I. and {Rossi}, G. and {Sanchez}, E. and {Schlegel}, D. and {Schubnell}, M. and {Sprayberry}, D. and {Tarl{\'e}}, G. and {Temple}, M.~J. and {Weaver}, B.~A. and {Zhou}, R.},
title = "{The Cosmic Evolution of C IV Absorbers at 1.4 < z < 4.5: Insights from 100,000 Systems in DESI Quasars}",
journal = {\apj},
keywords = {Quasar absorption line spectroscopy, Intergalactic medium, Redshift surveys, Astronomy software, 1317, 813, 1378, 1855, Cosmology and Nongalactic Astrophysics},
year = 2025,
month = sep,
volume = {990},
number = {2},
eid = {151},
pages = {151},
doi = {10.3847/1538-4357/adef3c},
archivePrefix = {arXiv},
eprint = {2504.20299},
primaryClass = {astro-ph.CO},
adsurl = {https://ui.adsabs.harvard.edu/abs/2025ApJ...990..151A},
adsnote = {Provided by the SAO/NASA Astrophysics Data System}
}
@software{Anandqsoabsfind2025,
author = {\{Anand}, Abhijeet},
title = "{qsoabsfind: A Python Package for Detecting
Absorption Line Doublets in SDSS and DESI Quasar
Spectra}",
month = jun,
year = 2025,
publisher = {Zenodo},
doi = {10.5281/zenodo.15685771},
url = {https://doi.org/10.5281/zenodo.15685771},
}Contributions are welcome! Please submit a pull request or open an issue to discuss your ideas or if you find any bugs. If you have any questions or suggestions, write to abhijeetanand2011@gmail.com or open a GitHub issue.
The first crude version of the codebase was developed and written by me during my PhD with lots of suggestions from my PhD supervisors Prof. Dr. Guinevere Kauffmann and Dr. Dylan Nelson. Over the years, it has grown from a simple script into a general-purpose tool. I thank the VS Code AI agents for their help in improving the codebase — they helped with documenting functions, optimizing logic, and expanding unit test coverage. The project logo was created from a absorber example generated by me, with assistance from ChatGPT-5.
Like any software, this code may contain bugs or unintended behavior. It is provided "as is" without warranty of any kind. Users are encouraged to test the code on a small sample before applying it to large datasets. If you find any issues, please report them via GitHub.
Copyright (c) 2021-2026 Abhijeet Anand.
qsoabsfind is a free software made available under the MIT License. For details, see the LICENSE file.
Thanks,
Abhijeet Anand
IUCAA, Pune &
Lawrence Berkeley National Lab
