From 76e776c52ad1bbd25ba0688553b5d5aaf196ec53 Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 22 May 2026 15:15:21 +0200 Subject: [PATCH 01/22] docs: get started on using astromodels in gammapy docs --- docs/md_docs/am_in_gp.md | 149 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 docs/md_docs/am_in_gp.md diff --git a/docs/md_docs/am_in_gp.md b/docs/md_docs/am_in_gp.md new file mode 100644 index 0000000..ada5f6f --- /dev/null +++ b/docs/md_docs/am_in_gp.md @@ -0,0 +1,149 @@ +--- +jupyter: + jupytext: + text_representation: + extension: .md + format_name: markdown + format_version: '1.3' + jupytext_version: 1.19.3 + kernelspec: + display_name: Python (threeml) + language: python + name: threeml +--- + +# Using astromodels in gammapy + +In case you do not want to use `threeML` for fitting but want to use `astromodels` for +modelling you can use the [converter](./converter.ipynb) to do so. + +```python +from gammapy_plugin.converter import AstromodelConverter +from gammapy_plugin.models import SpectralModelConverted +from astromodels.functions import Powerlaw +from astromodels.core.model import Model +from astromodels.sources import PointSource +import astropy.units as u +from astromodels.core.units import get_units + +get_units().energy = u.TeV +pl = Powerlaw() +ps = PointSource("crab", ra=83.63, dec=22.01, spectral_shape=pl) +pl.piv = 1 * u.TeV +pl.K = 1e-12 * u.Unit("TeV-1 cm-2 s-1") +pl.index = -2 +model = Model(ps) +conv = AstromodelConverter(model) +``` + + +pl = Powerlaw() +ps = PointSource("crab",ra=83.63, dec=22.01,spectral_shape = pl) + +model = Model(ps) +conv = AstromodelConverter(model) + + +Okay now go to all the gammapy setup +```python +from pathlib import Path +import astropy.units as u +from astropy.coordinates import Angle, SkyCoord +from regions import CircleSkyRegion + +# %matplotlib inline +import matplotlib.pyplot as plt +from IPython.display import display +from gammapy.data import DataStore +from gammapy.datasets import ( + Datasets, + FluxPointsDataset, + SpectrumDataset, +) +from gammapy.estimators import FluxPointsEstimator +from gammapy.estimators.utils import resample_energy_edges +from gammapy.makers import ( + ReflectedRegionsBackgroundMaker, + SafeMaskMaker, + SpectrumDatasetMaker, +) +from gammapy.maps import MapAxis, RegionGeom, WcsGeom +from gammapy.modeling import Fit +from gammapy.modeling.models import ( + ExpCutoffPowerLawSpectralModel, + SkyModel, + create_crab_spectral_model, +) +from gammapy.visualization import plot_spectrum_datasets_off_regions + +datastore = DataStore.from_dir("$GAMMAPY_DATA/hess-dl3-dr1/") +obs_ids = [23523, 23526, 23559, 23592] +observations = datastore.get_observations(obs_ids) +target_position = SkyCoord(ra=83.63, dec=22.01, unit="deg", frame="icrs") +on_region_radius = Angle("0.11 deg") +on_region = CircleSkyRegion(center=target_position, radius=on_region_radius) +exclusion_region = CircleSkyRegion( + center=SkyCoord(183.604, -8.708, unit="deg", frame="galactic"), + radius=0.5 * u.deg, +) + +skydir = target_position.galactic +geom = WcsGeom.create( + npix=(150, 150), binsz=0.05, skydir=skydir, proj="TAN", frame="icrs" +) + +exclusion_mask = ~geom.region_mask([exclusion_region]) +exclusion_mask.plot() +plt.show() +energy_axis = MapAxis.from_energy_bounds( + 0.1, 40, nbin=10, per_decade=True, unit="TeV", name="energy" +) +energy_axis_true = MapAxis.from_energy_bounds( + 0.05, 100, nbin=20, per_decade=True, unit="TeV", name="energy_true" +) + +geom = RegionGeom.create(region=on_region, axes=[energy_axis]) +dataset_empty = SpectrumDataset.create(geom=geom, energy_axis_true=energy_axis_true) + +dataset_maker = SpectrumDatasetMaker( + containment_correction=True, selection=["counts", "exposure", "edisp"] +) +bkg_maker = ReflectedRegionsBackgroundMaker(exclusion_mask=exclusion_mask) +safe_mask_maker = SafeMaskMaker(methods=["aeff-max"], aeff_percent=10) + +datasets = Datasets() + +for obs_id, observation in zip(obs_ids, observations): + dataset = dataset_maker.run(dataset_empty.copy(name=str(obs_id)), observation) + dataset_on_off = bkg_maker.run(dataset, observation) + dataset_on_off = safe_mask_maker.run(dataset_on_off, observation) + datasets.append(dataset_on_off) + +print(datasets) +plt.figure() +ax = exclusion_mask.plot() +on_region.to_pixel(ax.wcs).plot(ax=ax, edgecolor="k") +plot_spectrum_datasets_off_regions(ax=ax, datasets=datasets) +plt.show() + + +datasets.models = [conv.gammapy_models[0]] + + +fit_joint = Fit() +result_joint = fit_joint.run(datasets=datasets) +``` +```python +print(result_joint) +``` + +```python +display(result_joint.models.to_parameters_table()) +``` + +```python +ax_spectrum, ax_residuals = datasets[0].plot_fit() +ax_spectrum.set_ylim(0.1, 40) +plt.show() +``` + From 658e718189dfe11d2abab34f397006fc60655534 Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Tue, 26 May 2026 15:32:51 +0200 Subject: [PATCH 02/22] docs: warning on experimental unit setting --- docs/md_docs/am_in_gp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/md_docs/am_in_gp.md b/docs/md_docs/am_in_gp.md index ada5f6f..b5ab4be 100644 --- a/docs/md_docs/am_in_gp.md +++ b/docs/md_docs/am_in_gp.md @@ -26,7 +26,7 @@ from astromodels.sources import PointSource import astropy.units as u from astromodels.core.units import get_units -get_units().energy = u.TeV +get_units().energy = u.TeV # this is HIGHLY EXPERIMENTAL!!! pl = Powerlaw() ps = PointSource("crab", ra=83.63, dec=22.01, spectral_shape=pl) pl.piv = 1 * u.TeV From 54a810ecc0d39dead60b367a269673f14903ce30 Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Tue, 26 May 2026 15:33:15 +0200 Subject: [PATCH 03/22] test: add test framework for fitting with gammapy --- gammapy_plugin/test/test_gammapy_fit.py | 92 +++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 gammapy_plugin/test/test_gammapy_fit.py diff --git a/gammapy_plugin/test/test_gammapy_fit.py b/gammapy_plugin/test/test_gammapy_fit.py new file mode 100644 index 0000000..f2297e7 --- /dev/null +++ b/gammapy_plugin/test/test_gammapy_fit.py @@ -0,0 +1,92 @@ +import pytest +import numpy as np +from gammapy_plugin.converter import AstromodelConverter +from astromodels.core.model import Model +from astromodels.functions import Powerlaw +from astromodels.sources import PointSource +import astropy.units as u +from gammapy.modeling import Fit +from gammapy.modeling.models import PowerLawSpectralModel, SkyModel + + +def test_gammapy_fit(crab_test_data): + datasets = crab_test_data.copy() + datasets_gp = crab_test_data.copy() + np.random.seed(1234) + + pl = Powerlaw() + ps = PointSource("crab", spectral_shape=pl, ra=83.63, dec=22.01) + pl.piv = 1 * u.TeV + pl.K = 1e-12 * u.Unit("TeV-1 cm-2 s-1") + pl.index = -2 + pl.index.min_value = -np.inf + pl.index.max_value = np.inf + + model = Model(ps) + conv = AstromodelConverter(model) + datasets.models = [conv.gammapy_models[0]] # using ReflectedRegionsBackground + fit = Fit() + result = fit.run(datasets=datasets) + + spectral_model = PowerLawSpectralModel( + amplitude=1e-12 * u.Unit("cm-2 s-1 TeV-1"), + index=2, + reference=1 * u.TeV, + ) + model_gp = SkyModel(spectral_model=spectral_model, name="crab") + + datasets_gp.models = [model_gp] + + fit_joint = Fit() + result_joint = fit_joint.run(datasets=datasets_gp) + assert np.isclose( + result.models[0].parameters["crab.spectrum.main.Powerlaw.index"].value, + -result_joint.models[0].parameters["index"].value, + atol=result_joint.models[0].parameters["index"].error, + ) + + +def test_xspec_wrapping(crab_test_data): + + pytest.importorskip("xspec") + + from astromodels.xspec import XS_powerlaw + + datasets = crab_test_data.copy() + datasets = datasets.stack_reduce() + datasets_gp = crab_test_data.copy() + datasets_gp = datasets_gp.stack_reduce() + np.random.seed(1234) + pl = XS_powerlaw() + ps = PointSource("crab", spectral_shape=pl, ra=83.633, dec=22.014) + pl.phoindex = 2 + pl.phoindex.min_value = -np.nan + pl.phoindex.max_value = np.nan + + model = Model(ps) + conv = AstromodelConverter(model) + datasets.models = [conv.gammapy_models[0]] # using ReflectedRegionsBackground + fit = Fit() + result = fit.run(datasets=datasets) + + spectral_model = PowerLawSpectralModel( + amplitude=100 * u.Unit("cm-2 s-1 keV-1"), + index=2, + reference=1 * u.keV, + ) + model_gp = SkyModel(spectral_model=spectral_model, name="crab") + + datasets_gp.models = [model_gp] + + fit_joint = Fit() + result_joint = fit_joint.run(datasets=datasets_gp) + assert np.isclose( + result.models[0].parameters["crab.spectrum.main.XS_powerlaw.norm"].value, + result_joint.models[0].parameters["amplitude"].value, + atol=result_joint.models[0].parameters["amplitude"].error, + ) + assert np.isclose( + result.models[0].parameters["crab.spectrum.main.XS_powerlaw.phoindex"].value, + result_joint.models[0].parameters["index"].value, + atol=result_joint.models[0].parameters["index"].error, + ) From ec6bf74a120235fe24fd93019877e655b5f1bccb Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Tue, 26 May 2026 15:54:04 +0200 Subject: [PATCH 04/22] refactor: isort --- gammapy_plugin/test/test_gammapy_fit.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gammapy_plugin/test/test_gammapy_fit.py b/gammapy_plugin/test/test_gammapy_fit.py index f2297e7..dc11e33 100644 --- a/gammapy_plugin/test/test_gammapy_fit.py +++ b/gammapy_plugin/test/test_gammapy_fit.py @@ -1,13 +1,14 @@ -import pytest +import astropy.units as u import numpy as np -from gammapy_plugin.converter import AstromodelConverter +import pytest from astromodels.core.model import Model from astromodels.functions import Powerlaw from astromodels.sources import PointSource -import astropy.units as u from gammapy.modeling import Fit from gammapy.modeling.models import PowerLawSpectralModel, SkyModel +from gammapy_plugin.converter import AstromodelConverter + def test_gammapy_fit(crab_test_data): datasets = crab_test_data.copy() From deae5bc9c950c4f6f7a145056c5b83b09ac07b79 Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Thu, 28 May 2026 13:36:43 +0200 Subject: [PATCH 05/22] add: public update method --- gammapy_plugin/converter.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gammapy_plugin/converter.py b/gammapy_plugin/converter.py index 2a6129a..ad42337 100644 --- a/gammapy_plugin/converter.py +++ b/gammapy_plugin/converter.py @@ -221,6 +221,13 @@ def _create_skymodel(self) -> None: ) self._gather_mappings() + def update(self) -> None: + """ + This invokes the updating of all parameters of the converted model in the + gammapy SkyModels + """ + self._update_parameters() + @property def skymodel(self) -> SkyModel: """Returns the Gammapy skymodel for this source. From 06d03967426bf31ec4e4e5d0a4c392c032888775 Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Thu, 28 May 2026 13:42:34 +0200 Subject: [PATCH 06/22] docs: fix kernel name --- docs/md_docs/am_in_gp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/md_docs/am_in_gp.md b/docs/md_docs/am_in_gp.md index b5ab4be..7e02932 100644 --- a/docs/md_docs/am_in_gp.md +++ b/docs/md_docs/am_in_gp.md @@ -9,7 +9,7 @@ jupyter: kernelspec: display_name: Python (threeml) language: python - name: threeml + name: python3 --- # Using astromodels in gammapy From 1997bbbd42a6ca3b4d0651e053a4ad449f644c5e Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Thu, 28 May 2026 14:00:45 +0200 Subject: [PATCH 07/22] docs: add gammapy-datasets --- .readthedocs.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index b1e9ab8..a6651a4 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -16,6 +16,8 @@ build: jobs: pre_build: - sphinx-apidoc . -o docs/api + - export GAMMAPY_DATA=$HOME/gammapy_data && mkdir -p $GAMMAPY_DATA + - git clone https://github.com/gammapy/gammapy-data.git $GAMMAPY_DATA - jupytext --to ipynb --pipe black --execute docs/md_docs/*.md - mv docs/md_docs/*.ipynb docs/notebooks From 7630972411483cb6d7e3972973e4a83b474acb6f Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 29 May 2026 09:21:47 +0200 Subject: [PATCH 08/22] chore: clean up rtd config --- .readthedocs.yaml | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index b1e9ab8..c613caa 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,34 +1,21 @@ # Read the Docs configuration file for Sphinx projects # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details -# Required version: 2 -# Set the OS, Python version and other tools you might need build: os: ubuntu-24.04 tools: python: "3.12" - # You can also specify other tool versions: - # nodejs: "20" - # rust: "1.70" - # golang: "1.20" jobs: pre_build: - sphinx-apidoc . -o docs/api - - jupytext --to ipynb --pipe black --execute docs/md_docs/*.md - - mv docs/md_docs/*.ipynb docs/notebooks # Build documentation in the "docs/" directory with Sphinx sphinx: configuration: docs/conf.py fail_on_warning: false -# Optionally build your docs in additional formats such as PDF and ePub -# formats: -# - pdf -# - epub - python: install: - requirements: docs/requirements.txt From fe094b0a99fd49835837e68435a696b063805106 Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 29 May 2026 13:30:02 +0200 Subject: [PATCH 09/22] ci: add building jupytext job --- .github/workflows/docs.yml | 152 ++++++------------------------------- 1 file changed, 24 insertions(+), 128 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 6e6e765..86caf53 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,8 +1,23 @@ name: Docs -on: [release] +on: + push: + branches: + - main + - dev + tags: + - "v*" + pull_request: + branches: + - main + - dev + release: + +permissions: + contents: write # 'write' access to repository contents + pull-requests: write # 'write' access to pull requests jobs: - notebooks: + build-notebooks: name: "Build the notebooks for the docs" runs-on: ubuntu-latest steps: @@ -10,143 +25,24 @@ jobs: - name: Set up Python uses: actions/setup-python@v6 with: - python-version: 3.11 - - uses: conda-incubator/setup-miniconda@v4 - with: - auto-activate-base: true - activate-environment: "" - auto-update-conda: true - python-version: ${{ matrix.python-version }} - channels: conda-forge, threeml, defaults - + python-version: 3.13 - name: Install dependencies run: | - python -m pip install --upgrade pip wheel - pip install numpy==2.1 - pip install matplotlib==3.8.4 - pip install black - pip install ipython jupyter cython astropy - conda install jupytext jupyterthemes emcee pymultinest ultranest nbconvert ipykernel astropy regions threeML astromodels gammapy - pip install . + pip install -e . + pip install -r docs/requirements.txt - name: Execute the notebooks shell: bash -l {0} run: | - pip install . - export GAMMAPY_DATA=$HOME/data + export GAMMAPY_DATA="/home/runner/work/gammapy_data" mkdir -p $GAMMAPY_DATA git clone https://github.com/gammapy/gammapy-data.git $GAMMAPY_DATA - jupytext --to ipynb --pipe black --execute docs/md/*.md + jupytext --to ipynb --pipe black --execute docs/md_docs/*.md mkdir -p docs/notebooks - mv docs/md/*.ipynb docs/notebooks + mv docs/md_docs/*.ipynb docs/notebooks + echo "Next - uploading artifacts for sha ${{ github.sha }}" - uses: actions/upload-artifact@v6 with: name: notebooks-for-${{ github.sha }} path: docs/notebooks - - api_doc: - name: "Create the API stubs" - runs-on: macos-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token - fetch-depth: 0 # otherwise, you will failed to push refs to dest repo - - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: 3.11 - - - name: Build the API doc - run: | - - brew install c-blosc - brew install hdf5 - - pip3 install --upgrade pip - pip3 install cython - pip3 install numpy==2.1 - pip3 install --upgrade scipy numba astropy - pip3 install matplotlib==3.8.4 - pip3 install . - - brew install sphinx-doc pandoc - - pip3 install wheel - pip3 install mock recommonmark - pip3 install sphinx_rtd_theme - pip3 install -U sphinx nbsphinx sphinx-gallery - - - - sphinx-apidoc -f -o docs/api/ gammapy_plugin - - - uses: actions/upload-artifact@v6 - with: - name: api-stubs-for-${{ github.sha }} - path: docs/api - - build_docs: - name: "Build the Documentation" - runs-on: macos-latest - needs: [notebooks, api_doc] - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false # otherwise, the token used is the GITHUB_TOKEN, instead of your personal token - fetch-depth: 0 # otherwise, you will failed to push refs to dest repo - - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: 3.11 - - - name: Install package - run: | - - brew install c-blosc - brew install hdf5 - pip3 install numpy scipy numba astropy matplotlib==3.8.4 - brew install sphinx-doc pandoc - - pip3 install wheel - pip3 install mock recommonmark - pip3 install sphinx_rtd_theme - pip3 install -U sphinx nbsphinx sphinx-gallery - pip3 install threeML - pip3 install --upgrade git+https://github.com/threeml/astromodels.git - pip3 install --upgrade git+https://github.com/threeml/threeML.git - pip3 install --upgrade gammapy --use-pep517 - - - pip3 install -e . - - rm -rf docs/md/* - env: - ISDEV: ${{contains(github.rev,'dev') || contains(github.base_ref, 'dev')}} - - - uses: actions/download-artifact@master - with: - name: notebooks-for-${{ github.sha }} - path: docs/notebooks - - - uses: actions/download-artifact@master - with: - name: api-stubs-for-${{ github.sha }} - path: docs/notebooks/api - - - name: Build and Commit - uses: sphinx-notes/pages@master - with: - documentation_path: docs - sphinx_version: 5.1.1 - requirements_path: docs/requirements.txt - - - name: Push changes - if: github.event_name == 'push' - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: gh-pages From c4caa30c45b8768553deff2704c1d7530c0b5970 Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Thu, 28 May 2026 13:36:43 +0200 Subject: [PATCH 10/22] add: public update method --- gammapy_plugin/converter.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gammapy_plugin/converter.py b/gammapy_plugin/converter.py index 2a6129a..ad42337 100644 --- a/gammapy_plugin/converter.py +++ b/gammapy_plugin/converter.py @@ -221,6 +221,13 @@ def _create_skymodel(self) -> None: ) self._gather_mappings() + def update(self) -> None: + """ + This invokes the updating of all parameters of the converted model in the + gammapy SkyModels + """ + self._update_parameters() + @property def skymodel(self) -> SkyModel: """Returns the Gammapy skymodel for this source. From 002e3a3445baf07765028ed7ccd057bd553dc9ed Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 29 May 2026 13:44:34 +0200 Subject: [PATCH 11/22] add: public update method for converter --- gammapy_plugin/converter.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gammapy_plugin/converter.py b/gammapy_plugin/converter.py index ad42337..678c584 100644 --- a/gammapy_plugin/converter.py +++ b/gammapy_plugin/converter.py @@ -84,6 +84,11 @@ def _update_parameters(self) -> None: for name, source in self._converted_sources.items(): source._update_parameters() + def update(self) -> None: + """Update all parameters of all SkyModels witht the current values from the + astromodels model. Public method for _update_parameters""" + self._update_parameters() + @property def gammapy_models(self) -> list[SkyModel]: """ From b611c730a68b52cb10614a62aa0c6d6c00579e7d Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 29 May 2026 14:13:37 +0200 Subject: [PATCH 12/22] ci: fix the sha also for PRs --- .github/workflows/docs.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 86caf53..04a40cc 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -22,6 +22,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + - name: Set SHA + run: | + SHA="${{ github.event.pull_request.head.sha || github.sha }}" + echo "SHA=$SHA" >> "$GITHUB_ENV" - name: Set up Python uses: actions/setup-python@v6 with: @@ -40,9 +44,9 @@ jobs: jupytext --to ipynb --pipe black --execute docs/md_docs/*.md mkdir -p docs/notebooks mv docs/md_docs/*.ipynb docs/notebooks - echo "Next - uploading artifacts for sha ${{ github.sha }}" + echo "Next - uploading artifacts for sha ${SHA}" - uses: actions/upload-artifact@v6 with: - name: notebooks-for-${{ github.sha }} + name: notebooks-for-${SHA} path: docs/notebooks From 5ff1c32f1ef0b4384d7d2b8a2a995c181742be0f Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 29 May 2026 14:22:50 +0200 Subject: [PATCH 13/22] ci: why cant it be just bash ... --- .github/workflows/docs.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 04a40cc..e9f3647 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -45,8 +45,7 @@ jobs: mkdir -p docs/notebooks mv docs/md_docs/*.ipynb docs/notebooks echo "Next - uploading artifacts for sha ${SHA}" - - uses: actions/upload-artifact@v6 with: - name: notebooks-for-${SHA} + name: notebooks-for-${{ env.SHA }} path: docs/notebooks From e05d3d1597ca7f6d1635d5fe6296cc94cda9f5b7 Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 29 May 2026 14:48:03 +0200 Subject: [PATCH 14/22] docs: try downloading notebooks --- .github/workflows/docs.yml | 9 ++++++++ .readthedocs.yaml | 2 ++ docs/download_notebooks.sh | 46 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+) create mode 100644 docs/download_notebooks.sh diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index e9f3647..265680e 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -49,3 +49,12 @@ jobs: with: name: notebooks-for-${{ env.SHA }} path: docs/notebooks + - name: Trigger RTD + shell: bash -l {0} + run: | + curl \ + --data "branches=${{ ${{ github.head_ref || github.ref_name }} }}&token=${{ env.TOKEN }}&default_branch=main" \ + https://app.readthedocs.org/api/v2/webhook/gammapy-plugin/327402/ + + with: + TOKEN: ${{ secrets.RTD_API }} diff --git a/.readthedocs.yaml b/.readthedocs.yaml index c613caa..8e4ca36 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -10,6 +10,8 @@ build: jobs: pre_build: - sphinx-apidoc . -o docs/api + - bash docs/download_notebooks.sh + # Build documentation in the "docs/" directory with Sphinx sphinx: diff --git a/docs/download_notebooks.sh b/docs/download_notebooks.sh new file mode 100644 index 0000000..ce50c64 --- /dev/null +++ b/docs/download_notebooks.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +set -euo pipefail + +OWNER="threeML" +REPO="gammapy-plugin" +SHA="${READTHEDOCS_GIT_COMMIT_HASH}" +TOKEN="${GITHUB_TOKEN}" + +API="https://api.github.com/repos/$OWNER/$REPO" + +# Find artifact ID whose name contains the SHA +# + +ARTIFACT_ID=$( + curl -fsSL \ + -H "Authorization: Bearer $TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "$API/actions/artifacts?per_page=100" \ + | jq -r --arg SHA "$SHA" ' + .artifacts[] + | select(.expired == false) + | select(.name | contains($SHA)) + | .id + ' \ + | head -n1 +) + +if [[ -z "$ARTIFACT_ID" ]]; then + echo "No artifact found for SHA: $SHA" + exit 1 +fi + +echo "Artifact ID: $ARTIFACT_ID" + +# Download artifact ZIP +curl -fL \ + -H "Authorization: Bearer $TOKEN" \ + -H "Accept: application/vnd.github+json" \ + "$API/actions/artifacts/$ARTIFACT_ID/zip" \ + -o artifact.zip + +echo "Downloaded artifact.zip" +mkdir -p docs/notebooks +unzip artifact.zip -d docs/notebooks +rm artifac.zip +echo "Done unzipping" From 46c7e658f56c7f1fab882b8ae99dec0a262eed7e Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 29 May 2026 14:49:53 +0200 Subject: [PATCH 15/22] ci: syntax fix getting branch name --- .github/workflows/docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 265680e..cc087be 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -53,8 +53,8 @@ jobs: shell: bash -l {0} run: | curl \ - --data "branches=${{ ${{ github.head_ref || github.ref_name }} }}&token=${{ env.TOKEN }}&default_branch=main" \ + --data "branches=${{ github.head_ref || github.ref_name }}&token=${{ env.TOKEN }}&default_branch=main" \ https://app.readthedocs.org/api/v2/webhook/gammapy-plugin/327402/ - with: + env: TOKEN: ${{ secrets.RTD_API }} From 1aec26bd30000e72b3ccce78f8433ab4062a3998 Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 29 May 2026 15:01:17 +0200 Subject: [PATCH 16/22] ci: try again --- .github/workflows/docs.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index cc087be..a336102 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -52,9 +52,12 @@ jobs: - name: Trigger RTD shell: bash -l {0} run: | - curl \ - --data "branches=${{ github.head_ref || github.ref_name }}&token=${{ env.TOKEN }}&default_branch=main" \ - https://app.readthedocs.org/api/v2/webhook/gammapy-plugin/327402/ + curl -X POST \ + "https://app.readthedocs.org/api/v2/webhook/gammapy-plugin/327402/" \ + --data-urlencode "branches=${BRANCH}" \ + --data-urlencode "token=${TOKEN}" \ + --data-urlencode "default_branch=main" env: - TOKEN: ${{ secrets.RTD_API }} + TOKEN: ${{ secrets.RTD_API }} + BRANCH: ${{ github.event.pull_request.head.ref || github.ref_name }} From 2267c8d93f995567ff927af9f1b8c296afc7cf5a Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 29 May 2026 15:06:06 +0200 Subject: [PATCH 17/22] ci: use v3 api instead --- .github/workflows/docs.yml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index a336102..3d6acb8 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -49,14 +49,17 @@ jobs: with: name: notebooks-for-${{ env.SHA }} path: docs/notebooks - - name: Trigger RTD + + - name: Trigger RTD shell: bash -l {0} run: | curl -X POST \ - "https://app.readthedocs.org/api/v2/webhook/gammapy-plugin/327402/" \ - --data-urlencode "branches=${BRANCH}" \ - --data-urlencode "token=${TOKEN}" \ - --data-urlencode "default_branch=main" + "https://app.readthedocs.org/api/v3/projects/gammapy-plugin/versions/latest/builds/" \ + -H "Authorization: Token $TOKEN" \ + -H "Content-Type: application/json" \ + -d "{ + \"branch\": \"${BRANCH}\" + }" env: TOKEN: ${{ secrets.RTD_API }} From d9f035e85c0e0abc2657ea74ef2bea2c091d3f67 Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 29 May 2026 15:16:30 +0200 Subject: [PATCH 18/22] docs: use ultranest for notebook building --- .github/workflows/docs.yml | 1 + docs/md_docs/crab_spectrum.md | 4 ++-- docs/requirements.txt | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 3d6acb8..0768d48 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -32,6 +32,7 @@ jobs: python-version: 3.13 - name: Install dependencies run: | + pip install black ultranest pip install -e . pip install -r docs/requirements.txt diff --git a/docs/md_docs/crab_spectrum.md b/docs/md_docs/crab_spectrum.md index 7aab875..1cdf4cb 100644 --- a/docs/md_docs/crab_spectrum.md +++ b/docs/md_docs/crab_spectrum.md @@ -148,8 +148,8 @@ gl.set_datasets(datasets) gl.set_model(model, converted_model=conv) ba = BayesianAnalysis(model, DataList(gl)) -ba.set_sampler("multinest") -ba.sampler.setup(resume = False) +ba.set_sampler("ultranest") +ba.sampler.setup() ba.sample() res = ba.results res diff --git a/docs/requirements.txt b/docs/requirements.txt index d21a0e8..b5907a8 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -8,4 +8,3 @@ sphinx-copybutton sphinxcontrib-email jupytext furo -black From aaeac6cfc792fae57af3d33d50ff30c08b4127ec Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 29 May 2026 15:16:41 +0200 Subject: [PATCH 19/22] ci: fix versioning triggering --- .github/workflows/docs.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0768d48..74a2407 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -55,7 +55,7 @@ jobs: shell: bash -l {0} run: | curl -X POST \ - "https://app.readthedocs.org/api/v3/projects/gammapy-plugin/versions/latest/builds/" \ + "https://app.readthedocs.org/api/v3/projects/gammapy-plugin/versions/${PR_NUMBER}/builds/" \ -H "Authorization: Token $TOKEN" \ -H "Content-Type: application/json" \ -d "{ @@ -65,3 +65,4 @@ jobs: env: TOKEN: ${{ secrets.RTD_API }} BRANCH: ${{ github.event.pull_request.head.ref || github.ref_name }} + PR_NUMBER: ${{ github.event.number || "latest" }} From 25aa9f807f676a880513a357ffb9e4cb3478464f Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 29 May 2026 15:23:14 +0200 Subject: [PATCH 20/22] ci: syntax fix --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 74a2407..32d1afc 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -65,4 +65,4 @@ jobs: env: TOKEN: ${{ secrets.RTD_API }} BRANCH: ${{ github.event.pull_request.head.ref || github.ref_name }} - PR_NUMBER: ${{ github.event.number || "latest" }} + PR_NUMBER: ${{ github.event.number || 'latest' }} From 38093c2d85827deabef20e37d80f2264aa14ff2d Mon Sep 17 00:00:00 2001 From: Tobias Preis Date: Fri, 29 May 2026 15:23:31 +0200 Subject: [PATCH 21/22] docs: rtd download switch to python instead of jq for parsing --- docs/download_notebooks.sh | 49 +++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/docs/download_notebooks.sh b/docs/download_notebooks.sh index ce50c64..e024a84 100644 --- a/docs/download_notebooks.sh +++ b/docs/download_notebooks.sh @@ -8,21 +8,34 @@ TOKEN="${GITHUB_TOKEN}" API="https://api.github.com/repos/$OWNER/$REPO" -# Find artifact ID whose name contains the SHA -# +echo "Searching artifacts for SHA: $SHA" ARTIFACT_ID=$( - curl -fsSL \ - -H "Authorization: Bearer $TOKEN" \ - -H "Accept: application/vnd.github+json" \ - "$API/actions/artifacts?per_page=100" \ - | jq -r --arg SHA "$SHA" ' - .artifacts[] - | select(.expired == false) - | select(.name | contains($SHA)) - | .id - ' \ - | head -n1 +python3 - < Date: Fri, 29 May 2026 15:43:49 +0200 Subject: [PATCH 22/22] docs: add astromodels in gammapy notebook to toctree --- docs/index.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/index.rst b/docs/index.rst index 737b3eb..d38b00f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -44,6 +44,7 @@ To get started check out the `get-started`_ section. intro notebooks/converter.ipynb + notebooks/am_in_gp.ipynb api/API.rst @@ -51,4 +52,5 @@ To get started check out the `get-started`_ section. notebooks/crab_spectrum.ipynb notebooks/converter.ipynb + notebooks/am_in_gp.ipynb