Repository navigation
Add utu.spectrum.synthesize, the spectral radiance of each line - #14
Merged
Merged
Conversation
Spread each line of `contribution_function()` into a Gaussian in bins of velocity around its rest wavelength. Its width is the thermal motion of the ion added in quadrature to a nonthermal width, and its center is the line-of-sight velocity of the plasma. The plasma at each temperature has a profile of its own, and the profiles are summed over temperature with the emission measure. Every other axis of the emission measure, such as the two axes of a map, is carried through, and the shift and the nonthermal width can vary along any of them. The radiance of each bin is the integral of the profile across it, so the radiance of a line is conserved on coarse grids. The result's inputs are a `DopplerVectorArray` of the bin vertices. The tutorial gains a section on line profiles, and now gives the emission measure as that of n_e n_H, which is what fiasco's contribution function goes with. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017xqpht97bF4FWsACAA4wQa
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #14 +/- ##
==========================================
Coverage 100.00% 100.00%
==========================================
Files 17 19 +2
Lines 1055 1285 +230
==========================================
+ Hits 1055 1285 +230 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
- Raise a ValueError when `velocity` lacks `axis_velocity` or varies with temperature, when `temperature` or `contribution` lacks the axis of temperature, when a temperature is not positive, and when an argument varies along the axis of lines differently than `contribution` does. A velocity axis of the wrong name used to give a result of NaN. - Broadcast arguments with one element along the axis of lines, and return an empty result for a `contribution` with no lines, instead of raising. - Take the fraction of a profile in a bin from the complementary error function of the tail the bin is in. The difference of error functions rounded every bin beyond about 8.5 standard deviations to zero. - Fill a preallocated result one bin of velocity and one block of lines at a time, keeping every intermediate array under `_size_block` elements, and compute the profile once for all lines when nothing it depends on varies along the axis of lines. - Take the width of a bin in wavelength from the width of the bin in velocity, rather than as the difference of two Doppler-shifted wavelengths. - Say in the docs that the emission measure is per bin of temperature, not a DEM per unit log T, and document the n_e n_H convention in `lines()` and `contribution_function()` as well. - Test axis names other than the defaults, every new error, an empty and a broadcast axis of lines, reversed bins, the far wings, nonthermal widths which vary over a map, and synthesis in several blocks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017xqpht97bF4FWsACAA4wQa
This was referenced Oct 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This adds
utu.spectrum.synthesize, which turns the contribution functions of some lines and an emission measure into the spectral radiance of each line in bins of velocity. It is the first step toward simulated ESIS-II images built from a DEM, so that the esis report (esis-mission/esis#72), the ESIS-II paper and the ctis inversion tests can all get the same scene from installed code.What it computes
shift), and its width is the thermal motion of the ion added in quadrature to a nonthermal width.erfrounds every bin beyond about 8.5σ to zero.contributionis the output ofcontribution_function(), unchanged.mass(such asfiasco.Ion.mass) sets the thermal width; give it along the line axis to do several ions at once.emission_measureis ∫ n_e n_H dh per temperature bin, the convention of fiasco's G(T).shiftandwidth_nonthermalcan vary along any of them, including temperature.FunctionArraywhose inputs are ana.DopplerVectorArrayof the bin vertices (wavelength plus rest wavelength, so.velocityworks) and whose outputs are in erg cm⁻² s⁻¹ sr⁻¹ Å⁻¹, along the line and velocity axes._size_block(2²⁵ elements), so a map needs little more memory than the result itself. When nothing the profile depends on varies along the line axis, the profile is computed once for all lines.ValueErrorfor a missing velocity or temperature axis, a velocity grid that varies with temperature, a temperature that isn't positive, or an argument whose line axis disagrees withcontribution's. An argument with one element along the line axis broadcasts, and an emptycontributiongives an empty result.Other changes
lines(), is ∫ n_e n_H dh. The tutorial,lines()andcontribution_function()now say so.scipyis listed as a dependency, forerfc. It was already installed through fiasco.Tests
test_synthesis.pyhas 23 tests, 22 of which use made-up contribution functions, so they run on every job of the matrix, not only the CHIANTI one. They check that:shift(−30, 0, +45 km/s);ValueErroris raised, an empty line axis gives an empty result, and a length-1massbroadcasts;lines()divided by 4π sr (to 1e-10).I checked that the tests can fail. Doubling the thermal variance, dropping the 4π, or flipping the sign of the shift each fails two tests, and going back to a difference of
erffails the wing and reversed-bin tests.Locally: the full suite with
--doctest-modulespasses (108 tests), the docstring example and every block of the tutorial run, andblackandruffpass.The second commit fixes the 13 findings of an xhigh code review of the first.
🤖 Generated with Claude Code
https://claude.ai/code/session_017xqpht97bF4FWsACAA4wQa