Overview

There are two basic kinds of spectra in synphot, those with and without flux units. The former is used to construct Source Spectrum and Observation, while the latter for Bandpass, extinction curve, and Thermal. In the center of them all are Astropy models, which are used to represent the data, to create composite spectra, and to evaluate the results.

For simplicity and to be consistent with ASTROLIB PYSYNPHOT, a spectrum object stores its wavelength internally in Angstrom. A source spectrum stores flux in PHOTLAM, while a unitless spectrum stores throughput as dimensionless_unscaled. Despite this, most of the functionalities in synphot are unit-aware; i.e., you can pass in Quantity and specify the desired output units via optional keywords (see relevant API documentation).

File I/O in synphot is handled by its specio module, which uses Astropy FITS and Astropy ASCII, but read (both FITS and ASCII) and write (FITS only) spectrum data in a way that is backward-compatible with ASTROLIB PYSYNPHOT. In most cases, this module does not need to be accessed directly, but rather via from_file() and to_fits() methods of a spectrum object.

synphot and Astropy Models

Note

The interactions between synphot and astropy.models might change in the future as the latter support more features, such as Quantity. When that happens, the existing API will issue deprecation warnings, where appropriate.

synphot takes advantage of the analytical nature of Astropy models, except for tabular data, which are interpolated using Scipy. This is very different from ASTROLIB PYSYNPHOT that relied heavily on interpolation of internal lookup tables. But similar to ASTROLIB PYSYNPHOT, each individual model that goes into a compound (composite) model is stored separately and the final result is only calculated on evaluation. For simplicity, only 1D models and single model set (n_models=1) are supported.

At the time that this package was developed, some features needed for spectra manipulation were not (yet) available in Astropy models (e.g., Quantity parameters and sampleset that provides an array of values that best samples the model). In addition, some models (e.g., Empirical1D) are simply too specialized for our use case to be in Astropy. For those reasons, models exists to bridge that gap. For instance, a synphot.models.Gaussian1D is just like astropy.modeling.functional_models.Gaussian1D but with the extra sampleset. Still, some models can be used straight from Astropy (e.g., PowerLaw1D where sampleset is infinite, thus does not apply).

The following table lists the models allowed to be used for spectrum construction (with flux unit or unitless), where they reside, and special notes:

Model Package Notes
BlackBody1D synphot Calculate flux in PHOTLAM per steradian.
BlackBodyNorm1D synphot Calculate flux in PHOTLAM.
Box1D synphot Like astropy.modeling.functional_models.Box1D but with sampleset.
BrokenPowerLaw1D Astropy Flux handling might be incorrect unless amplitude is in PHOTLAM when creating a source spectrum using this model.
Const1D Astropy Flux handling might be incorrect unless amplitude is in PHOTLAM when creating a source spectrum using this model.
ConstFlux1D synphot Constant flux in a given unit might not be constant in other flux units. This handles flux unit conversion properly.
Empirical1D synphot Like Tabular1D but with extra features specific to spectrum (e.g., option to keep negative flux) and different default values.
ExponentialCutoffPowerLaw1D Astropy Flux handling might be incorrect unless amplitude is in PHOTLAM when creating a source spectrum using this model.
Gaussian1D synphot Like astropy.modeling.functional_models.Gaussian1D but with sampleset.
GaussianAbsorption1D synphot Like astropy.modeling.functional_models.GaussianAbsorption1D but with sampleset.
GaussianFlux1D synphot Like Gaussian1D but allows backward-compatible parameters like total flux and FWHM.
LogParabola1D Astropy Flux handling might be incorrect unless amplitude is in PHOTLAM when creating a source spectrum using this model.
Lorentz1D synphot Like astropy.modeling.functional_models.Lorentz1D but with sampleset and bounding_box.
MexicanHat1D synphot Like astropy.modeling.functional_models.MexicanHat1D but with sampleset and bounding_box.
PowerLaw1D Astropy Flux handling might be incorrect unless amplitude is in PHOTLAM when creating a source spectrum using this model.
PowerLawFlux1D synphot Like PowerLaw1D but handles flux unit conversion properly by evaluating in user flux unit instead of internal unit of PHOTLAM.
Trapezoid1D synphot Like astropy.modeling.functional_models.Trapezoid1D but with sampleset.

Spectrum Arithmetic

When spectrum objects are added to, subtracted from, multiplied with, or divided by each other, the resultant spectrum contains a compound model derived from the operands. If the operands themselves also contain compound models, then the final compound model is a compound of the input compound models.

Operations that do not make sense (e.g., multiplying two source spectra or adding a bandpass to a source spectrum) are prohibited. The type of output spectrum depends on the operation. In the table below, unitless spectrum can be a bandpass or extinction curve:

Operand 1 Operation Operand 2 Result Commutative
Source Spectrum \(+\) Source Spectrum Source Spectrum Yes
Source Spectrum \(-\) Source Spectrum Source Spectrum No
Source Spectrum \(\times\) Unitless Spectrum Source Spectrum Yes
Source Spectrum \(\times\) Scalar number Source Spectrum Yes
Source Spectrum \(\times\) Unitless Quantity Source Spectrum No
Source Spectrum \(/\) Source Spectrum Unitless Spectrum No
Source Spectrum \(/\) Unitless Spectrum Source Spectrum No
Source Spectrum \(/\) Scalar number Source Spectrum No
Source Spectrum \(/\) Unitless Quantity Source Spectrum No
Unitless Spectrum \(\times\) Unitless Spectrum Unitless Spectrum Yes
Unitless Spectrum \(\times\) Scalar number Unitless Spectrum Yes
Unitless Spectrum \(\times\) Unitless Quantity Unitless Spectrum No
Unitless Spectrum \(/\) Unitless Spectrum Unitless Spectrum No
Unitless Spectrum \(/\) Scalar number Unitless Spectrum No
Unitless Spectrum \(/\) Unitless Quantity Unitless Spectrum No

Quick Guide

The tables below summarize some main functionality of synphot. The variables, where appropriate, can be numbers (assumed to be in certain units) or Quantity. These are only for quick reference. Detailed explanations are available in their respective sections in the other parts of this document.

Create Bandpass

Description Command
Load from file. bp = SpectralElement.from_file(filename)
Load pre-defined bandpass. bp = SpectralElement.from_filter(filtername)
Create from wavelength and throughput arrays. bp = SpectralElement(Empirical1D, points=wavelength, lookup_table=throughput)
Box centered at mu with given width. bp = SpectralElement(Box1D, x_0=mu, width=width)
Create from tapering existing bandpass. bp2 = bp.taper()

Calculate Bandpass Parameters

Description Command
Average wavelength and associated throughput.

bp.avgwave()

bp.tlambda()

Peak throughput and associated wavelength.

bp.tpeak()

bp.wpeak()

Dimensionless efficiency. bp.efficiency()
Equivalent width. bp.equivwidth()
Rectangular width. bp.rectwidth()
RMS band width as in Koornneef et al. 1986 (page 836). bp.rmswidth()
RMS band width as in IRAF SYNPHOT. bp.photbw()
FWHM of equiv. Gaussian. bp.fwhm()
Pivot wavelength. bp.pivot()
Mean log wavelength. bp.barlam()
Unit response; flux that produces 1 count/s in the bandpass, for given telescope area. bp.unit_response(area)
Equiv. monochromatic flux. bp.emflx(area)
Check if bandpass fully overlaps a source spectrum. bp.check_overlap(sp)

Create Other Unitless Spectrum

Description Command
Reddening law from extinction model. Creation using Astropy model and from file also possible but not shown. redlaw = ReddeningLaw.from_extinction_model( extinction_model_name)
Extinction curve from reddening law at given \(E(B-V)\) extcurve = redlaw.extinction_curve(ebv)
Extinction for Lyman-alpha extcurve = etau_madau(wave, z)
Bandpass with thermal properties (from model). thbp = ThermalSpectralElement(modelclass, temperature, **kwargs)
Bandpass with thermal properties (from file). thbp = ThermalSpectralElement.from_file( filename)

Create Source Spectrum

Description Command
Load from file. sp = SourceSpectrum.from_file(filename)
Load Vega from file. sp = SourceSpectrum.from_vega()
Create from wavelength and flux arrays. sp = SourceSpectrum(Empirical1D, points=wavelength, lookup_table=flux)
Blackbody with temperature, teff, and flux normalized to a star of solar radius at a distance of 1 kpc. sp = SourceSpectrum(BlackBodyNorm1D, temperature=teff)
Flat spectrum with constant flux. sp = SourceSpectrum(ConstFlux1D, amplitude=flux)
Powerlaw spectrum with flux of 1 in given unit at x and power of -a. sp = SourceSpectrum(PowerLawFlux1D, amplitude=1*unit, x_0=x, alpha=a)
Gaussian emission line centered on mu with given FWHM and total flux. sp = SourceSpectrum(GaussianFlux1D, mean=mu, fwhm=fwhm, total_flux=total_flux)
Thermal source spectrum from thermal bandpass. sp = thbp.thermal_source()

Modify Source Spectrum

New source spectrum is created as a result unless stated otherwise.

Description Command
Taper flux to zero on ends. sp2 = sp.taper()
Normalize to given value over given bandpass. Count and VEGAMAG unit requires extra inputs.

sp2 = sp.normalize(value, band=bp)

sp2 = sp.normalize(value_count, band=bp, area=area)

sp2 = sp.normalize(value_vegamag, band=bp, vegaspec=SourceSpectrum.from_vega())

Apply extinction curve. sp2 = sp * extcurve
Apply redshift (models modified in-place).

sp.z = z

sp.z_type = …

Apply redshift (new source spectrum).

sp2 = SourceSpectrum(sp.model, z=z, z_type=…)

sp = SourceSpectrum(modelclass, z=z, z_type=…, **kwargs)

Create Observation and Calculate

Observation has binned and unbinned components. Most methods accept an optional binned keyword to indicate which component you want to calculate for. Only the default binning option is listed below.

Description Command
Observe a source spectrum through given bandpass. obs = Observation(sp, bp)
Sample observed flux.

flux = obs(wavelength) # Unbinned

flux = obs.sample_binned(wavelength)

Effective wavelength. obs.effective_wavelength() # Binned
Effective stimulus in given unit. obs.effstim(flux_unit=unit) # Unbinned
Count rate for given area. obs.countrate(area) # Binned
Convert into simple source spectrum. sp = obs.as_spectrum() # Binned

Miscellaneous

Description Command
Generate wavelength array. wavelength = generate_wavelengths()
Quick-look plot. obj.plot() # Any spectrum object
Write to FITS table. bp.to_fits(filename); redlaw.to_fits(); sp.to_fits(filename)

FITS Table Format

The FITS table format supported here is the same as that in ASTROLIB PYSYNPHOT for backward compatibility with existing data files. Data is extracted from Extension 1, where the first column contains wavelength values, and the second flux (for source spectrum) or throughput (for bandpass). The extension header must contain the following keywords (unless you overwrite them with non-default values in read_fits_spec()):

For writing out FITS table, many options can be set to non-default as acceptable by write_fits_spec().

ASCII Table Format

The ASCII table format supported here is the same as that in ASTROLIB PYSYNPHOT for backward compatibility with existing data files. Wavelength and flux/throughput values must be in the first and the second columns, respectively. By default, wavelength is assumed to be in Angstrom; For source spectrum, flux is assumed to be in FLAM. All values will be read in as double-precision floating points. The file may contain blank or comment lines (any lines starting with "#"), which are ignored.

By default, Astropy’s ASCII reader will attempt to guess the format of your file (e.g., space- or tab-delimited). If guessing fails, you can pass in additional keywords to the reader, as well as specifying non-default wavelength and flux units, via synphot.specio.read_ascii_spec().

Result Accuracy

This is indirectly discussed in a similar section within stsynphot documentation as it is heavily built upon synphot machinery.