Chemical Abundance Methodology

Comprehensive documentation of the emission-line abundance derivation pipeline implemented in jwspecabund. The methodology follows the six-step procedure of Berg et al. (2025) for UV nitrogen abundances, extended with strong-line calibrations from Sanders et al. (2025) and a Bayesian forward model following Cullen et al. (2025).


Table of Contents

  1. Overview

  2. Dust Correction

  3. Electron Temperature

  4. Electron Density

  5. Oxygen Abundance — 12 + log(O/H)

  6. Nitrogen-to-Oxygen Ratio — log(N/O)

  7. Carbon-to-Oxygen Ratio — log(C/O)

  8. Ionisation Correction Factors

  9. Strong-Line Calibrations

  10. Bayesian Forward Model

  11. Uncertainty Propagation

  12. Upper Limits for Non-Detected Ions

  13. References


1. Overview

Three independent methods are available, orchestrated by compute_abundances() in jwspecabund._core:

Method

Key reference

When to use

Direct T_e

Berg et al. (2025)

Auroral line detected (e.g. [OIII] 4363)

Strong-line

Sanders et al. (2025)

No auroral detection; uses O3, O2, R23, O32

Bayesian forward model

Cullen et al. (2025)

MCMC/nested sampling over (T_e, n_e, ionic abundances)

All three methods begin with the same dust correction step. The direct T_e method is documented in the most detail below, as it is the primary approach for galaxies with UV spectroscopy.


2. Dust Correction

Source: jwspecabund.dust

2.1 Attenuation from the Balmer decrement

The dust attenuation A_V is derived from a Balmer line ratio (typically Hgamma/Hbeta, as Halpha may fall outside the observed wavelength range at high redshift). The observed ratio R_obs is compared to the intrinsic Case B recombination ratio R_int:

A_V = 2.5 × log10(R_obs / R_int) / (f_den − f_num)

where f_num and f_den are the normalised attenuation curve values A(lambda)/A_V at the numerator and denominator wavelengths. Negative A_V values are clamped to zero.

Intrinsic Case B ratios at T_e = 10^4 K, n_e = 100 cm^-3 (Osterbrock & Ferland 2006):

Ratio

Value

Halpha / Hbeta

2.86

Hgamma / Hbeta

0.468

Hdelta / Hbeta

0.259

2.2 Extinction / attenuation laws

Two laws are implemented:

  • Cardelli, Clayton & Mathis (1989): Milky Way extinction curve with R_V = 3.1. Polynomial fits in 1/lambda across IR, optical/NIR, and UV regimes. Used for individual galaxy spectra following Berg et al. (2025).

  • Salim et al. (2018) / Noll et al. (2009): Modified Calzetti et al. (2000) attenuation curve with a UV bump and power-law slope deviation. Default parameters: R_V = 3.15, delta = -0.35, bump strength B = 2.27.

2.3 Multi-Balmer A_V

When multiple Balmer lines are detected (Hgamma through H10), individual A_V values are derived from each line’s ratio to Hbeta and combined as an SNR-weighted average via compute_Av_multi_balmer(). The weights are the inverse-variance of each A_V estimate.

Excluded lines (blended at typical NIRSpec resolution):

  • Hepsilon (3971 Å): blended with [NeIII] 3968 Å (Δλ = 3 Å)

  • H8 (3890 Å): blended with HeI 3889 Å (Δλ = 0.4 Å)

Included lines:

Line

λ_rest (Å)

Intrinsic ratio to Hβ

Hgamma

4342.90

0.468

Hdelta

4102.89

0.259

H9

3836.48

0.0731

H10

3799.00

0.0530

Single-pair option. Passing balmer_pair=(numerator, denominator) to compute_abundances (or calling compute_Av_balmer_pair() directly) restricts the derivation to one chosen decrement — e.g. ("Ha", "HBETA") for Hα/Hβ — bypassing the SNR-weighted multi-line fit. This is useful when only one Balmer ratio is high-SNR and the fainter lines would otherwise bias or inflate the A_V error. The intrinsic Case-B ratio is taken from the ladder above (extended with Hα = 2.86 and Hβ = 1.00). A_V is still applied as a single point value to all draws; its formal error is reported on the result but not marginalised into the abundances unless A_V resampling is explicitly enabled (§2.4).

2.4 Dust correction of line fluxes

Each emission-line flux is corrected using:

F_corr = F_obs × 10^(0.4 × A_lambda)

where A_lambda = A_V × f(lambda) from the chosen attenuation law.

2.5 Error propagation

The uncertainty on A_V is propagated from the fractional error on the observed ratio:

sigma_R = R_obs × sqrt[(sigma_num / F_num)^2 + (sigma_den / F_den)^2]
sigma_AV = |dA_V/dR| × sigma_R
         = 2.5 / [R_obs × ln(10) × (f_den − f_num)] × sigma_R

3. Electron Temperature

Source: jwspecabund.direct

3.1 Primary diagnostic: [OIII] auroral-to-nebular ratio

The electron temperature of the high-ionisation zone, T_e(O2+), is derived from the collisionally-excited line ratio:

R_OIII = [OIII] 4363 / ([OIII] 5007 + [OIII] 4959)

PyNEB’s Atom("O", 3).getTemDen() inverts the ratio to solve for T_e. We use to_eval="(L(4363))/(L(5007)+L(4959))" with log-space root-finding (log=True, start_x=3.0, end_x=5.0) to ensure convergence at T_e > 25,000 K, which is typical of metal-poor high-z galaxies.

3.2 UV fallback diagnostic: O III] 1666 / ([OIII] 5007 + 4959)

When [OIII] 4363 is unavailable or has insufficient SNR, the O III] 1666 Å intercombination line provides an alternative T_e diagnostic:

R_1666 = O III] 1666 / ([OIII] 5007 + [OIII] 4959)

The 1666 Å line arises from the 5→2 transition with a 7.5 eV energy gap (compared to 2.8 eV for 4363), making this ratio more temperature-sensitive. PyNEB’s Atom("O", 3).getTemDen() is used with to_eval="(L(1666))/(L(5007)+L(4959))" and solver range extended to 250,000 K (start_x=3.0, end_x=5.4). The ratio is monotonically increasing with T_e, so the solution is unique.

This diagnostic is automatically used as a fallback in compute_abundances() when [OIII] 4363 is not detected but O III] 1666 and the [OIII] 5007+4959 nebular lines are available.

3.3 Secondary diagnostic: [NII] auroral-to-nebular ratio

When [NII] 5756 is detected, T_e(N+) is computed from:

R_NII = [NII] 5756 / [NII] 6585

using PyNEB’s Atom("N", 2).getTemDen().

3.4 T_e–T_e relations for zone temperatures

A single auroral line measures T_e in one ionisation zone. Empirical relations map T_e(O2+) (the high zone) to the intermediate and low zones:

Intermediate zone (O+, C2+, Si2+) — Garnett (1992):

T_int = [0.243 + t × (1.031 − 0.184 × t)] × 10^4 K

where t = T_high / 10^4.

Low zone (N+, S+) — two options:

  1. DESI DR2 (arXiv:2601.02463, recommended):

    T_low = 0.648 × T_high + 3270 K
    
  2. Classical (Campbell, Terlevich & Melnick 1986; used in Garnett 1992):

    T_low = 0.7 × T_high + 3000 K
    

4. Electron Density

Source: jwspecabund.direct, notebook 08

4.1 Density-sensitive doublets

Five diagnostic doublets span the full ionisation structure, each measured via PyNEB’s getTemDen() at the appropriate zone temperature:

Doublet

Ion

Zone

T_e used

PyNEB wavelengths

[S II] 6718/6732

S+

Low

T_low

6718, 6732

[O II] 3726/3729

O+

Low

T_low

3726, 3729

C III] 1907/1909

C2+

Intermediate

T_int

1907, 1909

Si III] 1883/1892

Si2+

Intermediate

T_int

1883, 1892

N IV] 1483/1486

N3+

High

T_high

1483, 1487

[Ar IV] 4711/4740

Ar3+

High

T_high

4711, 4740

4.2 Multi-phase density assignments (Berg et al. 2025, Section 4.1)

Each ionisation zone is assigned a representative density:

  • n_e,low: from [S II] (preferred) or [O II]

  • n_e,int: from C III] (preferred) or Si III]

  • n_e,high: from N IV] (preferred) or [Ar IV]

  • Fallback: n_e = 100 cm^-3 if no diagnostic is available

4.3 Iterative T_e–n_e refinement

T_e and n_e are coupled (density diagnostics require a temperature, and the temperature diagnostic requires a density). The pipeline uses a two-pass procedure:

  1. Pass 1: Compute T_e with an initial density (n_e = 10^4 cm^-3). Derive all zone densities at this T_e.

  2. Pass 2: Recompute T_e using the refined high-zone density from Pass 1. Update zone temperatures via the T_e–T_e relations.

This converges in a single iteration because density diagnostics are only weakly sensitive to T_e.


5. Oxygen Abundance — 12 + log(O/H)

Source: jwspecabund.direct.compute_ionic_abundances, compute_total_abundances

5.1 Ionic abundance formula

For any ion X^i+, the ionic abundance relative to hydrogen is:

X^i+/H+ = (F_line / F_Hbeta) × (epsilon_Hbeta / epsilon_line)

where epsilon denotes the volume emissivity computed by PyNEB at the appropriate (T_e, n_e).

For doublets (e.g. [O II] 3726+3729), the emissivities of both components are summed before dividing.

5.2 Hbeta emissivity

  • T_e <= 30,000 K: PyNEB RecAtom("H", 1).getEmissivity(Te, ne, wave=4861), based on the Storey & Hummer (1995) recombination tables.

  • T_e > 30,000 K: The Storey & Hummer tables do not extend beyond 30,000 K. We use the Aller (1984) Case B formula:

    alpha_Hbeta_eff = 3.03 × 10^-14 × (T_e / 10^4)^(-0.874)   [cm^3 s^-1]
    epsilon_Hbeta   = alpha_Hbeta_eff × h × nu_Hbeta
    

    where h × nu_Hbeta = hc / lambda_Hbeta with lambda_Hbeta = 4862.68 A.

5.3 O2+/H+ from [OIII] 5007

Parameter

Value

Line

[OIII] 5007

PyNEB ion

Atom("O", 3), wave=5007

Zone

T_high, n_e,high

5.4 O+/H+ from [OII] 3726+3729

Parameter

Value

Lines

[OII] 3726 + [OII] 3729 (summed)

PyNEB ion

Atom("O", 2), waves=[3726, 3729]

Zone

T_low, n_e,low

If only the unresolved doublet is available (e.g. from prism data), the blended flux is used directly.

5.5 Total oxygen abundance

No ionisation correction factor is required for oxygen:

O/H = O+/H+ + O++/H+
12 + log(O/H) = 12 + log10(O/H)

The fraction O+/O quantifies the contribution of the low-ionisation zone, which feeds into the ICF calculations for other elements.


6. Nitrogen-to-Oxygen Ratio — log(N/O)

Source: jwspecabund.direct.compute_ionic_abundances, jwspecabund.martinez25_icf

Nitrogen abundance determination requires up to four ionic species, each measured in a different ionisation zone. An ionisation correction factor (ICF) then maps the observed ionic ratio to the total N/O.

6.1 N+ from [NII] 6585

Parameter

Value

Line

[NII] 6585

PyNEB ion

Atom("N", 2), wave=6584

Zone

T_low, n_e,low

6.2 N2+ from NIII] 1749+1752

Parameter

Value

Lines

NIII] 1749 + NIII] 1752 (summed)

PyNEB ion

Atom("N", 3), waves=[1749, 1752]

Zone

T_high, n_e,high

6.3 N3+ from NIV] 1483+1486

Parameter

Value

Lines

NIV] 1483 + NIV] 1486 (summed)

PyNEB ion

Atom("N", 4), waves=[1483, 1487]

Zone

T_high, n_e,high

6.4 N4+ from NV 1239+1243

PyNEB has no atomic data for N V. We implement a manual three-level Li-like atom model:

  • Level 1: 2s ^2S_{1/2} (g = 2)

  • Level 2: 2p ^2P_{1/2} (g = 2), lambda = 1242.804 A, A_{21} = 3.37 × 10^8 s^-1

  • Level 3: 2p ^2P_{3/2} (g = 4), lambda = 1238.821 A, A_{31} = 3.40 × 10^8 s^-1

Effective collision strengths Upsilon(T) are interpolated from the tabulation of Aggarwal & Keenan (2004) / CHIANTI v10. Statistical equilibrium is solved for the three-level system, and the emissivity follows from:

epsilon = (n_upper / n_total) × A × h × nu / n_e

6.5 Direct-sum N/O (Berg et al. 2025, Eq. 5)

The raw ionic sum is:

(N/O)_raw = (N+ + N2+ + N3+ + N4+) / (O+ + O2+)

This is biased because the ionisation structure is non-uniform — the N3+/N ratio differs from O2+/O. An ICF is required to correct this (see Section 8).

6.6 ICF-corrected N/O

The final N/O is obtained by applying the best available ICF from Martinez et al. (2025):

log(N/O) = log10(ionic_ratio × ICF)

The ICF selection procedure is described in Section 8.2.


7. Carbon-to-Oxygen Ratio — log(C/O)

Source: jwspecabund.direct.compute_ionic_abundances, compute_total_abundances

7.1 C2+ from CIII] 1907+1909

Parameter

Value

Lines

CIII] 1907 + CIII] 1909 (summed)

PyNEB ion

Atom("C", 3), waves=[1907, 1909]

Zone

T_high, n_e,high

7.2 C3+ from CIV 1548+1551

Parameter

Value

Lines

CIV 1548 + CIV 1551 (summed)

PyNEB ion

Atom("C", 4), waves=[1548, 1551]

Zone

T_high, n_e,high

Note that CIV can have both stellar wind and nebular components. Only the nebular component should be used; broad stellar P Cygni profiles must be excluded.

7.3 C+ from CII] 2326

Parameter

Value

Lines

CII] 2324 + CII] 2326 (multiplet sum)

PyNEB ion

Atom("C", 2), waves=[2323, 2325, 2326, 2327, 2328]

Zone

T_low, n_e,low

The CII] λ2326 multiplet (five components from 2323 to 2328 Å) traces C+ in the low-ionisation zone. When detected, the C+ ionic abundance is included in the carbon budget.

7.4 Total C/O

Two paths are available depending on whether C+ is detected:

With CII] 2326 (Garnett+1997 ICF):

When C+ is detected, the total C/O is computed using the Garnett (1997) ionisation correction factor:

C/O = ICF_C × (C2+/H+ + C3+/H+) / O2+/H+
ICF_C = (O+ + O2+) / O2+

This corrects for any remaining unobserved carbon ions by assuming the carbon and oxygen ionisation structures are similar.

Without CII] 2326 (Jones et al. 2023):

When C+ is not detected, C/O is computed as a direct ionic sum:

C/O = (C2+/H+ + C3+/H+) / (O2+/H+)

This assumes that C2+ and C3+ account for essentially all carbon in the O2+ zone, following Jones et al. (2023).


8. Ionisation Correction Factors

8.1 Izotov et al. (2006) — classical optical ICFs

Source: jwspecabund.icf

These are polynomial fits in x = O+/O_total, calibrated against photoionisation models. Used as the fallback when UV lines or log(U) are unavailable.

Element

Equation

Formula

Applied as

Nitrogen

Eq. 18

ICF_N = -0.825x^2 + 0.718x + 0.853

N/O = ICF_N × (N+/O+)

Neon

Eq. 19

ICF_Ne = -0.385x^2 + 0.405x + 0.335

Ne/O = ICF_Ne × (Ne2+/O2+)

Sulfur

Eq. 20

ICF_S = 0.013 + x(5.986 + x(-21.085 + x(26.462 - 11.282x)))

S/O = ICF_S × (S+ + S2+)/O

Argon

Eqs. 22-23

ICF_Ar = 0.157 + x(3.119 + x(-6.185 + 4.517x))

Ar/O = ICF_Ar × (Ar2+/O2+)

8.2 Martinez et al. (2025) — density-dependent ICFs

Source: jwspecabund.martinez25_icf

These ICFs are calibrated on Cloudy photoionisation models and account for the dependence of the ionisation correction on electron density, ionisation parameter, and metallicity. They are the recommended approach for UV N/O determinations (Berg et al. 2025, Section 4.2).

Ionisation parameter diagnostics

Before applying an ICF, the ionisation parameter log(U) must be estimated from one of two diagnostics:

  1. N43 diagnostic (recommended):

    log(N43) = log10(NIV] 1486 / NIII] 1750)
    log(U_high) = f(log(N43), Z/Zsun; n_e)
    

    Density-insensitive. Preferred when NIV] and NIII] are both detected. Valid range: -3.0 <= log(N43) <= 0.5.

  2. O32 diagnostic (fallback):

    log(O32) = log10([OIII] 5007 / [OII] 3727)
    log(U_int) = f(log(O32), Z/Zsun; n_e)
    

    Density-sensitive. Valid range: -1.0 <= log(O32) <= 2.5.

Both diagnostics use bicubic surface fits (Martinez et al. 2025, Table 3) interpolated between electron density grid points at log10(n_e) = [2, 3, 4, 5, 6]:

f(x, y) = A + Bx + Cy + Dxy + Ex^2 + Fy^2 + Gxy^2 + Hyx^2 + Ix^3 + Jy^3

The metallicity input is Z/Z_sun = 10^(12+log(O/H) - 8.69), where 12 + log(O/H)_sun = 8.69 (Asplund et al. 2009).

Overall validity ranges: 0.05 <= Z/Z_sun <= 0.40, -3.5 <= log(U) <= -1.0.

Five N/O ICFs (Table 4)

Each ICF corrects a specific ionic ratio to total N/O:

ICF

Ionic ratio

Notes

ICF 5

(N2+ + N3+) / O2+

Pure UV. Most robust at log(U) > -2.75 with corrections < 5%. Most preferred.

ICF 4

(N+ + N2+) / (O+ + O2+)

Mixed optical + UV. Robust across a wide range of conditions.

ICF 2

N2+ / O2+

UV single-ion. Overestimates at low log(U).

ICF 1

N+ / O+

Classical optical. Simplest but least accurate at high ionisation.

ICF 3

N3+ / O2+

Large corrections (100–15,000%); returned in log-space. Least preferred.

Selection priority

compute_NO_martinez25() selects the best ICF based on which ionic abundances are available, in order of decreasing preference:

  1. ICF 5 — requires N2+, N3+, O2+

  2. ICF 4 — requires N+, N2+, O+, O2+

  3. ICF 2 — requires N2+, O2+

  4. ICF 1 — requires N+, O+

  5. ICF 3 — requires N3+, O2+ (last resort)

The final N/O is:

N/O = ionic_ratio × ICF(log(U), Z/Z_sun, n_e)

Inputs outside the calibration bounds

The Martinez et al. (2025) coefficients are polynomial fits over a bounded calibration domain (the validity ranges above). The bicubic surface diverges if it is evaluated by extrapolation, so an input that falls outside its range — log(O32), log(N43), Z/Z_sun, or the resulting log(U) — is rejected, not clipped: the surface returns NaN rather than a boundary value or an extrapolated number. This keeps unphysical, uncalibrated values out of the reported N/O entirely.

Because only the N/O ICF depends on log(U) and Z/Z_sun, this rejection affects N/O alone. O/H (direct T_e), T_e, and the other X/O ratios (C/O, S/O, Ne/O, Ar/O) do not use the Martinez ICF and are unaffected — see Section 11.3 for how this is handled in the Monte Carlo / posterior loops.


9. Strong-Line Calibrations

Source: jwspecabund.strong_line

When no auroral line is detected, 12 + log(O/H) is estimated from strong-line ratios using the simultaneous polynomial calibrations of Sanders et al. (2025).

9.1 Diagnostic ratios

Ratio

Definition

Lines required

O3

log10([OIII] 5007 / Hbeta)

OIII_5007, HBETA

O2

log10([OII] 3726+3729 / Hbeta)

OII_doublet, HBETA

R23

log10(([OIII] 5007 + [OII] 3726+3729) / Hbeta)

OIII_5007, OII_doublet, HBETA

O32

log10([OIII] 5007 / [OII] 3726+3729)

OIII_5007, OII_doublet

Each ratio R is modelled as a polynomial in Z = 12 + log(O/H):

R(Z) = c0 + c1 × (Z - 8.0) + c2 × (Z - 8.0)^2 + ...

9.2 Simultaneous fit

All available ratios are fit simultaneously by minimising the combined chi-squared:

chi^2(Z) = sum_i [(R_obs,i - R_model,i(Z))^2 / (sigma_obs,i^2 + sigma_cal,i^2)]

where sigma_cal = sqrt(sigma_R,fit^2 + sigma_R,int^2) accounts for both the fit residual and intrinsic scatter in the calibration. The best-fit Z is found via bounded scalar minimisation over 6.5 <= Z <= 9.0.

9.3 Monte Carlo uncertainty

The uncertainty on Z is estimated by perturbing each ratio by its observational error (1000 MC iterations) and re-fitting. The reported uncertainty is the standard deviation of the posterior.


10. Bayesian Forward Model

Source: jwspecabund.forward

An alternative approach following Cullen et al. (2025): free parameters (T_e, n_e, ionic abundances) are sampled via MCMC or nested sampling. For each parameter vector, collisionally-excited line emissivities from PyNEB and the Aller (1984) Hbeta recombination formula predict line flux ratios that are compared to observations via a Gaussian likelihood.

This method self-consistently accounts for the T_e–n_e coupling and non-Gaussian posterior distributions, but is more computationally expensive than the direct method.


11. Uncertainty Propagation

11.1 Monte Carlo approach (direct T_e method)

The full abundance pipeline is wrapped in a Monte Carlo loop (default N_mc = 1000 iterations):

  1. Draw perturbed fluxes: F_perturbed ~ N(F_observed, sigma_F) for each emission line.

  2. Re-derive all quantities: dust correction, T_e, n_e, ionic abundances, log(U), ICFs, total abundances.

  3. Accumulate posterior arrays: {O/H, N/O, C/O, T_e, …}.

  4. Report: median and 16th/84th percentile intervals.

11.2 MCMC posterior propagation

When MCMC chains are available from jwspecmcmc, posterior flux samples are drawn directly from the chains rather than assuming Gaussian errors. The dust correction is applied per-sample:

F_corr,i = F_obs,i × 10^(0.4 × k(lambda) × A_V,i)

where A_V,i is re-derived from the Balmer decrement in each sample. This propagates the full posterior covariance between line fluxes through to the final abundances.

11.3 Out-of-bounds resampling and the O/H–N/O decoupling

The Martinez et al. (2025) log(U)/ICF surfaces are only valid inside their calibration domain (Section 8.2). Inputs outside that domain are rejected (set to NaN), not clipped — see “Inputs outside the calibration bounds” in Section 8.2. In the uncertainty loops this is handled per draw so the reported sample counts stay meaningful:

  1. Only N/O is gated. If a draw’s log(O32)/log(N43), Z/Z_sun, or resulting log(U) falls outside the bounds, log(U) is set to NaN for that draw. The Martinez N/O ICF then returns NaN, so the draw contributes nothing to N/O.

  2. O/H and the other ratios are kept. O/H (direct T_e), T_e, and the X/O ratios that do not use the Martinez ICF (C/O, S/O, Ne/O, Ar/O) are computed and recorded for every drawn sample, in-bounds or not. They are never discarded on account of an out-of-bounds N/O.

  3. Resampling to the requested count. The loop keeps drawing until n_mc (Gaussian MC) or n_posterior (MCMC pool) in-bounds N/O draws have been collected, so N/O is sampled to the requested depth rather than silently under-sampled. Solver failures and missing-line NaNs are not re-drawn (re-drawing cannot fix them) and count toward the target.

  4. Different lengths are expected. Because out-of-bounds draws are re-drawn for N/O but retained for O/H, the O/H posterior generally holds more finite samples than the N/O posterior. The two arrays are independent; do not assume they are the same length.

  5. Safety cap. To guarantee termination for an object centred outside the bounds (e.g. Z/Z_sun < 0.05, where acceptance ≈ 0), the total number of attempts is capped at 20× the requested count. If the target is not reached, a WARNING is logged ("... in-bounds N/O draws ...") and N/O is reported from whatever in-bounds draws were collected; O/H and the other ratios remain fully sampled.

Note

If you set the jwspecabund logger above WARNING, the under-sampling message is suppressed. To detect objects where N/O could not be sampled to the requested depth, inspect the posterior directly, e.g. np.isfinite(result.NO_posterior).sum().

11.4 Pre-computed emissivity grids

To avoid calling PyNEB ~10^6 times (N_mc × N_lines), emissivity grids are pre-computed as a function of T_e(high) on a fine grid (e.g. 5,000–80,000 K, 500 points). Each MC iteration interpolates into these grids, giving a factor ~100× speedup while preserving the parametric dependence on T_e.


12. Upper Limits for Non-Detected Ions

Source: jwspecabund._core._compute_continuum_rms_limits, _compute_ionic_upper_limits

When an emission line is not detected (flux consistent with zero or below the SNR threshold), we compute a 3σ upper limit on its flux and convert this to an ionic abundance upper limit. This is essential for constraining N/O and C/O when UV lines (e.g. N III], N IV], C IV) fall below the detection threshold.

12.1 Continuum-RMS flux upper limits

The flux upper limit is derived from the noise in the continuum around the expected line position, independent of the emission-line fit:

F_ul = n_sigma × RMS_cont × sigma_inst × sqrt(2π)

where:

  • RMS_cont: root-mean-square of the fit residuals (data minus model) in a window of ±5σ around the expected line centre, excluding the central ±2σ where the line would sit. If fewer than 3 pixels fall in this annulus, the window is expanded to ±10σ with ±3σ exclusion.

  • sigma_inst: the instrumental line width (in Angstrom), computed from the grating resolving power R as σ = λ_obs / (2.355 × R). When grating metadata is unavailable (e.g. spectra loaded from npz files), R is estimated from the pixel sampling via R_from_pixels(wave_um).

  • n_sigma: detection threshold, default 3.

This method is preferred over using the fit error because it measures actual noise at the line position rather than relying on bootstrap or MCMC error estimates, which can be inflated by unconstrained parameters (particularly for faint UV secondary doublet members).

12.2 Dust correction of upper limits

Flux upper limits are corrected for dust attenuation using the same A_V and attenuation law applied to detected lines:

F_ul,corr = F_ul × 10^(0.4 × A_lambda)

This ensures upper limits are on the same (intrinsic) flux scale as the detected line fluxes used for ionic abundances.

12.3 Doublet upper limits

For doublets where both members are undetected (e.g. N III] 1749+1752), the individual member upper limits are combined in quadrature:

F_ul,doublet = sqrt(F_ul,1^2 + F_ul,2^2)

This is the correct treatment for independent noise in each member, rather than linear summation which would overestimate the upper limit.

12.4 Ionic abundance upper limits

The flux upper limit is converted to an ionic abundance upper limit using the same emissivity-ratio formula as for detected lines (Section 5.1):

(X^i+/H+)_ul = (F_ul / F_Hbeta) × (epsilon_Hbeta / epsilon_line)

12.5 Abundance ratio upper limits

Upper limits on N/O and C/O are computed by summing detected ionic abundances with upper limits for non-detected ions, divided by total oxygen:

(N/O)_ul = (N_detected + N_upper_limits) / (O+ + O2+)
log(N/O)_ul = log10((N/O)_ul)

These are reported in the AbundanceResult.summary() output alongside the ionic upper limit details.

12.6 Fallback to fit errors

If the continuum-RMS method cannot be applied (e.g. the spectrum object is unavailable, or the residuals do not cover the line position), the pipeline falls back to the fit-error method:

F_ul = n_sigma × sqrt(sum(sigma_i^2))

where sigma_i are the per-member flux errors from bootstrap or MCMC. The ionic_ul_details dictionary records which method was used for each ion ("method": "continuum_rms" or "method": "fit_error").


13. References

Reference

Context

Aggarwal, K. M. & Keenan, F. P., 2004, A&A, 427, 763

N V effective collision strengths (CHIANTI v10)

Aller, L. H., 1984, Physics of Thermal Gaseous Nebulae (Reidel)

Hbeta Case B recombination formula for T_e > 30,000 K

Asplund, M. et al., 2009, ARA&A, 47, 481

Solar oxygen abundance: 12 + log(O/H)_sun = 8.69

Berg, D. A. et al., 2025, arXiv:2511.13591

Six-step UV nitrogen abundance procedure

Calzetti, D. et al., 2000, ApJ, 533, 682

Starburst attenuation curve (base for Salim+18)

Campbell, A., Terlevich, R. & Melnick, J., 1986, MNRAS, 223, 811

T_e–T_e relation: T_low = 0.7 × T_high + 3000

Cardelli, J. A., Clayton, G. C. & Mathis, J. S., 1989, ApJ, 345, 245

Milky Way extinction law

Cullen, F. et al., 2025, (EXCELS)

Bayesian forward model for emission-line abundances

DESI Collaboration, 2026, arXiv:2601.02463

Updated T_e–T_e relation: T_low = 0.648 × T_high + 3270

Garnett, D. R., 1992, AJ, 103, 1330

Classical T_e–T_e relations for intermediate/low zones

Garnett, D. R. et al., 1997, ApJ, 489, 63

C/O ionisation correction factor: ICF_C = (O+ + O++)/O++

Izotov, Y. I. et al., 2006, A&A, 448, 955

ICF equations 18–23 for N, Ne, S, Ar

Jones, T. et al., 2023

C/O from direct ionic sum: (C2+ + C3+) / O2+

Martinez, M. A., Berg, D. A. et al., 2025, arXiv:2510.21960

Density-dependent ICFs and log(U) diagnostics

Noll, S. et al., 2009, A&A, 499, 69

UV bump + slope modification to Calzetti curve

Osterbrock, D. E. & Ferland, G. J., 2006, Astrophysics of Gaseous Nebulae and Active Galactic Nuclei (University Science Books)

Case B recombination ratios

Salim, S. et al., 2018, ApJ, 859, 11

UV slope and bump calibration for dust attenuation

Sanders, R. L. et al., 2025

Strong-line metallicity calibrations (O3, O2, R23, O32)

Storey, P. J. & Hummer, D. G., 1995, MNRAS, 272, 41

H I recombination emissivity tables (valid to 30,000 K)


Appendix: Zone Assignment Summary

Ion

Lines

Zone

T_e

n_e

O2+

[OIII] 5007

High

T_high

n_e,high

O+

[OII] 3726+3729

Low

T_low

n_e,low

N+

[NII] 6585

Low

T_low

n_e,low

N2+

NIII] 1749+1752

High

T_high

n_e,high

N3+

NIV] 1483+1486

High

T_high

n_e,high

N4+

NV 1239+1243

High

T_high

n_e,high

C+

CII] 2324+2326

Low

T_low

n_e,low

C2+

CIII] 1907+1909

High

T_high

n_e,high

C3+

CIV 1548+1551

High

T_high

n_e,high

S+

[SII] 6718+6732

Low

T_low

n_e,low

S2+

[SIII] 9069

Mid

(T_high+T_low)/2

n_e,low

Ne2+

[NeIII] 3869

High

T_high

n_e,high

Ar2+

[ArIII] 7136

Mid

(T_high+T_low)/2

n_e,low