Add multi-wavelength spectroscopy tutorial#203
Conversation
Adds an end-to-end spectroscopy tutorial covering: - Loading real SDSS spectra from FITS files (FITSIO.jl) - Physical units and Fλ↔Fν conversions (Unitful + UnitfulAstro) - Dust extinction with CCM89, OD94, CAL00 laws (DustExtinction.jl) - Spectral axis inspection via spectral_axis/flux_axis (Spectra.jl) - Automatic uncertainty propagation (Measurements.jl) - Synthetic blackbody spectra generation (Spectra.jl) - Spectral arithmetic: sky subtraction and scaling - Cosmological redshift and luminosity distances (Cosmology.jl) Includes test/test_tutorial.jl — standalone verification script. Updates docs/Project.toml with [compat] bounds for all new deps. Closes JuliaAstro#202
DustExtinction='0.6, 1' excluded v0.11.x (current release), creating an unsolvable constraint with FITSIO 0.17 in CI.
Tutorial uses plain julia code blocks (not @example), so docs build environment does not need to install tutorial dependencies. Extra packages were causing CI resolution failures in the JuliaAstroDocs test suite.
The CI test runner picks up all .jl files in test/ and tries to execute them. test_tutorial.jl requires packages not present in the test environment, causing JuliaAstroDocs to error. Users can run the tutorial locally by installing the packages listed in the tutorial's Packages section.
|
@icweaver can you check the PR. What changes should I do? |
cgarling
left a comment
There was a problem hiding this comment.
Interesting example, thanks for the PR. I made some specific comments/suggestions below, here is some high-level feedback:
- It would be nice to have this run on CI so the output can be displayed. Could you expand on why you can't use
@examplehere? I thought that if you setup the doc build environment correctly there shouldn't be a problem with importing Spectra.jl even if it isn't in the General registry yet (i.e., using [sources] to set the url in the Project.toml). - Mostly you are dealing with flux density units in this example so we should make the associated plot labels "Flux Density" rather than "Flux" for clarity
- I would try to be more consistent with using units when constructing the wavelength / flux density vectors, some places where you are constructing blackbody spectra you are not putting units on the wavelengths/temperatures and I think we want to encourage the use of units
- I think that
blackbodyreturns radiance units so you may need to calculate the luminosity density as L_lam(lambda) = 4 \pi^2 R^2 B(lambda,T) where R is the radius of the spherical blackbody (say 1 solar radius) and B(lambda, T) is what blackbody returns. It would be good to check this and amend theblackbodydocstring to be more descriptive. - We are mostly using Makie.jl for plotting in our documentation now, idk if anyone has strong feelings on this. I don't mind using Plots.jl but would probably prefer makie
- @example blocks for CI + Spectra via [sources] in Project.toml - Flux -> Flux Density in all plot ylabels - Units on wave_bb, wave_synth (.* u"angstrom"), temperatures (u"K") - L_lam = 4pi^2 * R^2 * B(lambda,T) correct luminosity formula - SDSS ivar column for real Measurements uncertainties - F_obs = L*(1+z)/(4pi*d_L^2) correct cosmological formula - Plots.jl -> CairoMakie throughout - SFD98Map with ICRSCoords -> GalCoords conversion
- Replace synthetic galaxy spectrum with real SDSS plate 1323 data - Use FITS ivar column for real per-pixel σ = 1/√ivar uncertainties - Addresses mentor comment: use Measurements with actual SDSS error column
|
@cgarling I've added Spectra.jl to docs/Project.toml via
|
|
I do Github Actions with network dependencies pretty frequently (e.g., through DataDeps.jl) and can't recall any issues. What exactly is the problem CI is creating, are you hitting a firewall (Github won't let you access external URLs)? |
cgarling
left a comment
There was a problem hiding this comment.
Thanks for the update, good progress! More comments below
| fig4, ax4 = lines(ustrip.(wave_rest), ustrip.(bb_rest.flux); | ||
| label = "z = 0", color = :black, | ||
| axis = (xlabel = "Wavelength (Å)", | ||
| ylabel = "Flux Density (erg s⁻¹ cm⁻² Å⁻¹)", | ||
| title = "Cosmological Surface-Brightness Dimming")) | ||
|
|
||
| for (z, col) in zip([0.5, 1.0, 2.0], [:blue, :green, :red]) | ||
| d_L = uconvert(u"cm", luminosity_dist(cosmo, z)) | ||
| w_obs = wave_rest .* (1 + z) | ||
| F_obs = L_lam .* (1 + z) ./ (4π .* d_L.^2) | ||
| lines!(ax4, ustrip.(w_obs), ustrip.(F_obs); label = "z = $z", color = col) | ||
| end | ||
| axislegend(ax4, position = :rt) | ||
| fig4 |
There was a problem hiding this comment.
| fig4, ax4 = lines(ustrip.(wave_rest), ustrip.(bb_rest.flux); | |
| label = "z = 0", color = :black, | |
| axis = (xlabel = "Wavelength (Å)", | |
| ylabel = "Flux Density (erg s⁻¹ cm⁻² Å⁻¹)", | |
| title = "Cosmological Surface-Brightness Dimming")) | |
| for (z, col) in zip([0.5, 1.0, 2.0], [:blue, :green, :red]) | |
| d_L = uconvert(u"cm", luminosity_dist(cosmo, z)) | |
| w_obs = wave_rest .* (1 + z) | |
| F_obs = L_lam .* (1 + z) ./ (4π .* d_L.^2) | |
| lines!(ax4, ustrip.(w_obs), ustrip.(F_obs); label = "z = $z", color = col) | |
| end | |
| axislegend(ax4, position = :rt) | |
| fig4 | |
| fig4, ax4 = lines(ustrip.(wave_rest), ustrip.(bb_rest.flux); | |
| label = "z = 0", color = :black, | |
| axis = (xlabel = "Wavelength (Å)", | |
| ylabel = "Flux Density (erg s⁻¹ cm⁻² Å⁻¹)", | |
| yscale = log10, yticks=LogTicks(LinearTicks(5)), | |
| title = "Cosmological Surface-Brightness Dimming")) | |
| for (z, col) in zip([0.1, 0.5, 1.0], [:blue, :green, :red]) | |
| d_L = uconvert(u"cm", luminosity_dist(cosmo, z)) | |
| w_obs = wave_rest .* (1 + z) | |
| F_obs = L_lam .* (1 + z) ./ (4π .* d_L.^2) | |
| lines!(ax4, ustrip.(w_obs), ustrip.(F_obs); label = "z = $z", color = col) | |
| end | |
| axislegend(ax4, position = :rt) | |
| fig4 |
Changed to display a little better
|
I've been thinking about re-homing our tutorials section under our learn.JuliaAstro site that is currently in the works. My thinking is that this would help reduce duplication of efforts and also help make things more discoverable. I'd be happy to help migrate things over if this sounds like a reasonable organizational step to y'all. I think I am already seeing a good bit of overlap with our Dust extinction notebook, which could probably absorb the changes proposed here |
|
Replace FITSIO.jl with FITSFile.jl. |
Co-authored-by: Chris Garling <chris.t.garling@gmail.com>
Co-authored-by: Chris Garling <chris.t.garling@gmail.com>
Co-authored-by: Chris Garling <chris.t.garling@gmail.com>
Co-authored-by: Chris Garling <chris.t.garling@gmail.com>
|
Ok, I think I incorporated the above comments here and tried to clean things up a bit. Can add more if this seems like the right direction to go for this PR |
Follow-up to JuliaAstro/JuliaAstro.github.io#203 Trying it out in notebook format Doc preview: https://learn.juliaastro.org/previews/PR28/tutorials/spectroscopy-sdss/ --------- Co-authored-by: Chris Garling <chris.t.garling@gmail.com>
|
Thanks @aditya-pandey-dev for your contribution! We have merged things here over on our learn.JuliaAstro site that is currently under construction |
Closes #202
What's included
A new tutorial at
docs/src/tutorials/multi-wavelength-spectroscopy.mdcovering a realistic end-to-end spectroscopy workflow:spectral_axis/flux_axis(Spectra.jl)Testing
Includes
test/test_tutorial.jl— a standalone verification script:All 5 dependency tests pass on Julia 1.12.5
Packages exercised
Spectra.jl, FITSIO.jl, DustExtinction.jl, UnitfulAstro.jl, Measurements.jl, Cosmology.jl, Plots.jl
Notes
juliafences (not@example) since Spectra.jlis installed from GitHub and not yet in the General registry
continuum()is referenced as a planned future feature with a link toTowards
SpectrumBase.jlSpectrumBase.jl#41[compat]bounds added for all new registered dependencies