コード例 #1
0
    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)
コード例 #2
0
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
コード例 #3
0
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
コード例 #4
0
    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)
コード例 #5
0
    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)
コード例 #6
0
    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)
コード例 #7
0
    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
コード例 #8
0
    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
コード例 #9
0
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
コード例 #10
0
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