GSoC 2026 Weeks 7-8: What Counts as One Spectrum?
Looking beyond X-rays

After working with OGIP products and X-ray response matrices, I spent weeks 7 and 8 exploring infrared spectral data from JWST.
An already extracted JWST spectrum usually provides wavelength, flux, uncertainty, data-quality information, and other calibrated columns directly. It does not use the same PHA, RMF, and ARF workflow that shaped XraySpectra.jl. More importantly, a single JWST spectral product does not always contain only one spectrum.
The many shapes of an extracted spectrum
The first NIRSpec fixed-slit x1d file I inspected looked reassuringly familiar. Its EXTRACT1D table had one scalar wavelength and one scalar flux value per row. The complete table represented one extracted spectrum and mapped naturally to a SpectrumBase.SingleSpectrum.
NIRISS wide-field slitless spectroscopy was very different. WFSS observes many sources in the same field without using a slit for each one. In the files I inspected, one FITS table row contained an entire vector of wavelengths and fluxes for one source. One extension could therefore produce many spectra, and the file could contain several EXTRACT1D extensions for different exposures or spectral orders.
NIRISS SOSS introduced another layout. Its spectra represented different spectral orders, with one extracted spectrum in each extension. NIRCam WFSS also produced a collection of extracted spectra. NIRSpec IFU and MIRI MRS began from spectral cubes, but their final x1d products could still contain one extracted 1D spectrum.
The same product suffix was not enough to tell me whether a file represented one spectrum, several orders, or hundreds of sources. The observing mode and the structure of the FITS table mattered.
Building InfraredSpectra.jl
To experiment with these products, I created a separate package called InfraredSpectra.jl. Its initial scope is deliberately limited to extracted JWST x1d and c1d products. Multidimensional products such as cal, s2d, s3d, and i2d, as well as time-series x1dints, remain outside the first version.
The public interface currently looks like this:
read_spectrum(path)
read_spectra(path)
inspect_product(path)
read_spectrum requires the file to contain exactly one usable spectrum. If it finds several, it reports how many were found and points the user toward read_spectra. read_spectra always returns a vector, so the same function works for fixed-slit, multi-source, and multi-order products. inspect_product reports the telescope, instrument, observing mode, product type, and HDU structure before the science arrays are fully parsed.
Internally, small X1D and C1D marker types use multiple dispatch to select the correct parser. They are not part of the public interface. Users should only need to ask for one spectrum, all spectra, or a product description.
The returned objects reuse SpectrumBase.SingleSpectrum. Wavelength and flux units from the FITS table are attached without converting the stored values. Uncertainty arrays, DQ values, source IDs, spectral orders, slit information, and extension identity are retained in metadata.
x1d versus c1d
Looking at corresponding x1d and c1d files helped me understand what “combined” means in the JWST pipeline.
An x1d product can preserve extracted spectra from separate exposures. A c1d product combines corresponding spectra, but it does not merge unrelated sources or spectral orders. A SOSS observation therefore still contains separate spectra for its different orders after combination.
In one NIRISS WFSS example, the x1d file produced 1,200 usable spectra spread across 12 EXTRACT1D extensions. The related c1d product contained 113 combined source spectra. Seeing those actual outputs made the distinction much clearer than the filenames alone.
For now, read_spectra flattens spectra from all matching extensions into one vector. Each spectrum keeps its source, order, slit, and extension metadata, so the original identity is not discarded. Whether a future API should also offer grouped lookup by source or extension is still something I want to discuss with my mentors.
Testing several observing modes

By the end of this exploration, I had tried the loader on extracted products from all four JWST science instruments used in the sample: NIRSpec, NIRISS, NIRCam, and MIRI.
The real-data checks include NIRSpec fixed-slit, IFU, and MSA products; NIRISS WFSS and SOSS; NIRCam WFSS; and MIRI LRS and MRS. These files cover the important table layouts I had encountered: scalar samples per row, complete spectrum vectors per row, one spectrum per extension, many spectra per extension, and several spectral orders.
The ordinary package tests still use small generated FITS tables so they remain portable. The larger real files live outside the repository and are enabled through an environment variable. This gives me both precise unit tests and realistic integration checks without putting large mission datasets directly into the package.