Note
Go to the end to download the full example code.
Combining Configurations¶
Three patterns for assembling unite configurations in code rather than
by hand. No fitting is performed — see the NIRSpec and Generic tutorials
for the full inference workflow.
Imports¶
import astropy.units as u
from unite import prior
from unite.line.config import FWHM, Flux, LineConfiguration, Redshift
Pattern 1 — + (strict merge)¶
Use + when every token name across both configs is distinct.
It calls merge(strict=True) under the hood and raises if any token
names collide — the safe default that prevents accidental sharing.
Here we model blue and red arms of a spectrograph with independent kinematics: each arm gets its own redshift and FWHM.
See Line Configuration for the full token and merging reference, and Priors for available prior types.
z_blue = Redshift('z_blue', prior=prior.Uniform(-0.003, 0.003))
fwhm_blue = FWHM('fwhm_blue', prior=prior.Uniform(50, 500))
lc_blue = LineConfiguration()
for name, wl in {'Ha': 6564.61 * u.AA, 'NII_6585': 6585.27 * u.AA}.items():
lc_blue.add_line(
name, wl, profile='Gaussian', redshift=z_blue, fwhm_gauss=fwhm_blue
)
z_red = Redshift('z_red', prior=prior.Uniform(-0.003, 0.003))
fwhm_red = FWHM('fwhm_red', prior=prior.Uniform(50, 500))
lc_red = LineConfiguration()
for name, wl in {'Hb': 4862.68 * u.AA, 'OIII_5008': 5008.24 * u.AA}.items():
lc_red.add_line(name, wl, profile='Gaussian', redshift=z_red, fwhm_gauss=fwhm_red)
lc_independent = lc_blue + lc_red
print(lc_independent)
LineConfiguration: 4 lines, 4 flux / 2 z / 2 profile params
Name Wavelength Profile Redshift Params Flux/Tau zorder Strength
--------- ---------------- -------- -------- -------------------- -------------- ------ --------
Ha 6564.61 Angstrom Gaussian z_z_blue fwhm_gauss_fwhm_blue flux_Ha 0 1.00
NII_6585 6585.27 Angstrom Gaussian z_z_blue fwhm_gauss_fwhm_blue flux_NII_6585 0 1.00
Hb 4862.68 Angstrom Gaussian z_z_red fwhm_gauss_fwhm_red flux_Hb 0 1.00
OIII_5008 5008.24 Angstrom Gaussian z_z_red fwhm_gauss_fwhm_red flux_OIII_5008 0 1.00
Redshift:
z_z_blue Uniform(low=-0.003, high=0.003)
z_z_red Uniform(low=-0.003, high=0.003)
Params (fwhm_gauss):
fwhm_gauss_fwhm_blue Uniform(low=50.0, high=500.0)
fwhm_gauss_fwhm_red Uniform(low=50.0, high=500.0)
Flux:
flux_Ha Uniform(low=-3.0, high=3.0)
flux_NII_6585 Uniform(low=-3.0, high=3.0)
flux_Hb Uniform(low=-3.0, high=3.0)
flux_OIII_5008 Uniform(low=-3.0, high=3.0)
Pattern 3 — loops for survey targets¶
Build the configuration once, then reuse it across all targets in a loop.
The redshift prior is a relative offset from the systemic redshift passed
to Spectra at fit time — the config itself is target-independent.
See Building the Model for how Spectra consumes the config and
filters lines by wavelength coverage.
TARGETS = {'Example-001': 0.12, 'Example-002': 1.87, 'Example-003': 6.78}
LINES = {
'Ha': 6564.61 * u.AA,
'Hb': 4862.68 * u.AA,
'OIII_5008': 5008.24 * u.AA,
'NII_6585': 6585.27 * u.AA,
}
z_s = Redshift('z', prior=prior.Uniform(-0.005, 0.005))
fwhm_s = FWHM('fwhm', prior=prior.Uniform(50, 500))
survey_config = LineConfiguration()
for name, wl in LINES.items():
survey_config.add_line(
name, wl, profile='Gaussian', redshift=z_s, fwhm_gauss=fwhm_s
)
for target, z_sys in TARGETS.items():
n = len(list(survey_config))
print(f'{target} z={z_sys:.2f} → {n} lines configured')
# At fit time:
#
# for target, z_sys in TARGETS.items():
# spectra = Spectra([load_spectrum(target)], redshift=z_sys)
# filtered_lines, filtered_cont = spectra.prepare(survey_config, cc)
# samples, model_args = ModelBuilder(filtered_lines, filtered_cont, spectra).fit()
Example-001 z=0.12 → 4 lines configured
Example-002 z=1.87 → 4 lines configured
Example-003 z=6.78 → 4 lines configured
Total running time of the script: (0 minutes 0.005 seconds)