bayes_cn_hfs

Submodules

bayes_cn_hfs.cn_model

cn_model.py CNModel definition

Copyright(C) 2024 by Trey V. Wenger; tvwenger@gmail.com This code is licensed under MIT license (see LICENSE for details)

class bayes_cn_hfs.cn_model.CNModel(*args, molecule: str = 'CN', mol_data: dict | None = None, bg_temp: float = 2.7, Beff: float = 1.0, Feff: float = 1.0, **kwargs)

Bases: BaseModel

Definition of the CNModel.

Attributes:
baseline_deterministics

Get the deterministic baseline parameter names.

baseline_freeRVs

Get the free baseline parameter names.

cloud_deterministics

Get the deterministic cloud parameter names.

cloud_freeRVs

Get the free cloud parameter names.

hyper_deterministics

Get the deterministic hyper parameter names.

hyper_freeRVs

Get the free hyper parameter names.

labeller

Get the arviz labeller.

unique_solution

Check if posterior samples suggest a unique solution.

Methods

add_baseline_priors([prior_baseline_coeffs])

Add baseline priors to the model.

add_likelihood()

Add likelihood to the model.

add_priors([prior_log10_N, ...])

Add priors and deterministics to the model

bic([chain, solution])

Calculate the Bayesian information criterion at the mean point estimate.

fit([n, draws, rel_tolerance, ...])

Approximate posterior distribution using Variational Inference (VI).

graph()

Generate visualization of the model graph.

mean_lnlike([chain, solution])

Evaluate mean log-likelihood over posterior samples.

null_bic()

Evaluate the Bayesian Information Criterion for the null hypothesis (baseline only, no clouds)

predict_baseline([baseline_params])

Predict the un-normalized baseline model.

reset_results()

Reset results and convergence checks.

sample([init, n_init, chains, init_kwargs, ...])

Sample posterior distribution using MCMC.

sample_posterior_predictive([solution, thin])

Generate posterior predictive samples

sample_prior_predictive([samples])

Generate prior predictive samples

sample_smc(**kwargs)

Sample posterior distribution using Sequential Monte Carlo.

solve(**kwargs)

Identify unique solutions and break the labeling degeneracy.

add_likelihood()

Add likelihood to the model. SpecData key must be “observation”.

add_priors(prior_log10_N: Iterable[float] = [13.5, 1.0], prior_log10_Tkin: Iterable[float] = [1.0, 0.5], prior_velocity: Iterable[float] = [0.0, 10.0], prior_fwhm_nonthermal: float = 0.0, prior_fwhm_L: float | None = None, prior_rms: dict[str, float] | None = None, prior_baseline_coeffs: dict[str, Iterable[float]] | None = None, assume_LTE: bool = True, prior_log10_Tex: Iterable[float] = [1.0, 0.5], assume_CTEX: bool = True, prior_log10_LTE_precision: float = [-6.0, 1.0], fix_log10_Tkin: float | None = None, clip_weights: float | None = 1e-09, clip_tau: float | None = -10.0, ordered: bool = False)

Add priors and deterministics to the model

Parameters:
prior_log10_NIterable[float], optional

Prior distribution on total column density over all lower and upper states, by default [13.5, 1.0], where log10_N ~ Normal(mu=prior[0], sigma=prior[1])

prior_log10_TkinIterable[float], optional

Prior distribution on log10 cloud kinetic temperature (K), by default [1.0, 0.5], where log10_Tkin ~ Normal(mu=prior[0], sigma=prior[1])

prior_velocityIterable[float], optional

Prior distribution on centroid velocity (km s-1), by default [0.0, 10.0], where velocity ~ Normal(mu=prior[0], sigma=prior[1])

prior_fwhm_nonthermalfloat, optional

Prior distribution on non-thermal FWHM (km s-1), by default 0.0, where fwhm_nonthermal ~ HalfNormal(sigma=prior_fwhm_nonthermal) If 0.0, assume no non-thermal broadening.

prior_fwhm_LOptional[float], optional

Prior distribution on the pseudo-Voight Lorentzian profile line width (km/s), by default None, where fwhm_L ~ HalfNormal(sigma=prior_fwhm_L) If None, the line profile is assumed Gaussian.

prior_rmsOptional[dict[str, float]], optional

Prior distribution on spectral rms (K), by default None, where rms ~ HalfNormal(sigma=prior) Keys are dataset names and values are priors. If None, then the spectral rms is taken from dataset.noise and not inferred.

prior_baseline_coeffsOptional[dict[str, Iterable[float]]], optional

Prior distribution on the normalized baseline polynomial coefficients, by default None. Keys are dataset names and values are lists of length baseline_degree+1. If None, use [1.0]*(baseline_degree+1) for each dataset.

assume_LTEbool, optional

Assume local thermodynamic equilibrium by fixing the average excitation temperature to the cloud kinetic temperature, by default True.

prior_log10_TexIterable[float], optional

Prior distribution on log10 average excitation temperature (K), by default [1.5, 0.5], where log10_Tex ~ Normal(mu=prior[0], sigma=prior[1]) This parameter has no effect when assume_LTE = True. Otherwise, it characterizes either the CTEX excitation temperature (if assume_CTEX = True) or the “average” excitation temperature over all states (if assume_CTEX = False).

assume_CTEXbool, optional

Assume that every transition has the same excitation temperature, by default True.

prior_log10_LTE_precisionIterable[float], optional

Prior distribution on the state column density departures from LTE, by default [-6.0, 1.0], where log10_LTE_precision ~ prior[0] + HalfNormal(sigma=prior[1]) stat_weights ~ Dirichlet(a=LTE_stat_weights/LTE_precision)

fix_log10_TkinOptional[float], optional

Fix the log10 cloud kinetic temperature at this value (K), by default None.

clip_weightsOptional[float], optional

Clip weights between [clip, 1.0-clip], by default 1.0e-9

clip_tauOptional[float], optional

Clip masers by truncating optical depths below this value, by default -10.0

orderedbool, optional

If True, assume ordered velocities (optically thin assumption), by default False. If True, the prior distribution on the velocity becomes velocity(cloud = n) ~

prior[0] + sum_i(velocity[i < n]) + Gamma(alpha=2.0, beta=1.0/prior[1])

bayes_cn_hfs.cn_ratio_model

cn_ratio_model.py CNRatioModel definition

Copyright(C) 2024 by Trey V. Wenger; tvwenger@gmail.com This code is licensed under MIT license (see LICENSE for details)

class bayes_cn_hfs.cn_ratio_model.CNRatioModel(*args, mol_data_12CN: dict | None = None, mol_data_13CN: dict | None = None, bg_temp: float = 2.7, Beff: float = 1.0, Feff: float = 1.0, **kwargs)

Bases: BaseModel

Definition of the CNRatioModel.

Attributes:
baseline_deterministics

Get the deterministic baseline parameter names.

baseline_freeRVs

Get the free baseline parameter names.

cloud_deterministics

Get the deterministic cloud parameter names.

cloud_freeRVs

Get the free cloud parameter names.

hyper_deterministics

Get the deterministic hyper parameter names.

hyper_freeRVs

Get the free hyper parameter names.

labeller

Get the arviz labeller.

unique_solution

Check if posterior samples suggest a unique solution.

Methods

add_baseline_priors([prior_baseline_coeffs])

Add baseline priors to the model.

add_likelihood()

Add likelihood to the model.

add_priors([prior_log10_N_12CN, ...])

Add priors and deterministics to the model

bic([chain, solution])

Calculate the Bayesian information criterion at the mean point estimate.

fit([n, draws, rel_tolerance, ...])

Approximate posterior distribution using Variational Inference (VI).

graph()

Generate visualization of the model graph.

mean_lnlike([chain, solution])

Evaluate mean log-likelihood over posterior samples.

null_bic()

Evaluate the Bayesian Information Criterion for the null hypothesis (baseline only, no clouds)

predict_baseline([baseline_params])

Predict the un-normalized baseline model.

reset_results()

Reset results and convergence checks.

sample([init, n_init, chains, init_kwargs, ...])

Sample posterior distribution using MCMC.

sample_posterior_predictive([solution, thin])

Generate posterior predictive samples

sample_prior_predictive([samples])

Generate prior predictive samples

sample_smc(**kwargs)

Sample posterior distribution using Sequential Monte Carlo.

solve(**kwargs)

Identify unique solutions and break the labeling degeneracy.

add_likelihood()

Add likelihood to the model. SpecData key must be “observation”.

add_priors(prior_log10_N_12CN: Iterable[float] = [13.5, 1.0], prior_ratio_13C_12C: float = 0.1, prior_log10_Tkin: Iterable[float] = [1.0, 0.5], prior_velocity: Iterable[float] = [0.0, 10.0], prior_fwhm_nonthermal: float = 0.0, prior_fwhm_L: float | None = None, prior_rms: dict[str, float] | None = None, prior_baseline_coeffs: dict[str, Iterable[float]] | None = None, assume_LTE: bool = True, prior_log10_Tex: Iterable[float] = [1.0, 0.5], assume_CTEX_12CN: bool = True, prior_log10_LTE_precision: float = [-6.0, 1.0], assume_CTEX_13CN: bool = True, fix_log10_Tkin: float | None = None, clip_weights: float | None = 1e-09, clip_tau: float | None = -10.0, ordered: bool = False)

Add priors and deterministics to the model

Parameters:
prior_log10_N_12CNIterable[float], optional

Prior distribution on total CN column density over all lower and upper states, by default [13.5, 1.0], where log10_N_12CN ~ Normal(mu=prior[0], sigma=prior[1])

prior_ratio_13C_12Cfloat, optional

Prior distribution on 13C/12C ratio, by default 0.1, where ratio_13C_12C ~ HalfNormal(sigma=prior)

prior_log10_TkinIterable[float], optional

Prior distribution on log10 cloud kinetic temperature (K), by default [1.0, 0.5], where log10_Tkin ~ Normal(mu=prior[0], sigma=prior[1])

prior_velocityIterable[float], optional

Prior distribution on centroid velocity (km s-1), by default [0.0, 10.0], where velocity ~ Normal(mu=prior[0], sigma=prior[1])

prior_fwhm_nonthermalfloat, optional

Prior distribution on non-thermal FWHM (km s-1), by default 0.0, where fwhm_nonthermal ~ HalfNormal(sigma=prior_fwhm_nonthermal) If 0.0, assume no non-thermal broadening.

prior_fwhm_LOptional[float], optional

Prior distribution on the pseudo-Voight Lorentzian profile line width (km/s), by default None, where fwhm_L ~ HalfNormal(sigma=prior_fwhm_L) If None, the line profile is assumed Gaussian.

prior_rmsOptional[dict[str, float]], optional

Prior distribution on spectral rms (K), by default None, where rms ~ HalfNormal(sigma=prior) Keys are dataset names and values are priors. If None, then the spectral rms is taken from dataset.noise and not inferred.

prior_baseline_coeffsOptional[dict[str, Iterable[float]]], optional

Width of normal prior distribution on the normalized baseline polynomial coefficients. Keys are dataset names and values are lists of length baseline_degree+1. If None, use [1.0]*(baseline_degree+1) for each dataset, by default None

assume_LTEbool, optional

Assume local thermodynamic equilibrium by fixing the average excitation temperature to the cloud kinetic temperature, by default True.

prior_log10_TexIterable[float], optional

Prior distribution on log10 average excitation temperature (K), by default [1.5, 0.5], where log10_Tex ~ Normal(mu=prior[0], sigma=prior[1]) This parameter has no effect when assume_LTE = True. Otherwise, it characterizes either the CTEX excitation temperature (if assume_CTEX_12CN = True or assume_CTEX_13CN = True) or the “average” excitation temperature over all states (if assume_CTEX_12CN = False or assume_CTEX_13CN = False).

assume_CTEX_12CNbool, optional

Assume that every 12CN transition has the same excitation temperature, by default True.

prior_log10_LTE_precisionIterable[float], optional

Prior distribution on the state column density departures from LTE, by default [-6.0, 1.0], where log10_LTE_precision ~ prior[0] + HalfNormal(sigma=prior[1]) stat_weights ~ Dirichlet(a=LTE_stat_weights/LTE_precision)

assume_CTEX_13CNbool, optional

Assume that every 13CN transition has the same excitation temperature, by default True.

fix_log10_TkinOptional[float], optional

Fix the log10 cloud kinetic temperature at this value (K), by default None.

clip_weightsOptional[float], optional

Clip weights between [clip, 1.0-clip], by default 1.0e-9

clip_tauOptional[float], optional

Clip masers by truncating optical depths below this value, by default -10.0

orderedbool, optional

If True, assume ordered velocities (optically thin assumption), by default False. If True, the prior distribution on the velocity becomes velocity(cloud = n) ~

prior[0] + sum_i(velocity[i < n]) + Gamma(alpha=2.0, beta=1.0/prior[1])

bayes_cn_hfs.physics

physics.py Hyperfine physics

Copyright(C) 2024 by Trey V. Wenger; tvwenger@gmail.com This code is licensed under MIT license (see LICENSE for details)

bayes_cn_hfs.physics.calc_TR(freq: float, boltz_factor: float) float

Evaluate the radiation temperature (AKA Rayleigh-Jeans equivalent temperature, AKA brightness temperature). Note that we do not assume the R-J limit here.

Parameters:
freqfloat

frequency (MHz)

boltz_factorfloat

Boltzmann factor

Returns:
float

Radiation temperature (AKA brightness temperature, K)

bayes_cn_hfs.physics.calc_Tex(freq: float, boltz_factor: float) float

Evaluate the excitation temperature from a given Boltzmann factor.

Parameters:
freqfloat

Frequency (MHz)

boltz_factorfloat

Boltzmann factor = exp(-h*freq/(k*Tex))

Returns:
float

Excitation temperature

bayes_cn_hfs.physics.calc_boltz_factor(freq: float, Tex: float) float

Evaluate the Boltzmann factor from a given excitation temperature. B = Nu*gl/(Nl*gu) = exp(-h*freq/(k*Tex))

Parameters:
freqfloat

Frequency (MHz)

Texfloat

Excitation temperature (K)

Returns:
float

Boltzmann factor

bayes_cn_hfs.physics.calc_frequency(freq: float, velocity: float) float

Apply the Doppler equation to calculate the frequency in the same frame as the velocity.

Parameters:
freqfloat

Frequencies. Output has same units.

velocityfloat

Velocity (km/s)

Returns:
float

Radio-defined Doppler frequency

bayes_cn_hfs.physics.calc_fwhm_freq(freq: float, fwhm: float) float

Calculate the FWHM line width in frequency units

Parameters:
freqfloat

Frequencies. Output has same units.

fwhmfloat

FWHM line width (km/s) in velocity units (length C)

Returns:
float

FWHM line width (MHz) in frequency units (shape C x N)

bayes_cn_hfs.physics.calc_optical_depth(freq: float, gl: float, gu: float, Nl: float, Nu: float, Aul: float, line_profile: float) float

Evaluate the total optical depth assuming a homogeneous medium. This is the integral of the absorption coefficient (Condon & Ransom eq. 7.55)

Parameters:
freq: float

Transition frequency (MHz)

gl: float

Lower state degeneracy

gufloat

Upper state degeneracy

Nlfloat

Lower state column density (cm-2)

Nufloat

Upper state column density (cm-2)

Aulfloat

Einstein A coefficient (s-1)

line_profilefloat

Line profile (MHz-1). Pass 1.0 to get the integrated optical depth.

Returns:
float

Total optical depth

bayes_cn_hfs.physics.calc_pseudo_voigt(freq_axis: Iterable[float], frequency: Iterable[float], fwhm: Iterable[float], fwhm_L: Iterable[float]) Iterable[float]

Evaluate a pseudo Voight profile in order to aid in posterior exploration of the parameter space. This parameterization includes a latent variable fwhm_L, which can be conditioned on zero to analyze the posterior. We also consider the spectral channelization. We do not perform a full boxcar convolution, rather we approximate the convolution by assuming an equivalent FWHM for the boxcar kernel of 4 ln(2) / pi * channel_width ~= 0.88 * channel_width

Parameters:
freq_axisIterable[float]

Observed frequency axis (MHz length S)

frequencyIterable[float]

Cloud center frequency (MHz length C x N)

fwhmIterable[float]

Cloud FWHM line widths (MHz length C x N)

fwhm_LIterable[float]

Latent pseudo-Voigt profile Lorentzian FWHM (MHz length C)

Returns:
Iterable[float]

Line profile (MHz-1; shape S x C x N)

bayes_cn_hfs.physics.calc_stat_weight(g: float, E: float, Tex: float) float

Evaluate the statistical weight for a given excitation temperature.

Parameters:
gfloat

Degeneracy

Efloat

Energy relative to ground state / k_B (K)

Texfloat

Excitation temperature (K)

Returns:
float

statistical weight g * exp(-E/(k*Tex))

bayes_cn_hfs.physics.calc_thermal_fwhm(kinetic_temp: float, weight: float) float

Calculate the thermal line broadening assuming a Maxwellian velocity distribution (Condon & Ransom eq. 7.35)

Parameters:
kinetic_tempfloat

Kinetic temperature (K)

weightfloat

Molecular weight (number of nucleii)

Returns:
float

Thermal FWHM line width (km/s)

bayes_cn_hfs.physics.gaussian(x: float, center: float, fwhm: float) float

Evaluate a normalized Gaussian function

Parameters:
xfloat

Position at which to evaluate

centerfloat

Gaussian centroid

fwhmfloat

Gaussian FWHM line width

Returns:
float

Gaussian evaluated at x

bayes_cn_hfs.physics.lorentzian(x: float, center: float, fwhm: float) float

Evaluate a normalized Lorentzian function

Parameters:
xfloat

Position at which to evaluate

centerfloat

Centroid

fwhmfloat

FWHM

Returns:
float

Lorentzian evaluated at x

bayes_cn_hfs.physics.predict_tau_spectra(mol_data: dict, freq_axis: Iterable[float], tau: Iterable[float], velocity: Iterable[float], fwhm: Iterable[float], fwhm_L: float) Iterable[float]

Predict the optical depth spectra from model parameters.

Parameters:
mol_datadict

Dictionary of molecular data returned by utils.get_molecule_data mol_data[‘freq’] contains C-length array of transition frequencies

freq_axisIterable[float]

Observed frequency axis (MHz length S)

tauIterable[float]

Total optical depth of each transition (shape C x N)

velocityIterable[float]

Velocity (km s-1) (length N)

fwhmIterable[float]

FWHM line width (km s-1) (length N)

fwhm_Lfloat

Latent pseudo-Voigt profile Lorentzian FWHM (km s-1)

Returns:
Iterable[float]

Predicted optical depth spectra (shape S x C x N)

bayes_cn_hfs.physics.radiative_transfer(freq_axis: Iterable[float], tau: Iterable[float], TR: Iterable[float], bg_temp: float) Iterable[float]

Evaluate the radiative transfer to predict the emission spectrum. The emission spectrum is ON - OFF, where ON includes the attenuated emission of the background and the clouds, and the OFF is the emission of the background. Order of N clouds is assumed to be [nearest, …, farthest]. The emission spectum is the Rayleigh-Jeans equivalent temperature, AKA the brightness temperature.

Parameters:
freq_axisfloat

Frequency axis (MHz) (length S)

tauIterable[float]

Optical depth spectra (shape S x C x N)

TRIterable[float]

Radiation temperature; shape: C x N)

bg_tempfloat

Assumed background temperature

Returns:
Iterable[float]

Predicted emission Rayleigh-Jeans equivalent temperature (AKA brightness temperature) spectrum (K) (length S)

bayes_cn_hfs.utils

utils.py Hyperfine utilities

Copyright(C) 2024 by Trey V. Wenger; tvwenger@gmail.com This code is licensed under MIT license (see LICENSE for details)

bayes_cn_hfs.utils.get_molecule_data(molecule: str, fmin: float = 0.0, fmax: float = 10000.0, vibrational_state: int | None = None, rot_state_lower: int | None = None) dict

Get molecular transition data from the JPL database. Lifted heavily from pyspeckit’s get_molecular_parameters.

Parameters:
moleculestr

Molecule name

fminfloat, optional

Minimum frequency (GHz), by default 0.0

fmaxfloat, optional

Maximum frequency (GHz), by default 10000.0

vibrational_stateOptional[int], optional

For CN, limit to this vibrational state, which is assumed to be the second quantum number returned by JPLSpec, by default None

rot_state_lowerOptional[int], optional

For CN or 13CN, limit to this lower rotational state, which is assumed to be the first quantum number returned by JPLSpec, by default None

Returns:
dict

Molecular transition data, with keys: “freq” (Iterable[float]) : Rest frequencies (MHz) “Aul” (Iterable[float]) : Einstein A coefficients (s-1) “degu” (Iterable[float]) : Upper state degeneracies “Eu” (Iterable[float]) : Upper state energies (erg) “relative_int” (Iterable[float]) : Relative intensities “log10_Q_terms” (Iterable[float]) : Polynomial coefficients for logQ vs. logT (K)

Raises:
ValueError

Molecule not found in JPLSpec database

bayes_cn_hfs.utils.supplement_mol_data(molecule, mol_data: dict | None = None)

Add states and degeneracy information to mol_data

Parameters:
moleculestr

Either “CN” or “13CN”

mol_dataOptional[dict], optional

Molecular data dictionary returned by get_molecule_data(). If None, it will be downloaded. Default is None

Returns:
dict

Molecular data dictionary returned by get_molecule_data and populated with additional fields

float

Molecular weight (number of nucleii)

Module contents

class bayes_cn_hfs.CNModel(*args, molecule: str = 'CN', mol_data: dict | None = None, bg_temp: float = 2.7, Beff: float = 1.0, Feff: float = 1.0, **kwargs)

Bases: BaseModel

Definition of the CNModel.

Attributes:
baseline_deterministics

Get the deterministic baseline parameter names.

baseline_freeRVs

Get the free baseline parameter names.

cloud_deterministics

Get the deterministic cloud parameter names.

cloud_freeRVs

Get the free cloud parameter names.

hyper_deterministics

Get the deterministic hyper parameter names.

hyper_freeRVs

Get the free hyper parameter names.

labeller

Get the arviz labeller.

unique_solution

Check if posterior samples suggest a unique solution.

Methods

add_baseline_priors([prior_baseline_coeffs])

Add baseline priors to the model.

add_likelihood()

Add likelihood to the model.

add_priors([prior_log10_N, ...])

Add priors and deterministics to the model

bic([chain, solution])

Calculate the Bayesian information criterion at the mean point estimate.

fit([n, draws, rel_tolerance, ...])

Approximate posterior distribution using Variational Inference (VI).

graph()

Generate visualization of the model graph.

mean_lnlike([chain, solution])

Evaluate mean log-likelihood over posterior samples.

null_bic()

Evaluate the Bayesian Information Criterion for the null hypothesis (baseline only, no clouds)

predict_baseline([baseline_params])

Predict the un-normalized baseline model.

reset_results()

Reset results and convergence checks.

sample([init, n_init, chains, init_kwargs, ...])

Sample posterior distribution using MCMC.

sample_posterior_predictive([solution, thin])

Generate posterior predictive samples

sample_prior_predictive([samples])

Generate prior predictive samples

sample_smc(**kwargs)

Sample posterior distribution using Sequential Monte Carlo.

solve(**kwargs)

Identify unique solutions and break the labeling degeneracy.

add_likelihood()

Add likelihood to the model. SpecData key must be “observation”.

add_priors(prior_log10_N: Iterable[float] = [13.5, 1.0], prior_log10_Tkin: Iterable[float] = [1.0, 0.5], prior_velocity: Iterable[float] = [0.0, 10.0], prior_fwhm_nonthermal: float = 0.0, prior_fwhm_L: float | None = None, prior_rms: dict[str, float] | None = None, prior_baseline_coeffs: dict[str, Iterable[float]] | None = None, assume_LTE: bool = True, prior_log10_Tex: Iterable[float] = [1.0, 0.5], assume_CTEX: bool = True, prior_log10_LTE_precision: float = [-6.0, 1.0], fix_log10_Tkin: float | None = None, clip_weights: float | None = 1e-09, clip_tau: float | None = -10.0, ordered: bool = False)

Add priors and deterministics to the model

Parameters:
prior_log10_NIterable[float], optional

Prior distribution on total column density over all lower and upper states, by default [13.5, 1.0], where log10_N ~ Normal(mu=prior[0], sigma=prior[1])

prior_log10_TkinIterable[float], optional

Prior distribution on log10 cloud kinetic temperature (K), by default [1.0, 0.5], where log10_Tkin ~ Normal(mu=prior[0], sigma=prior[1])

prior_velocityIterable[float], optional

Prior distribution on centroid velocity (km s-1), by default [0.0, 10.0], where velocity ~ Normal(mu=prior[0], sigma=prior[1])

prior_fwhm_nonthermalfloat, optional

Prior distribution on non-thermal FWHM (km s-1), by default 0.0, where fwhm_nonthermal ~ HalfNormal(sigma=prior_fwhm_nonthermal) If 0.0, assume no non-thermal broadening.

prior_fwhm_LOptional[float], optional

Prior distribution on the pseudo-Voight Lorentzian profile line width (km/s), by default None, where fwhm_L ~ HalfNormal(sigma=prior_fwhm_L) If None, the line profile is assumed Gaussian.

prior_rmsOptional[dict[str, float]], optional

Prior distribution on spectral rms (K), by default None, where rms ~ HalfNormal(sigma=prior) Keys are dataset names and values are priors. If None, then the spectral rms is taken from dataset.noise and not inferred.

prior_baseline_coeffsOptional[dict[str, Iterable[float]]], optional

Prior distribution on the normalized baseline polynomial coefficients, by default None. Keys are dataset names and values are lists of length baseline_degree+1. If None, use [1.0]*(baseline_degree+1) for each dataset.

assume_LTEbool, optional

Assume local thermodynamic equilibrium by fixing the average excitation temperature to the cloud kinetic temperature, by default True.

prior_log10_TexIterable[float], optional

Prior distribution on log10 average excitation temperature (K), by default [1.5, 0.5], where log10_Tex ~ Normal(mu=prior[0], sigma=prior[1]) This parameter has no effect when assume_LTE = True. Otherwise, it characterizes either the CTEX excitation temperature (if assume_CTEX = True) or the “average” excitation temperature over all states (if assume_CTEX = False).

assume_CTEXbool, optional

Assume that every transition has the same excitation temperature, by default True.

prior_log10_LTE_precisionIterable[float], optional

Prior distribution on the state column density departures from LTE, by default [-6.0, 1.0], where log10_LTE_precision ~ prior[0] + HalfNormal(sigma=prior[1]) stat_weights ~ Dirichlet(a=LTE_stat_weights/LTE_precision)

fix_log10_TkinOptional[float], optional

Fix the log10 cloud kinetic temperature at this value (K), by default None.

clip_weightsOptional[float], optional

Clip weights between [clip, 1.0-clip], by default 1.0e-9

clip_tauOptional[float], optional

Clip masers by truncating optical depths below this value, by default -10.0

orderedbool, optional

If True, assume ordered velocities (optically thin assumption), by default False. If True, the prior distribution on the velocity becomes velocity(cloud = n) ~

prior[0] + sum_i(velocity[i < n]) + Gamma(alpha=2.0, beta=1.0/prior[1])

class bayes_cn_hfs.CNRatioModel(*args, mol_data_12CN: dict | None = None, mol_data_13CN: dict | None = None, bg_temp: float = 2.7, Beff: float = 1.0, Feff: float = 1.0, **kwargs)

Bases: BaseModel

Definition of the CNRatioModel.

Attributes:
baseline_deterministics

Get the deterministic baseline parameter names.

baseline_freeRVs

Get the free baseline parameter names.

cloud_deterministics

Get the deterministic cloud parameter names.

cloud_freeRVs

Get the free cloud parameter names.

hyper_deterministics

Get the deterministic hyper parameter names.

hyper_freeRVs

Get the free hyper parameter names.

labeller

Get the arviz labeller.

unique_solution

Check if posterior samples suggest a unique solution.

Methods

add_baseline_priors([prior_baseline_coeffs])

Add baseline priors to the model.

add_likelihood()

Add likelihood to the model.

add_priors([prior_log10_N_12CN, ...])

Add priors and deterministics to the model

bic([chain, solution])

Calculate the Bayesian information criterion at the mean point estimate.

fit([n, draws, rel_tolerance, ...])

Approximate posterior distribution using Variational Inference (VI).

graph()

Generate visualization of the model graph.

mean_lnlike([chain, solution])

Evaluate mean log-likelihood over posterior samples.

null_bic()

Evaluate the Bayesian Information Criterion for the null hypothesis (baseline only, no clouds)

predict_baseline([baseline_params])

Predict the un-normalized baseline model.

reset_results()

Reset results and convergence checks.

sample([init, n_init, chains, init_kwargs, ...])

Sample posterior distribution using MCMC.

sample_posterior_predictive([solution, thin])

Generate posterior predictive samples

sample_prior_predictive([samples])

Generate prior predictive samples

sample_smc(**kwargs)

Sample posterior distribution using Sequential Monte Carlo.

solve(**kwargs)

Identify unique solutions and break the labeling degeneracy.

add_likelihood()

Add likelihood to the model. SpecData key must be “observation”.

add_priors(prior_log10_N_12CN: Iterable[float] = [13.5, 1.0], prior_ratio_13C_12C: float = 0.1, prior_log10_Tkin: Iterable[float] = [1.0, 0.5], prior_velocity: Iterable[float] = [0.0, 10.0], prior_fwhm_nonthermal: float = 0.0, prior_fwhm_L: float | None = None, prior_rms: dict[str, float] | None = None, prior_baseline_coeffs: dict[str, Iterable[float]] | None = None, assume_LTE: bool = True, prior_log10_Tex: Iterable[float] = [1.0, 0.5], assume_CTEX_12CN: bool = True, prior_log10_LTE_precision: float = [-6.0, 1.0], assume_CTEX_13CN: bool = True, fix_log10_Tkin: float | None = None, clip_weights: float | None = 1e-09, clip_tau: float | None = -10.0, ordered: bool = False)

Add priors and deterministics to the model

Parameters:
prior_log10_N_12CNIterable[float], optional

Prior distribution on total CN column density over all lower and upper states, by default [13.5, 1.0], where log10_N_12CN ~ Normal(mu=prior[0], sigma=prior[1])

prior_ratio_13C_12Cfloat, optional

Prior distribution on 13C/12C ratio, by default 0.1, where ratio_13C_12C ~ HalfNormal(sigma=prior)

prior_log10_TkinIterable[float], optional

Prior distribution on log10 cloud kinetic temperature (K), by default [1.0, 0.5], where log10_Tkin ~ Normal(mu=prior[0], sigma=prior[1])

prior_velocityIterable[float], optional

Prior distribution on centroid velocity (km s-1), by default [0.0, 10.0], where velocity ~ Normal(mu=prior[0], sigma=prior[1])

prior_fwhm_nonthermalfloat, optional

Prior distribution on non-thermal FWHM (km s-1), by default 0.0, where fwhm_nonthermal ~ HalfNormal(sigma=prior_fwhm_nonthermal) If 0.0, assume no non-thermal broadening.

prior_fwhm_LOptional[float], optional

Prior distribution on the pseudo-Voight Lorentzian profile line width (km/s), by default None, where fwhm_L ~ HalfNormal(sigma=prior_fwhm_L) If None, the line profile is assumed Gaussian.

prior_rmsOptional[dict[str, float]], optional

Prior distribution on spectral rms (K), by default None, where rms ~ HalfNormal(sigma=prior) Keys are dataset names and values are priors. If None, then the spectral rms is taken from dataset.noise and not inferred.

prior_baseline_coeffsOptional[dict[str, Iterable[float]]], optional

Width of normal prior distribution on the normalized baseline polynomial coefficients. Keys are dataset names and values are lists of length baseline_degree+1. If None, use [1.0]*(baseline_degree+1) for each dataset, by default None

assume_LTEbool, optional

Assume local thermodynamic equilibrium by fixing the average excitation temperature to the cloud kinetic temperature, by default True.

prior_log10_TexIterable[float], optional

Prior distribution on log10 average excitation temperature (K), by default [1.5, 0.5], where log10_Tex ~ Normal(mu=prior[0], sigma=prior[1]) This parameter has no effect when assume_LTE = True. Otherwise, it characterizes either the CTEX excitation temperature (if assume_CTEX_12CN = True or assume_CTEX_13CN = True) or the “average” excitation temperature over all states (if assume_CTEX_12CN = False or assume_CTEX_13CN = False).

assume_CTEX_12CNbool, optional

Assume that every 12CN transition has the same excitation temperature, by default True.

prior_log10_LTE_precisionIterable[float], optional

Prior distribution on the state column density departures from LTE, by default [-6.0, 1.0], where log10_LTE_precision ~ prior[0] + HalfNormal(sigma=prior[1]) stat_weights ~ Dirichlet(a=LTE_stat_weights/LTE_precision)

assume_CTEX_13CNbool, optional

Assume that every 13CN transition has the same excitation temperature, by default True.

fix_log10_TkinOptional[float], optional

Fix the log10 cloud kinetic temperature at this value (K), by default None.

clip_weightsOptional[float], optional

Clip weights between [clip, 1.0-clip], by default 1.0e-9

clip_tauOptional[float], optional

Clip masers by truncating optical depths below this value, by default -10.0

orderedbool, optional

If True, assume ordered velocities (optically thin assumption), by default False. If True, the prior distribution on the velocity becomes velocity(cloud = n) ~

prior[0] + sum_i(velocity[i < n]) + Gamma(alpha=2.0, beta=1.0/prior[1])

bayes_cn_hfs.get_molecule_data(molecule: str, fmin: float = 0.0, fmax: float = 10000.0, vibrational_state: int | None = None, rot_state_lower: int | None = None) dict

Get molecular transition data from the JPL database. Lifted heavily from pyspeckit’s get_molecular_parameters.

Parameters:
moleculestr

Molecule name

fminfloat, optional

Minimum frequency (GHz), by default 0.0

fmaxfloat, optional

Maximum frequency (GHz), by default 10000.0

vibrational_stateOptional[int], optional

For CN, limit to this vibrational state, which is assumed to be the second quantum number returned by JPLSpec, by default None

rot_state_lowerOptional[int], optional

For CN or 13CN, limit to this lower rotational state, which is assumed to be the first quantum number returned by JPLSpec, by default None

Returns:
dict

Molecular transition data, with keys: “freq” (Iterable[float]) : Rest frequencies (MHz) “Aul” (Iterable[float]) : Einstein A coefficients (s-1) “degu” (Iterable[float]) : Upper state degeneracies “Eu” (Iterable[float]) : Upper state energies (erg) “relative_int” (Iterable[float]) : Relative intensities “log10_Q_terms” (Iterable[float]) : Polynomial coefficients for logQ vs. logT (K)

Raises:
ValueError

Molecule not found in JPLSpec database

bayes_cn_hfs.supplement_mol_data(molecule, mol_data: dict | None = None)

Add states and degeneracy information to mol_data

Parameters:
moleculestr

Either “CN” or “13CN”

mol_dataOptional[dict], optional

Molecular data dictionary returned by get_molecule_data(). If None, it will be downloaded. Default is None

Returns:
dict

Molecular data dictionary returned by get_molecule_data and populated with additional fields

float

Molecular weight (number of nucleii)