def binned_pixelrange(self, waverange, **kwargs): """Calculate the number of pixels within the given wavelength range and `binset`. Parameters ---------- waverange : tuple of float or `~astropy.units.quantity.Quantity` Lower and upper limits of the desired wavelength range. If not a Quantity, assumed to be in Angstrom. kwargs : dict Keywords accepted by :func:`synphot.binning.pixel_range`. Returns ------- npix : number Number of pixels. Raises ------ synphot.exceptions.UndefinedBinset Undefined `binset`. """ if self.binset is None: raise synexceptions.UndefinedBinset( 'No binset specified for this passband.') x = units.validate_quantity( waverange, self._internal_wave_unit, equivalencies=u.spectral()) return binning.pixel_range(self.binset.value, x.value, **kwargs)
def _process_graphtable(graphtable): """Load and cache graphtable. Get primary area.""" global _GRAPHDICT # Use default graph table if not given if graphtable is None: gtname = conf.graphtable else: gtname = graphtable # Load and cache graphtable, if not in cache if gtname in _GRAPHDICT: gt = _GRAPHDICT[gtname] else: gt = GraphTable(gtname) _GRAPHDICT[gtname] = gt # Set telescope collecting area if gt.primary_area is None: area = conf.area else: area = gt.primary_area primary_area = units.validate_quantity(area, units.AREA) return gt, gtname, primary_area
def thermback(self, area=None, thermtable=None): """Calculate thermal background count rate for ``self.obsmode``. Calculation uses :func:`~stsynphot.observationmode.ObservationMode.thermal_spectrum` to extract thermal component source spectrum in PHOTLAM per square arcsec. Then this spectrum is integrated and multiplied by detector pixel scale and telescope collecting area to produce a count rate in count/s/pix. This unit is non-standard but used widely by STScI Exposure Time Calculator. .. note:: Similar to IRAF SYNPHOT THERMBACK. Parameters ---------- area : float, `~astropy.units.quantity.Quantity`, or `None` Area that flux covers. If not a Quantity, assumed to be in :math:`cm^{2}`. If `None`, use `area`. thermtable : str or `None` Thermal component table filename. If `None`, uses ``stsynphot.config.conf.thermtable``. Returns ------- bg : `~astropy.units.quantity.Quantity` Thermal background count rate. Raises ------ synphot.exceptions.SynphotError Calculation failed. """ if self.obsmode.pixscale is None: raise synexceptions.SynphotError( 'Undefined pixel scale for {0}.'.format(self.obsmode)) if area is None: area = self.area area = units.validate_quantity(area, units.AREA) sp = self.obsmode.thermal_spectrum(thermtable=thermtable) bg = sp.integrate() * self.obsmode.pixscale ** 2 * area return bg.value * (u.count / u.s / u.pix)
def binned_waverange(self, cenwave, npix, **kwargs): """Calculate the wavelength range covered by the given number of pixels centered on the given central wavelengths of `binset`. Parameters ---------- cenwave : float or `~astropy.units.quantity.Quantity` Desired central wavelength. If not a Quantity, assumed to be in Angstrom. npix : int Desired number of pixels, centered on ``cenwave``. kwargs : dict Keywords accepted by :func:`synphot.binning.wave_range`. Returns ------- waverange : `~astropy.units.quantity.Quantity` Lower and upper limits of the wavelength range, in the unit of ``cenwave``. Raises ------ synphot.exceptions.UndefinedBinset Undefined `binset`. """ if self.binset is None: raise synexceptions.UndefinedBinset( 'No binset specified for this passband.') # Calculation is done in the unit of cenwave. if not isinstance(cenwave, u.Quantity): cenwave = cenwave * self._internal_wave_unit bin_wave = units.validate_quantity(self.binset, cenwave.unit, equivalencies=u.spectral()) return binning.wave_range(bin_wave.value, cenwave.value, npix, ** kwargs) * cenwave.unit
def binned_waverange(self, cenwave, npix, **kwargs): """Calculate the wavelength range covered by the given number of pixels centered on the given central wavelengths of `binset`. Parameters ---------- cenwave : float or `~astropy.units.quantity.Quantity` Desired central wavelength. If not a Quantity, assumed to be in Angstrom. npix : int Desired number of pixels, centered on ``cenwave``. kwargs : dict Keywords accepted by :func:`synphot.binning.wave_range`. Returns ------- waverange : `~astropy.units.quantity.Quantity` Lower and upper limits of the wavelength range, in the unit of ``cenwave``. Raises ------ synphot.exceptions.UndefinedBinset Undefined `binset`. """ if self.binset is None: raise synexceptions.UndefinedBinset( 'No binset specified for this passband.') # Calculation is done in the unit of cenwave. if not isinstance(cenwave, u.Quantity): cenwave = cenwave * self._internal_wave_unit bin_wave = units.validate_quantity( self.binset, cenwave.unit, equivalencies=u.spectral()) return binning.wave_range( bin_wave.value, cenwave.value, npix, **kwargs) * cenwave.unit
def grid_to_spec(gridname, t_eff, metallicity, log_g): """Extract spectrum from given catalog grid parameters. Interpolate if necessary. Grid parameters are only read once and then cached. Until the cache is cleared explicitly using :func:`reset_cache`, cached values are used. Parameters ---------- gridname : {'ck04models', 'k93models', 'phoenix'} Model to use: * ``ck04models`` - Castelli & Kurucz (2004) * ``k93models`` - Kurucz (1993) * ``phoenix`` - Allard et al. (2009) t_eff : str, float or `astropy.units.quantity.Quantity` Effective temperature of model. If not Quantity, assumed to be in Kelvin. If string (from parser), convert to Quantity. metallicity : str or float Metallicity of model. If string (from parser), convert to float. log_g : str or float Log surface gravity for model. If string (from parser), convert to float. Returns ------- sp : `synphot.spectrum.SourceSpectrum` Empirical source spectrum. Raises ------ stsynphot.exceptions.ParameterOutOfBounds Grid parameter out of bounds. synphot.exceptions.SynphotError Invalid inputs. """ if gridname == 'ck04models': catdir = 'crgridck04$' elif gridname == 'k93models': catdir = 'crgridk93$' elif gridname == 'phoenix': catdir = 'crgridphoenix$' else: raise synexceptions.SynphotError( '{0} is not a supported catalog grid.'.format(gridname)) metallicity = _par_from_parser(metallicity) if isinstance(metallicity, u.Quantity): raise synexceptions.SynphotError( 'Quantity is not supported for metallicity.') log_g = _par_from_parser(log_g) if isinstance(log_g, u.Quantity): raise synexceptions.SynphotError( 'Quantity is not supported for log surface gravity.') t_eff = units.validate_quantity(_par_from_parser(t_eff), u.K).value catdir = stio.irafconvert(catdir) filename = os.path.join(catdir, 'catalog.fits') # If not cached, read from grid catalog and cache it if filename not in _CACHE: data = stio.read_catalog(filename) # Ext 1 _CACHE[filename] = [[float(x) for x in index.split(',')] + [data['FILENAME'][i]] for i, index in enumerate(data['INDEX'])] indices = _CACHE[filename] list0, list1 = _break_list(indices, 0, t_eff) list2, list3 = _break_list(list0, 1, metallicity) list4, list5 = _break_list(list1, 1, metallicity) list6, list7 = _break_list(list2, 2, log_g) list8, list9 = _break_list(list3, 2, log_g) list10, list11 = _break_list(list4, 2, log_g) list12, list13 = _break_list(list5, 2, log_g) sp1 = _get_spectrum(list6[0], catdir) sp2 = _get_spectrum(list7[0], catdir) sp3 = _get_spectrum(list8[0], catdir) sp4 = _get_spectrum(list9[0], catdir) sp5 = _get_spectrum(list10[0], catdir) sp6 = _get_spectrum(list11[0], catdir) sp7 = _get_spectrum(list12[0], catdir) sp8 = _get_spectrum(list13[0], catdir) spa1 = _interpolate_spectrum(sp1, sp2, log_g) spa2 = _interpolate_spectrum(sp3, sp4, log_g) spa3 = _interpolate_spectrum(sp5, sp6, log_g) spa4 = _interpolate_spectrum(sp7, sp8, log_g) spa5 = _interpolate_spectrum(spa1, spa2, metallicity) spa6 = _interpolate_spectrum(spa3, spa4, metallicity) spa7 = _interpolate_spectrum(spa5, spa6, t_eff) sp = spa7[0] sp.meta['expr'] = '{0}(T_eff={1:g},metallicity={2:g},log_g={3:g})'.format( gridname, t_eff, metallicity, log_g) return sp
def grid_to_spec(gridname, t_eff, metallicity, log_g): """Extract spectrum from given catalog grid parameters. Interpolate if necessary. Grid parameters are read with :func:`get_catalog_index`. Parameters ---------- gridname : {'ck04models', 'k93models', 'phoenix'} Model to use: * ``ck04models`` - Castelli & Kurucz (2004) * ``k93models`` - Kurucz (1993) * ``phoenix`` - Allard et al. (2009) t_eff : str, float or `astropy.units.quantity.Quantity` Effective temperature of model. If not Quantity, assumed to be in Kelvin. If string (from parser), convert to Quantity. metallicity : str or float Metallicity of model. If string (from parser), convert to float. log_g : str or float Log surface gravity for model. If string (from parser), convert to float. Returns ------- sp : `synphot.spectrum.SourceSpectrum` Empirical source spectrum. Raises ------ stsynphot.exceptions.ParameterOutOfBounds Grid parameter out of bounds. synphot.exceptions.SynphotError Invalid inputs. """ indices, catdir = get_catalog_index(gridname) metallicity = _par_from_parser(metallicity) if isinstance(metallicity, u.Quantity): raise synexceptions.SynphotError( 'Quantity is not supported for metallicity.') log_g = _par_from_parser(log_g) if isinstance(log_g, u.Quantity): raise synexceptions.SynphotError( 'Quantity is not supported for log surface gravity.') t_eff = units.validate_quantity(_par_from_parser(t_eff), u.K).value list0, list1 = _break_list(indices, 0, t_eff) list2, list3 = _break_list(list0, 1, metallicity) list4, list5 = _break_list(list1, 1, metallicity) list6, list7 = _break_list(list2, 2, log_g) list8, list9 = _break_list(list3, 2, log_g) list10, list11 = _break_list(list4, 2, log_g) list12, list13 = _break_list(list5, 2, log_g) sp1 = _get_spectrum(list6[0], catdir) sp2 = _get_spectrum(list7[0], catdir) sp3 = _get_spectrum(list8[0], catdir) sp4 = _get_spectrum(list9[0], catdir) sp5 = _get_spectrum(list10[0], catdir) sp6 = _get_spectrum(list11[0], catdir) sp7 = _get_spectrum(list12[0], catdir) sp8 = _get_spectrum(list13[0], catdir) spa1 = _interpolate_spectrum(sp1, sp2, log_g) spa2 = _interpolate_spectrum(sp3, sp4, log_g) spa3 = _interpolate_spectrum(sp5, sp6, log_g) spa4 = _interpolate_spectrum(sp7, sp8, log_g) spa5 = _interpolate_spectrum(spa1, spa2, metallicity) spa6 = _interpolate_spectrum(spa3, spa4, metallicity) spa7 = _interpolate_spectrum(spa5, spa6, t_eff) sp = spa7[0] sp.meta['expr'] = (f'{gridname}(T_eff={t_eff:g},' f'metallicity={metallicity:g},log_g={log_g:g})') return sp