API#

The API is under active development and should be considered unstable. Feedback is welcomed.

emulator#

Precomputed synthetic spectral models are awesome but imperfect and rigid. Here we clone the most prominent spectral lines and continuum appearance of synthetic spectral models to turn them into tunable, flexible, semi-empirical models. We can ultimately learn the properties of the pre-computed models with a neural network training loop, and then transfer those weights to real data, where a second transfer-learning training step can take place. The spectrum has \(N_{\rm pix} \sim 300,000\) pixels and \(N_{\rm lines} \sim 5000\) spectral lines. The number of lines is set by the prominence= kwarg: lower produces more lines and higher (up to about 0.3) produces fewer lines.

blase.emulator.EchelleModel#

alias of ExtrinsicModel

class blase.emulator.ExtrinsicModel(wl_native, device=None)#

A Model for Extrinsic modulation

Parameters:
  • wl_native (float vector) – The native wavelength coordinates

  • device (Torch Device or str) – GPU or CPU?

forward(high_res_model)#

The forward pass of the data-based echelle model implementation

Computes the RV and vsini modulations of the native model:

\[\mathsf{S}_{\rm ext}(\lambda_S) = \mathsf{S}_{\rm clone}(\lambda_\mathrm{c} - \frac{RV}{c}\lambda_\mathrm{c}) * \zeta \left(\frac{v}{v\sin{i}}\right)\]
Parameters:

high_res_model (torch.tensor) – The high resolution model fluxes sampled at the native wavelength grid

Returns:

The high resolution model modulated for extrinsic parameters, \(\mathsf{S}_{\rm ext}\)

Return type:

torch.tensor

rotational_broaden(input_flux, vsini)#

Rotationally broaden the spectrum

Computes the convolution of the input flux with a Rotational Broadening kernel:

\[\mathsf{S}_{\rm clone} * \zeta \left(\frac{v}{v\sin{i}}\right)\]
Parameters:
  • input_flux (torch.tensor) – The input flux vector, sampled at the native wavelength grid

  • vsini (float scalar) – The rotational velocity in km/s

Returns:

The rotationally broadened flux vector

Return type:

torch.tensor

class blase.emulator.InstrumentalModel(wl_bin_edges, wl_native, device=None)#

A Model for instrumental resolution, etc (e.g. for a spectrograph)

Parameters:
  • wl_bin_edges (float vector) – The edges of the wavelength bins

  • wl_native (float vector) – The native wavelength coordinates

  • device (Torch Device or str) – GPU or CPU?

forward(high_res_model)#

The forward pass of the instrumental model

Computes the instrumental modulation of the joint model and resamples the spectrum to the coarse data wavelength coordinates.

We start with a joint model composed of the elementwise product of the extrinsic stellar spectrum with the resampled telluric spectrum:

\[\begin{split}\mathsf{M}_{\rm joint} = \mathsf{S}_{\rm ext} \odot \mathsf{T}(\lambda_S) \\\end{split}\]

An intermediate high resolution spectrum is computed by convolving the joint model with a Gaussian kernel, and weighting by a smooth polynomial shape:

\[\mathsf{M}_{\rm inst}(\lambda_S) = \mathsf{P} \odot \Big(\mathsf{M}_{\rm joint} * g(R) \Big)\]

Finally, we resample the intermediate high resolution instrumental spectrum to the coarser data wavelength coordinates:

\[\mathsf{M}(\lambda_D) = \text{resample} \Big[ \mathsf{M}_{\rm inst}(\lambda_S) \Big]\]
Parameters:

high_res_model (torch.tensor) – The high resolution model fluxes sampled at the native wavelength grid. The high resolution model is typically the joint model including the extrinsic spectrum and telluric spectrum, \(\mathsf{M}_{\rm joint}\). It can alternatively be a bare extrinisic spectrum, \(\mathsf{S}_{\rm ext}\) if telluric absorption is negligible in the wavelength range of interest.

Returns:

The high resolution model modulated for extrinsic parameters, and resampled at the data coordinates \(\mathsf{M}(\lambda_D)\).

Return type:

torch.tensor

instrumental_broaden(input_flux, sigma_angs)#

Instrumental broaden the spectrum

Parameters:
  • input_flux (torch.tensor) – The input flux vector to be broadened

  • sigma_angs (float scalar) – The spectral resolution sigma in Angstroms

Returns:

The instrumental broadened flux vector

Return type:

torch.tensor

resample_to_data(convolved_flux)#

Resample the high resolution model to the data wavelength sampling

warped_continuum()#

Warp the continuum by a smooth polynomial

class blase.emulator.LinearEmulator(wl_native, flux_native=None, prominence=None, init_state_dict=None)#

Model for cloning a precomputed synthetic spectrum in linear flux.

\(\mathsf{S} \mapsto \mathsf{S}_{\rm clone}\)

Parameters:
  • wl_native (torch.tensor) – The vector of input wavelengths at native resolution and sampling

  • flux_native (torch.tensor or None) – The vector of continuum-flattened input fluxes. If None, line-finding is skipped, init_state_dict is required, and the optimize method does not work.

  • prominence (int or None) – The threshold prominence for peak finding, defaults to 0.03. Ignored if init_state_dict is provided.

  • init_state_dict (dict) – A dictionary of model parameters to initialize the model with

detect_lines(wl_native, flux_native, prominence=0.03)#

Identify the spectral lines in the native model

Parameters:
  • wl_native (torch.tensor) – The 1D vector of native model wavelengths (Angstroms)

  • flux_native (torch.tensor) – The 1D vector of continuum-flattened model fluxes

Returns:

The wavelength centers, prominences, and widths for all ID’ed spectral lines

Return type:

tuple of tensors

forward(wl)#

The forward pass of the blase clone model

Conducts the product of PseudoVoigt profiles for each line, with between one and three tunable parameters. The entire spectrum can optionally be modulated by a tunable continuum polynomial.

\[\mathsf{S}_{\rm clone} = \mathsf{P}(\lambda_S) \prod_{j=1}^{N_{\mathrm{lines}}} 1-a_j \mathsf{V}_j(\lambda_S)\]
Parameters:

wl (torch.tensor) – The input wavelength \(\mathbf{\lambda}_S\) at which to evaluate the model

Returns:

The 1D generative spectral model clone \(\mathsf{S}_{\rm clone}\) destined for backpropagation parameter tuning

Return type:

torch.tensor

optimize()#

Optimize the model parameters

product_of_pseudovoigt_model(wl)#

Return the Product of pseudo-Voigt profiles

The product acts like a matrix contraction:

\[\prod_{j=1}^{N_{\mathrm{lines}}} 1-a_j \mathsf{V}_j(\lambda_S)\]
Parameters:

wl (torch.tensor) – The input wavelength \(\mathbf{\lambda}_S\) at which to evaluate the model

Returns:

The 1D generative spectral model clone \(\mathsf{S}_{\rm clone}\) destined for backpropagation parameter tuning

Return type:

torch.tensor

pseudo_voigt_profiles(wavelengths)#

Compute the pseudo-Voigt Profile for a collection of lines

Much faster than the exact Voigt profile, but not as accurate:

\[\mathsf{V}(\lambda_S-\lambda_{\mathrm{c},j}, \sigma_j, \gamma_j)\]
Parameters:

wavelengths (torch.tensor) – The 1D vector of wavelengths \(\mathbf{\lambda}_S\) at which to evaluate the model

Returns:

The 1D pseudo-Voigt profiles

Return type:

torch.tensor

Notes

The pseudo-Voigt [1] is an approximation to the convolution of a Lorentzian profile \(L(\lambda,f)\) and Gaussian profile \(G(\lambda,f)\)

\[V_p(\lambda,f) = \eta \cdot L(\lambda, f) + (1 - \eta) \cdot G(\lambda,f)\]

with mixture pre-factor:

\[\eta = 1.36603 (f_L/f) - 0.47719 (f_L/f)^2 + 0.11116(f_L/f)^3\]

and FWHM:

\[f = [f_G^5 + 2.69269 f_G^4 f_L + 2.42843 f_G^3 f_L^2 + 4.47163 f_G^2 f_L^3 + 0.07842 f_G f_L^4 + f_L^5]^{1/5}\]

References

blase.emulator.PhoenixEmulator#

alias of LinearEmulator

class blase.emulator.SparseLinearEmulator(wl_native, flux_native=None, prominence=None, device=None, wing_cut_pixels=None, init_state_dict=None)#

A sparse implementation of the LinearEmulator

Parameters:
  • wl_native (float vector) – The input wavelength at native sampling

  • flux_native (float vector) – The continuum-flattened flux at native sampling

  • prominence (int) – The threshold for detecting lines

  • device (Torch Device or str) – GPU or CPU?

  • wing_cut_pixels (int) – The number of pixels centered on the line center to evaluate in the sparse implementation, default: 1000 pixels

  • init_state_dict (dict) – A dictionary of model parameters to initialize the model with

forward()#

The forward pass of the sparse implementation— no wavelengths needed!

Returns:

The 1D generative spectral model destined for backpropagation

Return type:

torch.tensor

optimize(epochs=100, LR=0.01)#

Optimize the model parameters with backpropagation

Parameters:
  • epochs (int) – The number of epochs to run the optimization for

  • LR (float) – The learning rate for the optimizer

Return type:

None

sparse_gaussian_model()#

A sparse Gaussian-only model

Returns:

the 1D generative spectral model destined for backpropagation parameter tuning

Return type:

(torch.tensor)

sparse_pseudo_Voigt_model()#

A sparse pseudo-Voigt model

The sparse matrix \(\hat{F}\) is composed of the log flux values. Instead of a dense matrix \(\bar{F}\), the log fluxes are stored as trios of coordinate values and fluxes. \((i, j, \ln{F_{ji}})\). The computation proceeds as follows:

\[\mathsf{S}_{\rm clone} = \exp{\Big(\sum_{j=1}^{N_{lines}} \ln{F_{ji}} \Big)}\]
Returns:

The 1D generative sparse spectral model

Return type:

torch.tensor

class blase.emulator.SparseLogEmissionEmulator(wl_native, lnflux_native=None, prominence=None, device=None, wing_cut_pixels=None, init_state_dict=None)#

An emission line version of the sparse emulator

exact_sparse_opacity_model()#

A sparse pseudo-Voigt model with exact Voigt profiles

The sparse matrix \(\hat{F}\) is composed of the log flux values. Instead of a dense matrix \(\bar{F}\), the log fluxes are stored as trios of coordinate values and fluxes. \((i, j, \ln{F_{ji}})\). The computation proceeds as follows:

\[\mathsf{S}_{\rm clone} = \exp{\Big(-\sum_{j=1}^{N_{\mathrm{lines}}} a_j \mathsf{V}_j\Big)}\]
Returns:

The 1D generative sparse spectral model

Return type:

torch.tensor

sparse_opacity_model()#

A sparse pseudo-Voigt model

The sparse matrix \(\hat{F}\) is composed of the log flux values. Instead of a dense matrix \(\bar{F}\), the log fluxes are stored as trios of coordinate values and fluxes. \((i, j, \ln{F_{ji}})\). The computation proceeds as follows:

\[\mathsf{S}_{\rm clone} = \exp{\Big(-\sum_{j=1}^{N_{\mathrm{lines}}} a_j \mathsf{V}_j\Big)}\]
Returns:

The 1D generative sparse spectral model

Return type:

torch.tensor

class blase.emulator.SparseLogEmulator(wl_native, lnflux_native=None, prominence=None, device=None, wing_cut_pixels=None, init_state_dict=None)#

A log version of the sparse emulator

Parameters:
  • wl_native (float vector) – The input wavelength at native sampling

  • lnflux_native (float vector) – The natural log of the continuum-flattened flux at native sampling

  • prominence (int) – The threshold for detecting lines

  • device (Torch Device or str) – GPU or CPU?

  • wing_cut_pixels (int) – The number of pixels centered on the line center to evaluate in the sparse implementation, default: 1000 pixels

  • init_state_dict (dict) – The initial state of the model

exact_sparse_opacity_model()#

A sparse pseudo-Voigt model with exact Voigt profiles

The sparse matrix \(\hat{F}\) is composed of the log flux values. Instead of a dense matrix \(\bar{F}\), the log fluxes are stored as trios of coordinate values and fluxes. \((i, j, \ln{F_{ji}})\). The computation proceeds as follows:

\[\mathsf{S}_{\rm clone} = \exp{\Big(-\sum_{j=1}^{N_{\mathrm{lines}}} a_j \mathsf{V}_j\Big)}\]
Returns:

The 1D generative sparse spectral model

Return type:

torch.tensor

exact_voigt_profile(lam_center, sigma_width, gamma_width, wavelengths)#

The exact Voigt profile ported from exojax (Kawahara et al. 2022)

Returns:

The exact Voigt profile for

Return type:

torch.tensor

forward()#

The forward pass of the sparse implementation— no wavelengths needed!

Returns:

The 1D generative spectral model destined for backpropagation

Return type:

torch.tensor

hjert(x, a)#

custom JVP version of the Voigt-Hjerting function, consisting of a combination of rewofz and real(wofzs2).

Code is ported to pytorch from ExoJAX fadeeva.py # Kawahara et al. 2022: # http://arxiv.org/abs/2105.14782

Parameters:
  • x

  • a

Returns:

H(x,a) or Real(wofz(x+ia))

rewofz(x, y)#

Real part of wofz (Faddeeva) function based on Algorithm 916

We apply a=0.5 for Algorithm 916. Ported from exojax to PyTorch by gully

Parameters:

x – Torch tensor

Must be shape (N_lines x N_wl x 1)

y: Torch tensor

Must be shape (N_lines x 1 x 1)

Returns:

(N_wl x N_lines)

Return type:

Torch tensor

rewofzs2(x, y)#

Asymptotic representation of wofz (Faddeeva) function 1 for |z|**2 > 112 (for e = 10e-6) See Zaghloul (2018) arxiv:1806.01656

Code is ported to pytorch from ExoJAX fadeeva.py # Kawahara et al. 2022: # http://arxiv.org/abs/2105.14782

Parameters:
  • x

  • y

Returns:

H=real(wofz(x+iy)),L=imag(wofz(x+iy))

sparse_opacity_model()#

A sparse pseudo-Voigt model

The sparse matrix \(\hat{F}\) is composed of the log flux values. Instead of a dense matrix \(\bar{F}\), the log fluxes are stored as trios of coordinate values and fluxes. \((i, j, \ln{F_{ji}})\). The computation proceeds as follows:

\[\mathsf{S}_{\rm clone} = \exp{\Big(-\sum_{j=1}^{N_{\mathrm{lines}}} a_j \mathsf{V}_j\Big)}\]
Returns:

The 1D generative sparse spectral model

Return type:

torch.tensor

blase.emulator.SparsePhoenixEmulator#

alias of SparseLinearEmulator

blase.emulator.erfcx_naive(x)#

Erfcx based on erfc

utilities#

These general purpose methods are used in one or more other modules.

blase.utils.doppler_grid(lambda_0, lambda_max, velocity_resolution_kmps=0.5)#

Compute the exponential sampling interval for a given lambda_0 and velocity resolution.

telluric#

Telluric absorption forward modeling based on HITRAN

TelluricModel#

class blase.telluric.TelluricModel(device='cuda')#

Make a model of Earth’s atmospheric absorption and/or sky emission

Parameters:

device (str) – On which device to run the model, “cuda” or “cpu”

S_ij_of_T(T, S_ij_296, nu_ij, g_lower, E_lower)#

The Spectral Line Intensity as a function of temperature

\[S_{ij}(T) = S_{ij}(T_\mathrm{ref}) \frac{Q(T_\mathrm{ref})}{Q(T)} \frac{\exp\left( -c_2 E''/T \right)}{\exp\left( -c_2 E''/T_\mathrm{ref} \right)} \frac{[1-\exp\left( -c_2 \nu_{ij}/T \right)]}{[1-\exp\left(-c_2 \nu_{ij}/T_\mathrm{ref} \right)]}\]
Parameters:
  • T (float) – Temperature \(T\) in K

  • S_ij_296 (float) – The spectral line intensity at \(T_{ref}=296\) K

  • nu_ij (float) – Wavenumber of the spectral line transition \((\mathrm{cm^{-1}})\) in vacuum

  • g_lower (float) – The lower state statistical weights \(g''\)

  • E_lower (float) – The lower-state energy of the transition \(\mathrm{cm^{-1}}\)

Returns:

A vector of length \(N_{\mathrm{lines}}\)

Return type:

torch.Tensor

forward()#

The forward pass of the neural network

gamma_of_p_and_T(p, T, p_self, n_air, gamma_air_ref, gamma_self_ref)#

Compute the Lorentz half width at half maximum (HWHM) in units of \(\mathrm{cm^{-1}}\) with pressure and temperature:

\[\gamma(p, T) = \left( \frac{T_\mathrm{ref}}{T} \right)^{n_\mathrm{air}}\left( \gamma_\mathrm{air}(p_\mathrm{ref}, T_\mathrm{ref})(p-p_\mathrm{self}) + \gamma_\mathrm{self}(p_\mathrm{ref}, T_\mathrm{ref})p_\mathrm{self}\right)\]
Parameters:
  • p (float) – Pressure \(p\) in standard atmospheres atm

  • T (float) – Temperature \(T\) in K

  • p_self (float) – Partial pressure of the species in atm

  • n_air (float) – The coefficient of the temperature dependence of the air-broadened half width (dimensionless)

  • gamma_air_ref (float) – The air-broadened HWHM at \(T_{ref}=296\;\) K and reference pressure \(p_{ref}=1\;\) atm

  • gamma_self_ref (float) – The self-broadened HWHM at \(T_{ref}=296\;\) K and reference pressure \(p_{ref}=1\;\) atm

Returns:

A vector of length \(N_{\mathrm{lines}}\)

Return type:

torch.Tensor

get_hapi_molec_data(species)#

Fetch HITRAN atomic and molecular data as torch tensors

Parameters:

species (str) – Which atomic/molecular species to examine

Returns:

A dictionary containing tensors of size \(N_{\mathrm{lines}}\)

for each of the 8 HITRAN columns of interest

Return type:

dict

lorentz_profile(nu, p, nu_ij, gamma, dp_ref, S_ij)#

Return the Lorentz line profile given vectors and parameters

\[f_\mathrm{L}(\nu; \nu_{ij}, T, p) = \frac{1}{\pi}\frac{\gamma(p,T)}{\gamma(p,T)^2 + [\nu-(\nu_{ij} + \delta(p_\mathrm{ref})p)]^2}\]
Parameters:
  • nu (float) – Wavenumber variable input \(\nu\) in \(\mathrm{cm^{-1}}\). For matrix output, nu should have shape \(N_{\lambda} \times 1\).

  • p (float) – Pressure \(p\) in standard atmospheres atm

  • nu_ij (float) – Wavenumber of the spectral line transition \((\mathrm{cm^{-1}})\) in vacuum

  • gamma (float) – Lorentz half width at half maximum (HWHM), \(\gamma\) in units of \(\mathrm{cm^{-1}}\)

  • dp_ref (float) – The pressure shift \(\mathrm{cm^{-1}/atm}\) at \(T_{ref}=296\) K and \(p_{ref} = 1\) atm of the line position with respect to the vacuum transition wavenumber \(\nu_{ij}\)

  • S_ij (float) – The spectral line intensity \(\mathrm{cm^{-1}/(molecule·cm^{-2}})\)

Returns:

Either a vector of length \(N_\lambda\) if \(\gamma\) is a scalar, or a matrix of size \(N_\lambda \times N_{lines}\) if \(\gamma\) is a vector

Return type:

torch.Tensor

tips_Q_of_T(T, g_k, E_k)#

Total Internal Partition Sum

\[Q(T) = \sum_k g_k \exp\left(-\frac{c_2E_k}{T}\right)\]
Parameters:
  • T (float) – Temperature \(T\) in K

  • g_k (float) – The lower state statistical weights \(g_k\)

  • E_k (float) – The lower-state energy of the transition \(\mathrm{cm^{-1}}\)

Returns:

A scalar or a vector the same length as T

Return type:

torch.Tensor

transmission_multilayer_atmosphere(T_vector, p_vector, nus, vol_mix_ratio, hitran)#

Return the transmission spectrum \(\mathcal{T}(\nu; T, P)=\exp(-\tau_\nu)\) for a cascade of \(N_{layers}\) pathlengths with thickness 1 km.

Parameters:
  • T_vector (\(1 \times 1 \times N_{layers}\) tensor) – Temperature \(T\) in K

  • p_vector (\(1 \times 1 \times N_{layers}\) tensor) – Pressure \(p\) in standard atmospheres atm

  • nus (\(N_{\nu} \times 1 \times 1\) tensor) – Wavenumber variable input \(\nu\) in \(\mathrm{cm^{-1}}\).

  • vol_mix_ratio (scalar or \(1 \times 1 \times N_{layers}\) tensor) – The volume mixing ratio of the species assuming ideal gas

  • hitran (OrderedDict) – Each entry of consists of a \(N_{lines}\) vector that will be broadcasted to a \(1 \times N_{lines} \times 1\) tensor when operating with the other vectors.

Returns:

A vector of length \(N_{\nu}\)

Return type:

torch.Tensor

transmission_of_T_p(T, p, nus, vol_mix_ratio, hitran)#

Return the transmission spectrum \(\mathcal{T}(\nu; T, P)=\exp(-\tau_\nu)\) for 1 km of pathlength

Parameters:
  • T (float) – Temperature \(T\) in K

  • p (float) – Pressure \(p\) in standard atmospheres atm

  • nus (float) – Wavenumber variable input \(\nu\) in \(\mathrm{cm^{-1}}\).

  • vol_mix_ratio (float) – The volume mixing ratio of the species assuming ideal gas

Returns:

A vector of length \(N_{\nu}\)

Return type:

torch.Tensor