Source code for jdaviz.core.custom_units_and_equivs

import astropy.units as u

__all__ = ["PIX2", "SPEC_PHOTON_FLUX_DENSITY_UNITS",
           "_eqv_pixar_sr", "_eqv_flux_to_sb_pixel",
           "_eqv_sb_per_pixel_to_per_angle"]

# define custom composite units here
PIX2 = u.pix * u.pix


# Add spaxel to enabled units
def enable_spaxel_unit():
    spaxel = u.Unit('spaxel', represents=u.pixel, parse_strict='silent')
    u.add_enabled_units([spaxel])
    return


def _spectral_and_photon_flux_density_units(freq_only=False, wav_only=False,
                                            as_units=False):
    """
    Returns an alphabetically sorted list of string representations
    of flux density units supported by the unit conversion plugin. These units can
    be used for conversion if the input data units are compatible (i.e., directly
    equivalent or convertible using ``u.spectral_density(cube_wave)``). If both
    ``freq_only`` and ``wav_only`` are False, the function returns the combined
    list of all supported units. If ``as_units`` is True, return ``u.Unit`` instead
    of strings.

    Parameters:
    -----------
    freq_only : bool, optional
        If True, returns only frequency-based flux density units. (Default=False).

    wav_only : bool, optional
        If True, returns only wavelength-based flux density units. (Default=False).

    as_units : bool, optional
        If True, return ``u.Unit`` instead of strings

    Returns:
    --------
    list of str
        A sorted list of flux density unit strings.
    """
    wav_flux_units = ['erg / (Angstrom s cm2)', 'ph / (Angstrom s cm2)']
    freq_flux_units = ['Jy', 'mJy', 'uJy', 'MJy', 'W / (Hz m2)', 'eV / (Hz s m2)',
                       'erg / (Hz s cm2)', 'ph / (Hz s cm2)']

    if freq_only:
        flux_units = sorted(freq_flux_units)
    elif wav_only:
        flux_units = sorted(wav_flux_units)
    else:
        flux_units = sorted(freq_flux_units + wav_flux_units)

    if as_units:
        flux_units = [u.Unit(x) for x in flux_units]

    return flux_units


SPEC_PHOTON_FLUX_DENSITY_UNITS = _spectral_and_photon_flux_density_units()


[docs] def _eqv_pixar_sr(pixar_sr): """ Return Equivalencies to convert from flux to flux per solid angle (aka surface brightness) using scale ratio ``pixar_sr`` (steradians per pixel). """ def converter_flux(x): # Surface Brightness -> Flux return x * pixar_sr def iconverter_flux(x): # Flux -> Surface Brightness return x / pixar_sr return [ (u.MJy / u.sr, u.MJy, converter_flux, iconverter_flux), (u.erg / (u.s * u.cm**2 * u.Angstrom * u.sr), u.erg / (u.s * u.cm**2 * u.Angstrom), converter_flux, iconverter_flux), # noqa (u.ph / (u.Angstrom * u.s * u.cm**2 * u.sr), u.ph / (u.Angstrom * u.s * u.cm**2), converter_flux, iconverter_flux), # noqa (u.ph / (u.Hz * u.s * u.cm**2 * u.sr), u.ph / (u.Hz * u.s * u.cm**2), converter_flux, iconverter_flux), # noqa (u.ct / u.sr, u.ct, converter_flux, iconverter_flux) # noqa ]
[docs] def _eqv_flux_to_sb_pixel(): """ Returns an Equivalency between ``flux_unit`` and ``flux_unit`/pix**2``. This allows conversion between flux and flux-per-square-pixel surface brightness e.g MJy <> MJy / pix2 """ # generate an equivalency for each flux type that would need # another equivalency for converting to/from flux_units = [u.MJy, u.erg / (u.s * u.cm**2 * u.Angstrom), u.ph / (u.Angstrom * u.s * u.cm**2), u.ph / (u.Hz * u.s * u.cm**2), u.ct, u.DN, u.DN / u.s] equivs = [(flux_unit, flux_unit / PIX2, lambda x: x, lambda x: x) for flux_unit in flux_units] # We also need to convert between spaxel and pixel squared equivs += [(flux_unit / u.Unit('spaxel'), flux_unit / PIX2, lambda x: x, lambda x: x) for flux_unit in flux_units] return equivs
[docs] def _eqv_sb_per_pixel_to_per_angle(flux_unit, scale_factor=1): """ Returns an equivalency between ``flux_unit`` per square pixel and ``flux_unit`` per solid angle to be able to compare and convert between units like Jy/pix**2 and Jy/sr. The scale factor is assumed to be in steradians, to follow the convention of the PIXAR_SR keyword. Note: To allow conversions between units like ``ph / (Hz s cm2 sr)`` and MJy / pix2, which would require this equivalency as well as u.spectral_density, these CAN'T be combined when converting like: equivalencies=u.spectral_density(1 * u.m) + _eqv_sb_per_pixel_to_per_angle(u.Jy) So additional logic is needed to compare units that need both equivalencies (one solution being creating this equivalency for each equivalent flux-type.) """ # the two types of units we want to define a conversion between flux_solid_ang = flux_unit / u.sr flux_sq_pix = flux_unit / PIX2 pix_to_solid_angle_equiv = [(flux_solid_ang, flux_sq_pix, lambda x: x * scale_factor, lambda x: x / scale_factor)] return pix_to_solid_angle_equiv