Source code for synphot.thermal

# Licensed under a 3-clause BSD style license - see LICENSE.rst
"""This module defines thermal spectra."""

# ASTROPY
from astropy import units as u
from astropy.io import fits
from astropy.io.fits.connect import is_fits

# LOCAL
from synphot import exceptions, specio, units
from synphot.models import BlackBody1D, Empirical1D
from synphot.spectrum import BaseUnitlessSpectrum, SourceSpectrum

__all__ = ['ThermalSpectralElement']


[docs] class ThermalSpectralElement(BaseUnitlessSpectrum): """Class to handle spectral element with associated thermal properties. This differs from `~synphot.spectrum.SpectralElement` in the sense that it carries thermal parameters, i.e., temperature and beam filling factor. .. note:: Use :func:`thermal_source` to apply its emissivity to an existing beam. Parameters ---------- modelclass, kwargs See `~synphot.spectrum.BaseSpectrum`. temperature : float or `~astropy.units.quantity.Quantity` Temperature. If not a Quantity, assumed to be in Kelvin. beam_fill_factor : float or `~astropy.units.quantity.Quantity` Beam filling factor. If a Quantity, must be unitless. Defaults to 1. """ def __init__(self, modelclass, temperature, beam_fill_factor=1, **kwargs): super(ThermalSpectralElement, self).__init__(modelclass, **kwargs) self.temperature = temperature self.beam_fill_factor = beam_fill_factor @property def temperature(self): """Temperature.""" return self._temperature @temperature.setter def temperature(self, what): """Set temperature.""" self._temperature = units.validate_quantity(what, u.K) @property def beam_fill_factor(self): """Beam filling factor.""" return self._beam_fill_factor @beam_fill_factor.setter def beam_fill_factor(self, what): """Set beam filling factor.""" self._beam_fill_factor = units.validate_quantity(what, '').value
[docs] def taper(self, **kwargs): """Tapering is disabled.""" raise NotImplementedError( 'Thermal spectral element cannot be tapered.')
[docs] def thermal_source(self): """Apply emissivity to an existing beam to produce a thermal source spectrum (without optical counterpart). Thermal source spectrum is calculated as follow: #. Create a blackbody spectrum in PHOTLAM per square arcsec with `temperature`. #. Multiply the blackbody with `beam_fill_factor` and ``self``. Returns ------- sp : `~synphot.spectrum.SourceSpectrum` Thermal source spectrum. """ sp = (SourceSpectrum(BlackBody1D, temperature=self.temperature) * units.SR_PER_ARCSEC2 * self.beam_fill_factor * self) sp.meta['temperature'] = self.temperature sp.meta['beam_fill_factor'] = self.beam_fill_factor return sp
[docs] @classmethod def from_file(cls, filename, temperature_key='DEFT', beamfill_key='BEAMFILL', **kwargs): """Creates a thermal spectral element from file. .. note:: Only FITS format is supported. Parameters ---------- filename : str Thermal spectral element filename. temperature_key, beamfill_key : str Keywords in FITS *table extension* that store temperature (in Kelvin) and beam filling factor values. Beam filling factor is set to 1 if its keyword is missing. kwargs : dict Keywords acceptable by :func:`~synphot.specio.read_fits_spec`. Returns ------- th : `ThermalSpectralElement` Empirical thermal spectral element. Raises ------ synphot.exceptions.SynphotError Invalid inputs. """ if not is_fits("", filename, None): raise exceptions.SynphotError('Only FITS format is supported.') # Extra info from table header ext = kwargs.get('ext', 1) tab_hdr = fits.getheader(filename, ext=ext) temperature = tab_hdr.get(temperature_key) if temperature is None: raise exceptions.SynphotError( 'Missing {0} keyword.'.format(temperature_key)) beam_fill_factor = tab_hdr.get('BEAMFILL', 1) if 'flux_col' not in kwargs: kwargs['flux_col'] = 'EMISSIVITY' header, wavelengths, em = specio.read_spec(filename, **kwargs) return cls( Empirical1D, temperature, beam_fill_factor=beam_fill_factor, points=wavelengths, lookup_table=em, meta={'header': header})