From abcbc93dade6138c10fd9e47c68b457fb93c4bf1 Mon Sep 17 00:00:00 2001 From: Josh Veitch-Michaelis Date: Mon, 23 Mar 2026 13:55:51 +0000 Subject: [PATCH] update scripts + add CI workflow --- .github/workflows/example-scripts.yml | 39 +++++++++++++++++++ README.md | 1 + examples/example_gemini_gmos_longslit.py | 6 ++- ...ample_gemini_gmos_longslit_manual_atlas.py | 6 ++- examples/example_gtc_osiris.py | 6 +-- examples/example_keck_deimos_830g.py | 11 ++++-- examples/example_lt_sprat_xe_manual_atlas.py | 9 +++-- examples/example_ntt_efosc_grism11.py | 5 ++- examples/example_wht_isis_r300r.py | 9 +++-- pyproject.toml | 4 ++ uv.lock | 4 +- 11 files changed, 80 insertions(+), 20 deletions(-) create mode 100644 .github/workflows/example-scripts.yml diff --git a/.github/workflows/example-scripts.yml b/.github/workflows/example-scripts.yml new file mode 100644 index 0000000..fd1a774 --- /dev/null +++ b/.github/workflows/example-scripts.yml @@ -0,0 +1,39 @@ +name: Example scripts + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + run-examples: + runs-on: ubuntu-latest + + env: + MPLBACKEND: Agg + + steps: + - uses: actions/checkout@v5 + + - name: Install uv + uses: astral-sh/setup-uv@v6 + with: + python-version: "3.11" + + - name: Setup venv + run: uv python install + + - name: Install dependencies + run: uv sync --all-extras --dev + + - name: Run example scripts + run: | + for f in examples/*.py; do + echo "Running $f" + uv run python "$f" || exit 1 + done + + - name: Run example notebooks + run: | + uv run --with nbconvert jupyter nbconvert --to notebook --execute --inplace examples/*.ipynb diff --git a/README.md b/README.md index 4bf3a62..c54e55e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Rascal: RANSAC Assisted Spectral CALibration [![Python package](https://github.com/jveitchmichaelis/rascal/actions/workflows/python-package.yml/badge.svg)](https://github.com/jveitchmichaelis/rascal/actions/workflows/python-package.yml) +[![Example scripts](https://github.com/jveitchmichaelis/rascal/actions/workflows/example-scripts.yml/badge.svg)](https://github.com/jveitchmichaelis/rascal/actions/workflows/example-scripts.yml) [![Coverage Status](https://coveralls.io/repos/github/jveitchmichaelis/rascal/badge.svg?branch=main)](https://coveralls.io/github/jveitchmichaelis/rascal?branch=main) [![Readthedocs Status](https://readthedocs.org/projects/rascal/badge/?version=latest\&style=flat)](https://rascal.readthedocs.io/en/latest/) [![PyPI version](https://badge.fury.io/py/rascal.svg)](https://badge.fury.io/py/rascal) diff --git a/examples/example_gemini_gmos_longslit.py b/examples/example_gemini_gmos_longslit.py index 4486f60..36ba21b 100644 --- a/examples/example_gemini_gmos_longslit.py +++ b/examples/example_gemini_gmos_longslit.py @@ -12,7 +12,11 @@ sys.path.append("../../bhtomspec/GMOS") -from gmos_fieldflattening import create_pixel_array +try: + from gmos_fieldflattening import create_pixel_array +except ImportError: + print("Skipping: gmos_fieldflattening module not available") + sys.exit(0) pixels = create_pixel_array("north", 2) rawpix_to_pix_itp = interpolate.interp1d(np.arange(len(pixels)), pixels) diff --git a/examples/example_gemini_gmos_longslit_manual_atlas.py b/examples/example_gemini_gmos_longslit_manual_atlas.py index e478d8f..381cb99 100644 --- a/examples/example_gemini_gmos_longslit_manual_atlas.py +++ b/examples/example_gemini_gmos_longslit_manual_atlas.py @@ -13,7 +13,11 @@ sys.path.append("../../bhtomspec/GMOS") -from gmos_fieldflattening import create_pixel_array +try: + from gmos_fieldflattening import create_pixel_array +except ImportError: + print("Skipping: gmos_fieldflattening module not available") + sys.exit(0) pixels = create_pixel_array("north", 2) rawpix_to_pix_itp = interpolate.interp1d(np.arange(len(pixels)), pixels) diff --git a/examples/example_gtc_osiris.py b/examples/example_gtc_osiris.py index 11779a7..31c8d0e 100644 --- a/examples/example_gtc_osiris.py +++ b/examples/example_gtc_osiris.py @@ -83,7 +83,7 @@ c.do_hough_transform() -c.plot_arc(save_fig="png", filename="output/gtc-osiris-arc-spectrum") +c.plot_arc(save_fig="png", filename=os.path.join(base_dir, "output", "gtc-osiris-arc-spectrum")) c.do_hough_transform() @@ -105,7 +105,7 @@ log_spectrum=False, tolerance=5.0, save_fig="png", - filename="output/gtc-osiris-wavelength-calibration", + filename=os.path.join(base_dir, "output", "gtc-osiris-wavelength-calibration"), ) # Show the parameter space for searching possible solution @@ -114,4 +114,4 @@ print("Peaks utilisation rate: {}%".format(peak_utilisation * 100)) print("Atlas utilisation rate: {}%".format(atlas_utilisation * 100)) -c.plot_search_space(save_fig="png", filename="output/gtc-osiris-search-space") +c.plot_search_space(save_fig="png", filename=os.path.join(base_dir, "output", "gtc-osiris-search-space")) diff --git a/examples/example_keck_deimos_830g.py b/examples/example_keck_deimos_830g.py index 3265ba4..0438a38 100644 --- a/examples/example_keck_deimos_830g.py +++ b/examples/example_keck_deimos_830g.py @@ -1,4 +1,5 @@ import json +import os import numpy as np from scipy.signal import find_peaks @@ -8,7 +9,9 @@ from rascal.util import refine_peaks # Load the 1D Spectrum from Pypeit -spectrum_json = json.load(open("data_keck_deimos/keck_deimos_830g_l_PYPIT.json")) +base_dir = os.path.dirname(__file__) +os.makedirs(os.path.join(base_dir, "output"), exist_ok=True) +spectrum_json = json.load(open(os.path.join(base_dir, "data_keck_deimos/keck_deimos_830g_l_PYPIT.json"))) spectrum = np.array(spectrum_json["spec"]) # Identify the arc lines @@ -16,7 +19,7 @@ peaks = refine_peaks(spectrum, peaks, window_width=3) c = Calibrator(peaks, spectrum=spectrum) -c.plot_arc(save_fig="png", filename="output/keck-deimos-arc-spectrum") +c.plot_arc(save_fig="png", filename=os.path.join(base_dir, "output", "keck-deimos-arc-spectrum")) c.set_hough_properties( num_slopes=10000.0, range_tolerance=500.0, @@ -66,7 +69,7 @@ log_spectrum=False, tolerance=5.0, save_fig="png", - filename="output/keck-deimos-wavelength-calibration", + filename=os.path.join(base_dir, "output", "keck-deimos-wavelength-calibration"), ) # Show the parameter space for searching possible solution @@ -75,4 +78,4 @@ print("Peaks utilisation rate: {}%".format(peak_utilisation * 100)) print("Atlas utilisation rate: {}%".format(atlas_utilisation * 100)) -c.plot_search_space(save_fig="png", filename="output/keck-deimos-search-space") +c.plot_search_space(save_fig="png", filename=os.path.join(base_dir, "output", "keck-deimos-search-space")) diff --git a/examples/example_lt_sprat_xe_manual_atlas.py b/examples/example_lt_sprat_xe_manual_atlas.py index 5242a67..b174f1f 100644 --- a/examples/example_lt_sprat_xe_manual_atlas.py +++ b/examples/example_lt_sprat_xe_manual_atlas.py @@ -21,7 +21,8 @@ plt.xlabel("Spectral Direction / Pix") plt.ylabel("Spatial Direction / Pix") plt.tight_layout() -plt.savefig("output/lt-sprat-arc-image.png") +os.makedirs(os.path.join(base_dir, "output"), exist_ok=True) +plt.savefig(os.path.join(base_dir, "output", "lt-sprat-arc-image.png")) # Collapse into 1D spectrum between row 110 and 120 spectrum = np.median(spectrum2D[110:120], axis=0) @@ -126,7 +127,7 @@ print("Atlas utilisation rate: {}%".format(atlas_utilisation * 100)) c.use_matplotlib() -c.plot_arc(save_fig="png", filename="output/lt-sprat-arc-spectrum") +c.plot_arc(save_fig="png", filename=os.path.join(base_dir, "output", "lt-sprat-arc-spectrum")) # Plot the solution c.plot_fit( @@ -136,8 +137,8 @@ log_spectrum=False, tolerance=5.0, save_fig="png", - filename="output/lt-sprat-wavelength-calibration", + filename=os.path.join(base_dir, "output", "lt-sprat-wavelength-calibration"), ) # Show the parameter space for searching possible solution -c.plot_search_space(save_fig="png", filename="output/lt-sprat-search-space") +c.plot_search_space(save_fig="png", filename=os.path.join(base_dir, "output", "lt-sprat-search-space")) diff --git a/examples/example_ntt_efosc_grism11.py b/examples/example_ntt_efosc_grism11.py index dd1085b..eb0e94f 100644 --- a/examples/example_ntt_efosc_grism11.py +++ b/examples/example_ntt_efosc_grism11.py @@ -1,3 +1,5 @@ +import os + from astropy.io import fits import numpy as np from scipy.signal import find_peaks @@ -7,7 +9,8 @@ from rascal.util import refine_peaks # Load the 1D Spectrum from Pypeit -data = fits.open("data_eso36_efosc/EFOSC_spec_HeAr227_0005.fits")[0] +base_dir = os.path.dirname(__file__) +data = fits.open(os.path.join(base_dir, "data_eso36_efosc/EFOSC_spec_HeAr227_0005.fits"))[0] spectrum = np.median(data.data.T, axis=0) # Identify the arc lines diff --git a/examples/example_wht_isis_r300r.py b/examples/example_wht_isis_r300r.py index 20398f3..ea37129 100644 --- a/examples/example_wht_isis_r300r.py +++ b/examples/example_wht_isis_r300r.py @@ -22,7 +22,8 @@ plt.xlabel("Spectral Direction / Pix") plt.ylabel("Spatial Direction / Pix") plt.tight_layout() -plt.savefig("output/wht-isis-arc-image.png") +os.makedirs(os.path.join(base_dir, "output"), exist_ok=True) +plt.savefig(os.path.join(base_dir, "output", "wht-isis-arc-image.png")) # Identify the peaks peaks, _ = find_peaks(spectrum, height=500, prominence=100, distance=5, threshold=None) @@ -30,7 +31,7 @@ # Initialise the calibrator c = Calibrator(peaks, spectrum=spectrum) -c.plot_arc(log_spectrum=True, save_fig="png", filename="output/wht-isis-arc-spectrum") +c.plot_arc(log_spectrum=True, save_fig="png", filename=os.path.join(base_dir, "output", "wht-isis-arc-spectrum")) c.set_hough_properties( num_slopes=10000, xbins=500, @@ -75,11 +76,11 @@ log_spectrum=False, tolerance=5.0, save_fig="png", - filename="output/wht-isis-wavelength-calibration", + filename=os.path.join(base_dir, "output", "wht-isis-wavelength-calibration"), ) # Show the parameter space for searching possible solution -c.plot_search_space(save_fig="png", filename="output/wht-isis-search-space") +c.plot_search_space(save_fig="png", filename=os.path.join(base_dir, "output", "wht-isis-search-space")) print("Stdev error: {} A".format(residual.std())) print("Peaks utilisation rate: {}%".format(peak_utilisation * 100)) diff --git a/pyproject.toml b/pyproject.toml index 5732685..79e9bc3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,7 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + [project] name = "rascal" version = "0.4.0" diff --git a/uv.lock b/uv.lock index 35733f7..efe4d62 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 2 +revision = 3 requires-python = ">=3.10" resolution-markers = [ "python_full_version >= '3.11'", @@ -1387,7 +1387,7 @@ wheels = [ [[package]] name = "rascal" version = "0.4.0" -source = { virtual = "." } +source = { editable = "." } dependencies = [ { name = "kaleido" }, { name = "matplotlib" },