Skip to content

Improved integration for common Astromodels Functions, and custom function cleanup#466

Merged
israelmcmc merged 9 commits intocositools:developfrom
McKelvey-Engineering-CSE:new_integrate_clean
Feb 4, 2026
Merged

Improved integration for common Astromodels Functions, and custom function cleanup#466
israelmcmc merged 9 commits intocositools:developfrom
McKelvey-Engineering-CSE:new_integrate_clean

Conversation

@jdbuhler
Copy link
Contributor

@jdbuhler jdbuhler commented Feb 4, 2026

This PR was motivated by an investigation into the cost of spectral fitting for short-duration GRBs. Fitting requires repeatedly integrating the spectrum for every Ei bin whenever its parameters change. Currently, this integration is done with adaptive quadrature (scipy's integrate.quad), and it cannot be vectorized over bins.

We introduce a new function, get_integral_values(), that takes an Astromodels function and a vector of x's and computes the integral between each successive pair of x's. For commonly used functions, we implement the integrals using analytic expressions or special functions, thereby avoiding the need for adaptive quadrature. This is much faster to evaluate for most of the functions mentioned in response/functions.py. Notably, we provide integral functions for a Gaussian and for a Band spectrum; the latter is 20-25x faster than quadrature for typical values of alpha. The computed integrals are also somewhat more accurate for step functions (which are poorly sampled by integrate.quad) and Band (for which quadrature loses accuracy around the cutoff energy).

This work also prompted a review and cleanup of the custom functions in the threeml subdirectory and of response-related code that makes use of spectral integration. COSILike has been left alone for now because it is due to be substantially refactored with the introduction of the interfaces redesign, but it does use the new integral code via the PointSourceResponse class.

While this work benefits users of common Astromodels spectral functions, it doesn't accelerate all such functions. We don't accelerate integrals over functions evaluated by 1D linear interpolation (e.g., SpecFromDat), though that could be done in the future using trapezoidal rebinning to replace quadrature. And we don't try to decompose Composite functions representing linear combinations of simple functions -- that should be done once, rather than on every call to integration, and so would require some additional infrastructure.

There are a few uses of integrate.quad in cosipy that don't involve Astromodels spectra, notably in LineBackground (involving sums of powerlaws and Gaussians) and 3D functions (involving integrals of a 1D linearly interpolated function). These could, with a bit of work, be converted to use the new infrastructure, but there is no point in doing so until we address the two extensions suggested above.

Jeremy Buhler added 8 commits February 3, 2026 11:47
…including

  Band functions
* minor cleanups to custom functions and flux integration
  including Band spectra
* assorted small cleanups related to flux integrals
all the divides in question have floating-point denominators and so will
return the same result as regular /
  attribute tests in eval.
* don't reload file and rebuild interpolator on every call to
  evaluate in SpecFromDat; do so only if the filename changes
* retire Wide_Asymmetric_Gaussian function, because we can
  get exactly the same behavior from Astromodels' Asymmetric_Gaussian
  (which has identical code) by changing the upper limit on one of
  its parameters
* change notebooks that used Wide_Asymmetric_Gaussian to reflect
  the previous change
  it is read from a file or created directly via __init__()
* simplify sanity check in ExtendedResponse's get_expectation()
  (now also enforces unit agreement between first two axes of response
  and input)
* remove some unneeded imports
@codecov
Copy link

codecov bot commented Feb 4, 2026

Codecov Report

❌ Patch coverage is 97.93814% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.51%. Comparing base (5fe8fd8) to head (a28ffc7).
⚠️ Report is 10 commits behind head on develop.

Files with missing lines Patch % Lines
cosipy/threeml/custom_functions.py 90.69% 4 Missing ⚠️
Files with missing lines Coverage Δ
cosipy/response/ExtendedSourceResponse.py 91.42% <100.00%> (+1.42%) ⬆️
cosipy/response/PointSourceResponse.py 100.00% <100.00%> (ø)
cosipy/response/functions.py 91.48% <100.00%> (ø)
cosipy/response/functions_3d.py 96.29% <100.00%> (-0.38%) ⬇️
cosipy/response/integrals.py 100.00% <100.00%> (ø)
cosipy/threeml/custom_functions.py 81.20% <90.69%> (+18.50%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@israelmcmc
Copy link
Collaborator

Thanks @jdbuhler . This look good to me. Just one thing: can you please commit the tutorial with notebook executed --i.e. with the output cells? While outputs are not ideal for version control, they are used directly for the website with the documentation.

As a side note, the integration functionality is a candidate to be added directly into astromodels. This is something to think a out for later. Maybe we can discuss it in the 3ML meeting at the end of the month.

@jdbuhler
Copy link
Contributor Author

jdbuhler commented Feb 4, 2026

Will do.

And yeah, I would much prefer to have the integral as a method of the Function class, with a fallback to adaptive quadrature, inside astromodels. At least one of their Band implementations has an integration function that is currently broken (only works for integer alpha), so maybe they can use my code.

…l_fit notebook

* produce output for notebooks that were changed for Asymm_Gaussian fix
@israelmcmc
Copy link
Collaborator

Thanks @jdbuhler. As an additional test I check the output of the Crab spectral fit, and it looks as expected. I'm merging.

@israelmcmc israelmcmc merged commit 99bed81 into cositools:develop Feb 4, 2026
4 checks passed
@jdbuhler jdbuhler deleted the new_integrate_clean branch February 5, 2026 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants