# Ammonia Models¶

The Ammonia modeling tools include a set of constants in the ammonia_constants module and the following ammonia modeling tools listed below.

There is also an ammonia fitter wrapper; see Wrappers.

Note that there are two modules described here: the multi-rotational-transition fitter, which has its own set of custom functions, and a generic hyperfine-line fitting module meant to fit a single metastable (or non-metastable) transition.

If you run into a problem, have a look at the ammonia-tagged issues on github

Note that the default ammonia spectrum, with only the CMB as a background, is intentionally restricted to be positive to avoid nonphysical (absorption against the CMB) parameters. If you find your spectral fits sometimes returning errors about a negative spectrum, you may need the ‘restricted excitation temperature’ model. In this model, the excitation temperature is no longer a free parameter, but instead is set to trot + deltat, where deltat is a positive value. The only difference from the main ammonia model is this restriction, which can result in more numerically stable results. An example can be found in the examples directory

Ammonia inversion transition TROT fitter translated from Erik Rosolowsky’s https://github.com/low-sky/nh3fit

## Module API¶

pyspeckit.spectrum.models.ammonia.ammonia(xarr, trot=20, tex=None, ntot=14, width=1, xoff_v=0.0, fortho=0.0, tau=None, fillingfraction=None, return_tau=False, return_tau_profile=False, background_tb=2.7315, verbose=False, return_components=False, debug=False, line_names=['oneone', 'twotwo', 'threethree', 'fourfour', 'fivefive', 'sixsix', 'sevenseven', 'eighteight', 'ninenine'], ignore_neg_models=False)[source] [github] [bitbucket]

Generate a model Ammonia spectrum based on input temperatures, column, and gaussian parameters. The returned model will be in Kelvin (brightness temperature) units.

Note that astropy units are not used internally for performance reasons. A wrapped version of this module including those units would be a good idea, as it is definitely possible to implement this with unit support and good performance.

Parameters: xarr: pyspeckit.spectrum.units.SpectroscopicAxis : Array of wavelength/frequency values trot: float : The rotational temperature of the lines. This is the excitation temperature that governs the relative populations of the rotational states. tex: float or None : Excitation temperature. Assumed LTE if unspecified (None) or if tex>trot. This is the excitation temperature for all of the modeled lines, which means we are explicitly assuming T_ex is the same for all lines. ntot: float : Total log column density of NH3. Can be specified as a float in the range 5-25 width: float : Line width (Gaussian sigma) in km/s xoff_v: float : Line offset in km/s fortho: float : Fraction of NH3 molecules in ortho state. Default assumes all para (fortho=0). tau: None or float : If tau (optical depth in the 1-1 line) is specified, ntot is NOT fit but is set to a fixed value. The optical depths of the other lines are fixed relative to tau_oneone fillingfraction: None or float : fillingfraction is an arbitrary scaling factor to apply to the model return_tau: bool : Return a dictionary of the optical depths in each line instead of a synthetic spectrum return_tau_profile: bool : Return a dictionary of the optical depth profiles in each line, i.e., the optical depths that will be used in conjunction with T_ex to produce the synthetic spectrum return_components: bool : Return a list of arrays, one for each hyperfine component, instead of just one array background_tb : float The background brightness temperature. Defaults to TCMB. ignore_neg_models: bool : Normally if background=TCMB and the model is negative, an exception will be raised. This parameter will simply skip that exception. Use with extreme caution: negative models (absorption spectra against the CMB) are not physical! You may want to allow this in some cases because there can be numerical issues where the model goes negative when it shouldn’t. verbose: bool : More messages debug: bool : For debugging. spectrum: numpy.ndarray : Synthetic spectrum with same shape as xarr component_list: list : List of numpy.ndarray’s, one for each hyperfine component tau_dict: dict : Dictionary of optical depth values for the various lines (if return_tau is set)
class pyspeckit.spectrum.models.ammonia.ammonia_model(npeaks=1, npars=6, parnames=['trot', 'tex', 'ntot', 'width', 'xoff_v', 'fortho'], **kwargs)[source] [github] [bitbucket]
The basic Ammonia (NH3) model with 6 free parameters:
Trot, Tex, ntot, width, xoff_v, and fortho

Trot is the rotational temperature. It governs the relative populations of the rotational states, i.e., the relative strength of different transitions

Tex is the excitation temperature. It is assumed constant across all states, which is not always a good assumption - a radiative transfer and excitation model is required to constrain this, though.

ntot is the total column density of p-NH3 integrated over all states.

width is the linewidth (the Gaussian sigma)

xoff_v is the velocity offset / line of sight velocity

fortho is the ortho fraction (northo / (northo+npara))

annotations()[source] [github] [bitbucket]

Return a list of TeX-formatted labels

The values and errors are formatted so that only the significant digits are displayed. Rounding is performed using the decimal package.

Parameters: shortvarnames : list A list of variable names (tex is allowed) to include in the annotations. Defaults to self.shortvarnames

Examples

>>> # Annotate a Gaussian
>>> sp.specfit.annotate(shortvarnames=['A','\Delta x','\sigma'])

components(xarr, pars, hyperfine=False, return_hyperfine_components=False, **kwargs)[source] [github] [bitbucket]

Ammonia components don’t follow the default, since in Galactic astronomy the hyperfine components should be well-separated. If you want to see the individual components overlaid, you’ll need to pass hyperfine to the plot_fit call

moments(Xax, data, negamp=None, veryverbose=False, **kwargs)[source] [github] [bitbucket]

Returns a very simple and likely incorrect guess

multinh3fit(xax, data, err=None, parinfo=None, quiet=True, shh=True, debug=False, maxiter=200, use_lmfit=False, veryverbose=False, **kwargs)[source] [github] [bitbucket]

Fit multiple nh3 profiles (multiple can be 1)

Parameters: xax : array x axis data : array y axis npeaks : int How many nh3 profiles to fit? Default 1 (this could supersede onedgaussfit) err : array error corresponding to data params : list Fit parameters: [trot, tex, ntot (or tau), width, offset, ortho fraction] * npeaks If len(params) % 6 == 0, npeaks will be set to len(params) / 6. These parameters (and the related fixed, limited, min/max, names below) need to have length = 6*npeaks. If npeaks > 1 and length = 6, they will be replicated npeaks times, otherwise they will be reset to defaults: fixed : list Is parameter fixed? limitedmin : list minpars : list set lower limits on each parameter (default: width>0, Tex and trot > Tcmb) limitedmax : list maxpars : list set upper limits on each parameter parnames : list default parameter names, important for setting kwargs in model [‘trot’,’tex’,’ntot’,’width’,’xoff_v’,’fortho’] quiet : bool should MPFIT output each iteration? shh : bool output final parameters? mpp : model parameter object Fit parameters model : array The model array errors : array the fit errors chi2 : float the chi^2 value of the fit
n_ammonia(pars=None, parnames=None, **kwargs)[source] [github] [bitbucket]

Returns a function that sums over N ammonia line profiles, where N is the length of trot,tex,ntot,width,xoff_v,fortho OR N = len(pars) / 6

The background “height” is assumed to be zero (you must “baseline” your spectrum before fitting)

pars [ list ]
a list with len(pars) = (6-nfixed)n, assuming trot,tex,ntot,width,xoff_v,fortho repeated
parnames [ list ]
len(parnames) must = len(pars). parnames determine how the ammonia function parses the arguments
parse_3par_guesses(guesses)[source] [github] [bitbucket]

Try to convert a set of interactive guesses (peak, center, width) into guesses appropriate to the model.

For NH3 models, we add in several extra parameters:
tex = 2.73 * peak trot = tex * 2 fortho = 0.5 ntot = 15

ntot is set to a constant ~10^15 because this results in optical depths near 1, so it forces the emission to be approximately significant. trot > tex so that we’re in a physical regime to begin with.

We assume tex = peak + 2.73 because most spectra are shown background-subtracted (single dish are always that way, interferometric data are intrinsically that way…) and otherwise the guessing will crash if you guess a number < 2.73.

class pyspeckit.spectrum.models.ammonia.ammonia_model_background(**kwargs)[source] [github] [bitbucket]
moments(Xax, data, negamp=None, veryverbose=False, **kwargs)[source] [github] [bitbucket]

Returns a very simple and likely incorrect guess

multinh3fit(xax, data, npeaks=1, err=None, params=(20, 20, 14, 1.0, 0.0, 0.5, 2.7315), parnames=None, fixed=(False, False, False, False, False, False, True), limitedmin=(True, True, True, True, False, True, True), limitedmax=(False, False, False, False, False, True, True), minpars=(2.7315, 2.7315, 0, 0, 0, 0, 2.7315), parinfo=None, maxpars=(0, 0, 0, 0, 0, 1, 2.7315), tied=('', '', '', '', '', '', ''), quiet=True, shh=True, veryverbose=False, **kwargs)[source] [github] [bitbucket]

Fit multiple nh3 profiles (multiple can be 1)

Parameters: xax : array x axis data : array y axis npeaks : int How many nh3 profiles to fit? Default 1 (this could supersede onedgaussfit) err : array error corresponding to data params : list Fit parameters: [trot, tex, ntot (or tau), width, offset, ortho fraction] * npeaks If len(params) % 6 == 0, npeaks will be set to len(params) / 6. These parameters (and the related fixed, limited, min/max, names below) need to have length = 6*npeaks. If npeaks > 1 and length = 6, they will be replicated npeaks times, otherwise they will be reset to defaults: fixed : list Is parameter fixed? limitedmin : list minpars : list set lower limits on each parameter (default: width>0, Tex and trot > Tcmb) limitedmax : list maxpars : list set upper limits on each parameter parnames : list default parameter names, important for setting kwargs in model [‘trot’,’tex’,’ntot’,’width’,’xoff_v’,’fortho’] quiet : bool should MPFIT output each iteration? shh : bool output final parameters? mpp : model parameter object Fit parameters model : array The model array errors : array the fit errors chi2 : float the chi^2 value of the fit
class pyspeckit.spectrum.models.ammonia.ammonia_model_restricted_tex(parnames=['trot', 'tex', 'ntot', 'width', 'xoff_v', 'fortho', 'delta'], ammonia_func=<function ammonia>, **kwargs)[source] [github] [bitbucket]

Ammonia model with an explicitly restricted excitation temperature such that tex <= trot, set by the “delta” parameter (tex = trot - delta) with delta > 0. You can choose the ammonia funciton when you initialize it (e.g., ammonia_model_restricted_tex(ammonia_func=ammonia) or ammonia_model_restricted_tex(ammonia_func=cold_ammonia))

make_parinfo(params=(20, 20, 0.5, 1.0, 0.0, 0.5, 0), fixed=(False, False, False, False, False, False, False), limitedmin=(True, True, True, True, False, True, True), limitedmax=(False, False, False, False, False, True, False), minpars=(2.7315, 2.7315, 0, 0, 0, 0, 0), maxpars=(0, 0, 0, 0, 0, 1, 0), tied=('', 'p[0]-p[6]', '', '', '', '', ''), **kwargs)[source] [github] [bitbucket]

parnames=[‘trot’, ‘tex’, ‘ntot’, ‘width’, ‘xoff_v’, ‘fortho’, ‘delta’]

‘delta’ is the difference between tex and trot

n_ammonia(pars=None, parnames=None, **kwargs)[source] [github] [bitbucket]

Returns a function that sums over N ammonia line profiles, where N is the length of trot,tex,ntot,width,xoff_v,fortho OR N = len(pars) / 6

The background “height” is assumed to be zero (you must “baseline” your spectrum before fitting)

pars [ list ]
a list with len(pars) = (6-nfixed)n, assuming trot,tex,ntot,width,xoff_v,fortho repeated
parnames [ list ]
len(parnames) must = len(pars). parnames determine how the ammonia function parses the arguments
class pyspeckit.spectrum.models.ammonia.ammonia_model_vtau(parnames=['trot', 'tex', 'tau', 'width', 'xoff_v', 'fortho'], **kwargs)[source] [github] [bitbucket]
make_parinfo(params=(20, 14, 0.5, 1.0, 0.0, 0.5), fixed=(False, False, False, False, False, False), limitedmin=(True, True, True, True, False, True), limitedmax=(False, False, False, False, False, True), minpars=(2.7315, 2.7315, 0, 0, 0, 0), maxpars=(0, 0, 0, 0, 0, 1), tied=('', '', '', '', '', ''), **kwargs)[source] [github] [bitbucket]

parnames=[‘trot’, ‘tex’, ‘tau’, ‘width’, ‘xoff_v’, ‘fortho’]

moments(Xax, data, negamp=None, veryverbose=False, **kwargs)[source] [github] [bitbucket]

Returns a very simple and likely incorrect guess

class pyspeckit.spectrum.models.ammonia.ammonia_model_vtau_thin(parnames=['tkin', 'tau', 'width', 'xoff_v', 'fortho'], **kwargs)[source] [github] [bitbucket]
make_parinfo(params=(20, 14, 1.0, 0.0, 0.5), fixed=(False, False, False, False, False), limitedmin=(True, True, True, False, True), limitedmax=(False, False, False, False, True), minpars=(2.7315, 0, 0, 0, 0), maxpars=(0, 0, 0, 0, 1), tied=('', '', '', '', ''), **kwargs)[source] [github] [bitbucket]

parnames=[‘trot’, ‘tex’, ‘tau’, ‘width’, ‘xoff_v’, ‘fortho’]

moments(Xax, data, negamp=None, veryverbose=False, **kwargs)[source] [github] [bitbucket]

Returns a very simple and likely incorrect guess

pyspeckit.spectrum.models.ammonia.ammonia_thin(xarr, tkin=20, tex=None, ntot=14, width=1, xoff_v=0.0, fortho=0.0, tau=None, return_tau=False, **kwargs)[source] [github] [bitbucket]

Use optical depth in the 1-1 line as a free parameter The optical depths of the other lines are then set by the kinetic temperature

tkin is used to compute trot assuming a 3-level system consisting of (1,1), (2,1), and (2,2) as in Swift et al, 2005 [2005ApJ…620..823S]

pyspeckit.spectrum.models.ammonia.cold_ammonia(xarr, tkin, **kwargs)[source] [github] [bitbucket]

Generate a model Ammonia spectrum based on input temperatures, column, and gaussian parameters

Parameters: xarr: pyspeckit.spectrum.units.SpectroscopicAxis : Array of wavelength/frequency values tkin: float : The kinetic temperature of the lines in K. Will be converted to rotational temperature following the scheme of Swift et al 2005 (http://esoads.eso.org/abs/2005ApJ…620..823S, eqn A6) and further discussed in Equation 7 of Rosolowsky et al 2008 (http://adsabs.harvard.edu/abs/2008ApJS..175..509R)
class pyspeckit.spectrum.models.ammonia.cold_ammonia_model(parnames=['tkin', 'tex', 'ntot', 'width', 'xoff_v', 'fortho'], **kwargs)[source] [github] [bitbucket]

## Ammonia inversion transition: Hyperfine-only fitter¶

### Module API¶

pyspeckit.spectrum.models.ammonia_hf.nh3_vtau_multimodel_generator(linenames)[source] [github] [bitbucket]

If you want to use multiple hyperfines for the same spectrum, use this generator. It is useful if you want N independent tau/tex values but the same velocity and linewidth

Parameters: linenames : list A list of line names from the set (‘oneone’, …, ‘eighteight’) model : model.SpectralModel A SpectralModel class build from N different metastable inversion hyperfine models