GSoC 2026 Weeks 3-4: Building the First Pieces of XraySpectra.jl
Moving from loading files to using them

During weeks 3 and 4, the project started to feel less like βcan I read this FITS file?β and more like βcan someone actually use this package on real data?β
After getting the basic OGIP pieces loaded, I worked more on how the pieces fit together: PHA files, RMFs, ARFs, backgrounds, and the higher-level dataset loader. A lot of the work was still small and careful, but the direction became clearer. The package should not just expose a pile of parsed FITS columns. It should give users the parts of an observation in a way that makes sense.
One useful change was moving toward read_dataset as the higher-level loader name. A PHA file is already the spectrum-like data, so calling the full observation loader read_spectrum felt a little confusing. read_dataset better describes what is happening: read the spectrum, and optionally read the response, ancillary response, and background too.
Response folding
A big part of these weeks was response folding. This is where the model or flux is passed through the instrument response to predict what the detector would see.
At first, the math looked simple:
response matrix * flux
But as usual, the details matter. The ARF has effective area values, and the RMF redistributes photons from true energy bins into detector channels. Combining the ARF and RMF means scaling the response matrix by the effective area before folding.
I also learned more about performance here. Some response matrices can be sparse, so preserving sparsity matters. Otherwise, a matrix operation that looks harmless could accidentally allocate a much larger dense matrix. This led to improving combine! so it could work better with sparse matrices instead of creating unnecessary temporary arrays.
Rebinning and real data
Another major topic was rebinning. The important idea is that rebinning should be explicit. The package should not silently change a userβs data just because two grids do not match.
For channel rebinning, the basic idea is simple: combine neighboring detector channels and preserve the right quantities. Counts should be summed. Bad quality flags should propagate if any channel in the group is bad. Errors need more care, especially depending on whether they are Poisson or explicitly provided numeric errors.
I spent time comparing this with how SpectralFitting.jl already approaches grouping and rebinning. That helped keep the new package from drifting too far away from the ecosystem it is supposed to support.
Testing with real files
A lot of these weeks were also about test data. Instead of committing large binary files directly, I worked on using Julia artifacts and GitHub release assets so tests can download data only when needed. That seems like the right direction for real mission files, because FITS files can get large very quickly.
I also started looking outside X-rays a bit. I inspected JWST and MAST products to understand what βspectrum loadingβ might mean for infrared data. That was useful because JWST products are not all the same shape. Some are already extracted 1D spectra, while others are 2D spectral images, imaging products, or source catalogs.
That made the boundary clearer again: extracted 1D products like x1d are closer to SpectrumBase. 2D images or slitless spectroscopy products may need more thought before forcing them into the same interface.
What I learned
The main thing I learned in weeks 3 and 4 is that a loader is also an interface design problem.
It is not enough to parse the file correctly. The package also needs to make the scientific meaning hard to misuse. Is this detector channel data or physical energy data? Has the ARF already been folded in? Is this one spectrum or many spectra? Are we looking at a 1D extracted product or a 2D image?
These questions kept showing up in different forms. The work is still incremental, but I feel like I understand the shape of the problem much better now. The next steps are to keep tightening the loader API, improve rebinning behavior, and keep testing against real mission data instead of only artificial examples.