예제 #1
0
    def __init__(self,
                 model="kpno",
                 extinction=None,
                 spectral_axis=None,
                 cache=True,
                 show_progress=False,
                 **kwargs):
        if extinction is not None:
            if not isinstance(extinction, u.Quantity):
                warnings.warn(
                    "Input extinction is not a Quanitity. Assuming it is given in magnitudes...",
                    AstropyUserWarning)
                extinction = u.Magnitude(
                    extinction, u.MagUnit(u.dimensionless_unscaled)).to(
                        u.dimensionless_unscaled
                    )  # Spectrum1D wants this to be linear
            if isinstance(
                    extinction,
                (u.LogUnit, u.Magnitude)) or extinction.unit == u.mag:
                # if in log or magnitudes, recast into Magnitude with dimensionless physical units
                extinction = u.Magnitude(extinction.value,
                                         u.MagUnit(
                                             u.dimensionless_unscaled)).to(
                                                 u.dimensionless_unscaled)
            if extinction.unit != u.dimensionless_unscaled:
                # if we're given something linear that's not dimensionless_unscaled,
                # it's an error
                msg = "Input extinction must have unscaled dimensionless units."
                raise ValueError(msg)

        if extinction is None and spectral_axis is None:
            if model not in SUPPORTED_EXTINCTION_MODELS:
                msg = (f"Requested extinction model, {model}, not in list "
                       f"of available models: {SUPPORTED_EXTINCTION_MODELS}")
                raise ValueError(msg)
            model_file = os.path.join("extinction", f"{model}extinct.dat")
            model_path = get_reference_file_path(path=model_file,
                                                 cache=cache,
                                                 show_progress=show_progress)
            t = Table.read(model_path,
                           format="ascii",
                           names=['wavelength', 'extinction'])

            # the specreduce_data models all provide wavelengths in angstroms
            spectral_axis = t['wavelength'].data * u.angstrom

            # the specreduce_data models all provide extinction in magnitudes at an airmass of 1
            extinction = u.Magnitude(t['extinction'].data,
                                     u.MagUnit(u.dimensionless_unscaled)).to(
                                         u.dimensionless_unscaled)

        if spectral_axis is None:
            msg = "Missing spectral axis for input extinction data."
            raise ValueError(msg)

        super(AtmosphericExtinction,
              self).__init__(flux=extinction,
                             spectral_axis=spectral_axis,
                             unit=u.dimensionless_unscaled,
                             **kwargs)
예제 #2
0
    def test_str(self):
        """Do some spot checks that str, repr, etc. work as expected."""
        lu1 = u.mag(u.Jy)
        assert str(lu1) == 'mag(Jy)'
        assert repr(lu1) == 'Unit("mag(Jy)")'
        assert lu1.to_string('generic') == 'mag(Jy)'
        with pytest.raises(ValueError):
            lu1.to_string('fits')
        with pytest.raises(ValueError):
            lu1.to_string(format='cds')

        lu2 = u.dex()
        assert str(lu2) == 'dex'
        assert repr(lu2) == 'Unit("dex(1)")'
        assert lu2.to_string() == 'dex(1)'

        lu3 = u.MagUnit(u.Jy, function_unit=2 * u.mag)
        assert str(lu3) == '2 mag(Jy)'
        assert repr(lu3) == 'MagUnit("Jy", unit="2 mag")'
        assert lu3.to_string() == '2 mag(Jy)'

        lu4 = u.mag(u.ct)
        assert lu4.to_string('generic') == 'mag(ct)'
        assert lu4.to_string('latex') == ('$\\mathrm{mag}$$\\mathrm{\\left( '
                                          '\\mathrm{ct} \\right)}$')
        assert lu4._repr_latex_() == lu4.to_string('latex')
예제 #3
0
def test_custom_mag_model():
    """
    Test creation of custom model from Quantity arrays
    """
    wave = np.linspace(0.3, 2.0, 50)
    extinction = u.Magnitude(1. / wave, u.MagUnit(u.dimensionless_unscaled))
    ext = AtmosphericExtinction(extinction=extinction, spectral_axis=wave * u.um)
    assert(len(ext.extinction_mag) > 0)
    assert(len(ext.transmission) > 0)
예제 #4
0
def test_littleh():
    H0_70 = 70*u.km/u.s/u.Mpc
    h70dist = 70 * u.Mpc/u.littleh

    assert_quantity_allclose(h70dist.to(u.Mpc, u.with_H0(H0_70)), 100*u.Mpc)

    # make sure using the default cosmology works
    cosmodist = cosmology.default_cosmology.get().H0.value * u.Mpc/u.littleh
    assert_quantity_allclose(cosmodist.to(u.Mpc, u.with_H0()), 100*u.Mpc)

    # Now try a luminosity scaling
    h1lum = .49 * u.Lsun * u.littleh**-2
    assert_quantity_allclose(h1lum.to(u.Lsun, u.with_H0(H0_70)), 1*u.Lsun)

    # And the trickiest one: magnitudes.  Using H0=10 here for the round numbers
    H0_10 = 10*u.km/u.s/u.Mpc
    # assume the "true" magnitude M = 12.
    # Then M - 5*log_10(h)  = M + 5 = 17
    withlittlehmag = 17 * (u.mag - u.MagUnit(u.littleh**2))
    assert_quantity_allclose(withlittlehmag.to(u.mag, u.with_H0(H0_10)), 12*u.mag)
예제 #5
0
@pytest.mark.parametrize(
    'strings, unit',
    [
        (["m s", "m*s", "m.s"], u.m * u.s),
        (["m/s", "m*s**-1", "m /s", "m / s", "m/ s"], u.m / u.s),
        (["m**2", "m2", "m**(2)", "m**+2", "m+2", "m^(+2)"], u.m**2),
        (["m**-3", "m-3", "m^(-3)", "/m3"], u.m**-3),
        (["m**(1.5)", "m(3/2)", "m**(3/2)", "m^(3/2)"], u.m**1.5),
        (["2.54 cm"], u.Unit(u.cm * 2.54)),
        (["10+8m"], u.Unit(u.m * 1e8)),
        # This is the VOUnits documentation, but doesn't seem to follow the
        # unity grammar (["3.45 10**(-4)Jy"], 3.45 * 1e-4 * u.Jy)
        (["sqrt(m)"], u.m**0.5),
        (["dB(mW)", "dB (mW)"], u.DecibelUnit(u.mW)),
        (["mag"], u.mag),
        (["mag(ct/s)"], u.MagUnit(u.ct / u.s)),
        (["dex"], u.dex),
        (["dex(cm s**-2)", "dex(cm/s2)"], u.DexUnit(u.cm / u.s**2))
    ])
def test_unit_grammar(strings, unit):
    for s in strings:
        print(s)
        unit2 = u_format.Generic.parse(s)
        assert unit2 == unit


@pytest.mark.parametrize(
    'string', ['sin( /pixel /s)', 'mag(mag)', 'dB(dB(mW))', 'dex()'])
def test_unit_grammar_fail(string):
    with pytest.raises(ValueError):
        print(string)
예제 #6
0
    >>> import sbpy.units
    >>> sbpy.units.enable()    # doctest: +SKIP

"""

__all__ = ['spectral_density_vega', 'enable', 'VEGA', 'VEGAmag', 'JM', 'JMmag']

from warnings import warn
import numpy as np
import astropy.units as u
from astropy.utils.exceptions import AstropyWarning
from ..spectroscopy.vega import Vega

VEGA = u.def_unit(['VEGA', 'VEGAflux'], doc='Spectral flux density of Vega.')

VEGAmag = u.MagUnit(VEGA)
VEGAmag.__doc__ = "Vega-based magnitude: Vega is 0 mag at all wavelengths"

JM = u.def_unit(['JM', 'JMflux'],
                represents=VEGA * 10**(0.4 * 0.03),
                doc=('Johnson-Morgan magnitude system flux density '
                     'zeropoint (Johnson et al. 1966; Bessell & Murphy '
                     '2012).'))

JMmag = u.MagUnit(JM)
JMmag.__doc__ = ("Johnson-Morgan magnitude system: Vega is 0.03 mag at "
                 "all wavelengths (Johnson et al. 1966; Bessell & Murphy "
                 "2012).")


def enable():
예제 #7
0
파일: units.py 프로젝트: olebole/gamaica
need to import the module::

    >>> import astropy.units as u
    >>> import etc.units
    >>> u.Unit('mag(VEGA)')
    Unit("mag(VEGA)")

"""

import numpy as np
import astropy.units as u

VEGA = u.def_unit(['VEGA', 'VEGAflux'],
                  doc='Spectral flux density of Vega.')

VEGAmag = u.MagUnit(VEGA)
VEGAmag.__doc__ = "Vega-based magnitude: Vega is 0 mag at all wavelengths"

u.add_enabled_units(VEGA)


def spectral_density(wfb):
    """Flux density equivalencies, extended for Vega-based magnitude systems.

    This uses the default Vega spectrum that comes for 4MOST in the
    Instrument Control Repository (ICR).

    Vega is assumed to have an apparent magnitude of 0 in the
    ``VEGAmag`` system.

    See https://github.com/astropy/astropy/issues/10821 for a
예제 #8
0
def overplot_spectroscopic(res,
                           drp_logcube,
                           drpall_row,
                           mass_ax,
                           ml_ax,
                           f_ax,
                           pca_system,
                           res_wcs,
                           cmlr,
                           mlb='i'):
    '''
    overplot cumulative spectroscopic masses, log M/L, cumulative fluxes
    '''

    # synthetic photometry of IFU data in rest frame
    ebvgal = drpall_row['ebvgal']
    r_v = 3.1
    dustcorr = 10.**(0.4 * extinction.fitzpatrick99(
        drp_logcube['WAVE'].data, a_v=r_v * ebvgal, r_v=r_v))[:, None, None]

    ifu_s2p = spectrophot.Spec2Phot(
        lam=drp_logcube['WAVE'].data / (1. + drpall_row['nsa_z']),
        flam=1.0e-17 * drp_logcube['FLUX'].data * (1. + drpall_row['nsa_z']) *
        dustcorr)
    res_flux = (ifu_s2p.ABmags['sdss2010-{}'.format(mlb)] * u.ABmag).to(m.Mgy)

    # map sky coordinates to number of effective radii from center
    pos_to_nRe = RotatedParaboloid(ctr=np.array(
        [drpall_row['objra'], drpall_row['objdec']]),
                                   phi=drpall_row['nsa_elpetro_phi'] * u.deg,
                                   axis_ratio=drpall_row['nsa_elpetro_ba'],
                                   Re=drpall_row['nsa_elpetro_th50_r'] / 3600.)

    badpdf = res.badPDF()
    ml_mask = np.logical_or(res.mask, badpdf)

    # WCS from results file determines where elliptical projection is sampled
    #res_wcs = wcs.WCS(res['SNRMED'].header)
    res_II, res_JJ = np.meshgrid(
        *[np.linspace(0., s - 1., s) for s in res['SNRMED'].shape],
        indexing='ij')
    res_AA, res_DD = res_wcs.wcs_pix2world(res_JJ, res_II, 1)

    # sample Re at spaxel centers
    res_Re = pos_to_nRe(np.column_stack([res_AA.flatten(),
                                         res_DD.flatten()
                                         ])).reshape(res_AA.shape)
    nRe_to_plot = np.linspace(0., res_Re[~ml_mask].max(), 50.)

    # mass, log M/L
    badpdf = res.badPDF()
    ml_mask = np.logical_or.reduce((res.mask, badpdf))
    interior_mask = np.logical_or.reduce(
        (badpdf,
         (m.mask_from_maskbits(drp_logcube['MASK'].data, [3]).sum(axis=0) > 0),
         (m.mask_from_maskbits(drp_logcube['MASK'].data, [2]).sum(axis=0) >
          0)))
    logml = infer_masked(res.param_dist_med(extname='ML{}'.format(mlb)),
                         ml_mask, interior_mask)
    ml = 10.**logml * m.m_to_l_unit
    res_MAG = res_flux.to(u.ABmag) - cosmo.distmod(drpall_row['nsa_zdist'])
    mlb_sollum = 10.**(-0.4 * (res_MAG - spectrophot.absmag_sun_band[mlb] * u.ABmag)).value * \
                 m.bandpass_sol_l_unit
    spectro_mass = (ml * mlb_sollum).to(u.Msun)

    # sum mass within some number of Re
    mass_within_nRe = np.array(
        [sum_within_nRe(spectro_mass, res_Re, n) for n in nRe_to_plot])
    mass_ax.plot(nRe_to_plot, mass_within_nRe, c='C1')

    # plot mass to light versus Re
    ml_sc = ml_ax.scatter(res_Re[~ml_mask],
                          logml[~ml_mask],
                          c='C1',
                          edgecolor='None',
                          s=.5)

    res_Re_m = np.ma.array(res_Re, mask=ml_mask)
    # find ring method log M/L
    outer_ring = np.logical_and((res_Re_m <= res_Re_m.max()),
                                (res_Re_m >= res_Re_m.max() - .5))
    outer_logml_ring = np.median(logml[~ml_mask * outer_ring])
    ml_ax.scatter(x=[np.median(res_Re_m[~ml_mask * outer_ring])],
                  y=[outer_logml_ring],
                  marker='x',
                  c='C1')
    # find CMLR log M/L
    nsa_MAG = (np.array(drpall_row['nsa_elpetro_absmag'][2:]) * \
                        (u.ABmag - u.MagUnit(u.littleh**2))).to(u.ABmag, u.with_H0(cosmo.H0))
    nsa_mag = (nsa_MAG + cosmo.distmod(drpall_row['nsa_zdist']))
    nsa_flux = nsa_mag.to(m.Mgy)
    ifu_mag = np.array(
        [ifu_s2p.ABmags['sdss2010-{}'.format(b_)] for b_ in 'ugriz']) * u.ABmag
    ifu_mag[~np.isfinite(ifu_mag)] = 40. * u.ABmag
    ifu_flux = ifu_mag.to(m.Mgy)
    flux_deficit = nsa_flux - ifu_flux.sum(axis=(1, 2))
    logml_missingflux_cmlr = cmlr(2.5 *
                                  np.log10(flux_deficit[1] / flux_deficit[2]))
    ml_ax.scatter(x=[np.median(res_Re_m[~ml_mask * outer_ring])],
                  y=[logml_missingflux_cmlr],
                  marker='s',
                  c='C1',
                  edgecolor='k')

    #
    ml_missingflux_cmlr = 10.**logml_missingflux_cmlr * m.m_to_l_unit
    ml_missingflux_ring = 10.**outer_logml_ring * m.m_to_l_unit
    missing_mlb_MAG = flux_deficit[3].to(u.ABmag) - cosmo.distmod(
        drpall_row['nsa_zdist'])
    missing_mlb_sollum = 10.**(-0.4 * (missing_mlb_MAG - spectrophot.absmag_sun_band[mlb] * u.ABmag)).value * \
        m.bandpass_sol_l_unit
    missing_mass_cmlr = (ml_missingflux_cmlr * missing_mlb_sollum).to(u.Msun)
    missing_mass_ring = (ml_missingflux_ring * missing_mlb_sollum).to(u.Msun)

    mass_ax.scatter(x=res_Re.max() - .1,
                    y=mass_within_nRe[-1] * u.Msun + missing_mass_cmlr,
                    marker='s',
                    c='C1',
                    edgecolor='k',
                    zorder=3,
                    label='+AC(CMLR)')
    mass_ax.scatter(x=res_Re.max(),
                    y=mass_within_nRe[-1] * u.Msun + missing_mass_ring,
                    marker='x',
                    c='C1',
                    edgecolor='k',
                    zorder=3,
                    label='+AC(RING)')
    mass_ax.legend(loc='best', prop={'size': 'x-small'})

    summed_flux = np.array([
        sum_within_nRe(arr=res_flux, Re_a=res_Re, nRe=n) for n in nRe_to_plot
    ])
    f_ax.plot(nRe_to_plot, summed_flux, label='IFU', c='C1')
    f_ax.scatter(x=res_Re.max() + .1,
                 y=summed_flux[-1] * m.Mgy + flux_deficit[3],
                 marker='o',
                 c='C1',
                 edgecolor='k',
                 zorder=3)
예제 #9
0
def make_stellarmass_aperture_plot(preimaging,
                                   dap_maps,
                                   drp_logcube,
                                   cmlr,
                                   drpall_row,
                                   mlb='i',
                                   cb1='g',
                                   cb2='r'):
    '''
    make aperture plot of included mass (from CMLR and preimaging) versus radius (from DAP)

    preimaging: MaNGA_PreImage object
    dap_maps: FITS HDUList with DAP MAPS outputs
    '''
    ebvgal = drpall_row['ebvgal']

    # WCS from DAP determines sampling for Re grid, and where k-correction map is sampled
    dap_wcs = wcs.WCS(dap_maps['SPX_SNR'].header)
    dap_AA, dap_DD = dap_wcs.wcs_pix2world(
        *np.meshgrid(*[
            np.linspace(0., s - 1., s) for s in dap_maps['SPX_SNR'].data.shape
        ]), 1)

    # map sky coordinates to number of effective radii from center
    pos_to_nRe = RotatedParaboloid(ctr=np.array(
        [drpall_row['objra'], drpall_row['objdec']]),
                                   phi=drpall_row['nsa_elpetro_phi'] * u.deg,
                                   axis_ratio=drpall_row['nsa_elpetro_ba'],
                                   Re=drpall_row['nsa_elpetro_th50_r'] / 3600.)

    # WCS from preimaging determines where elliptical projection is resampled
    preimaging_wcs = wcs.WCS(preimaging['{} img'.format(mlb)].header)
    preimaging_II, preimaging_JJ = np.meshgrid(
        *[np.linspace(0., s - 1., s) for s in preimaging.img(mlb).shape],
        indexing='ij')
    preimaging_AA, preimaging_DD = preimaging_wcs.wcs_pix2world(
        preimaging_JJ, preimaging_II, 1)

    # evaluate Re interpolation on imaging RA/Dec grid
    preimaging_Re = pos_to_nRe(
        np.column_stack([preimaging_AA.flatten(),
                         preimaging_DD.flatten()
                         ])).reshape(preimaging_AA.shape)

    kcorr_cb1_interp, kcorr_cb2_interp, kcorr_mlb_interp = kcorr_spec_to_phot(
        drp_logcube, dap_maps['SPX_MFLUX_IVAR'], drpall_row['nsa_z'], cb1, cb2,
        mlb)

    kcorr_cb1_phot = kcorr_cb1_interp(preimaging_AA.flatten(),
                                      preimaging_DD.flatten()).reshape(
                                          preimaging_AA.shape) * u.mag
    kcorr_cb2_phot = kcorr_cb2_interp(preimaging_AA.flatten(),
                                      preimaging_DD.flatten()).reshape(
                                          preimaging_AA.shape) * u.mag
    kcorr_color = kcorr_cb1_phot - kcorr_cb2_phot
    kcorr_mlb_phot = kcorr_mlb_interp(preimaging_AA.flatten(),
                                      preimaging_DD.flatten()).reshape(
                                          preimaging_AA.shape) * u.mag

    # evaluate CMLR given preimaging
    ml_from_cmlr = 10.**cmlr(
        color=preimaging.color(cb1, cb2, dustcorr=True, ebvgal=ebvgal) +
        kcorr_color.value) * m.m_to_l_unit
    img_mag = (preimaging.img(mlb) * 1.0e-9 * m.Mgy).to(
        u.ABmag) + kcorr_mlb_phot
    distmod = cosmo.distmod(drpall_row['nsa_zdist'])
    img_MAG = img_mag - distmod

    mlb_sollum = 10.**(-0.4 * (img_MAG - spectrophot.absmag_sun_band[mlb] * u.ABmag)).value * \
                 m.bandpass_sol_l_unit
    mass_from_cmlr = (ml_from_cmlr * mlb_sollum).to(u.Msun)

    nRe_to_plot = np.linspace(0., 0.9 * preimaging_Re.max(), 1000)

    photomass_within_nRe = np.array([
        sum_within_nRe(mass_from_cmlr, preimaging_Re, n) for n in nRe_to_plot
    ])

    # solve for number of effective radii enclosing all of NSA flux
    NSA_bands = 'FNugriz'
    NSA_bands_ixs = dict(zip(NSA_bands, range(len(NSA_bands))))
    NSA_MAG = drpall_row['nsa_elpetro_absmag'][NSA_bands_ixs[mlb]] * \
              (u.ABmag - u.MagUnit(u.littleh**2))
    NSA_kcorr_flux = (NSA_MAG.to(u.ABmag, u.with_H0(cosmo.H0)) + \
                      cosmo.distmod(drpall_row['nsa_zdist'])).to(m.Mgy)

    fig, (ax1, ax2, ax3) = plt.subplots(nrows=3,
                                        ncols=1,
                                        figsize=(9, 7),
                                        dpi=150,
                                        sharex=True)
    ax1.plot(nRe_to_plot, photomass_within_nRe, linewidth=1., color='C0')
    ax1.set_yscale('log')
    ax1.set_ylabel(r'$\frac{M_{< R}}{M_{\odot}}$', size='small')

    ax2.scatter(preimaging_Re.flatten(),
                np.log10(ml_from_cmlr.value.flatten()),
                edgecolor='None',
                s=.5,
                c='C0')
    ax2.set_ylabel(r'$\log \Upsilon^*_{{{}}}$'.format(mlb), size='small')
    ax2.set_ylim([-2.5, 2.5])

    summed_flux = np.array([
        sum_within_nRe(arr=img_mag.to(m.Mgy), Re_a=preimaging_Re, nRe=n)
        for n in nRe_to_plot
    ])
    img_var = 1. / preimaging.img_ivar(mlb) * (1.0e-9 * m.Mgy)**2
    quadsummed_fluxunc = np.sqrt(
        np.array([
            sum_within_nRe(arr=img_var, Re_a=preimaging_Re, nRe=n)
            for n in nRe_to_plot
        ]))
    ax3.plot(nRe_to_plot, summed_flux, label='K-Corr. Phot.', color='C0')
    ax3.fill_between(nRe_to_plot,
                     summed_flux - quadsummed_fluxunc,
                     summed_flux + quadsummed_fluxunc,
                     alpha=0.5,
                     linewidth=0.25,
                     color='C0')
    ax3.set_xlabel(r'$\frac{R}{R_e}$', size='small')
    ax3.set_ylabel(r'$\frac{F_{<R}}{\rm Mgy}$', size='small')
    ax3.set_yscale('log')

    fig.suptitle(drpall_row['plateifu'])

    return fig, ax1, ax2, ax3
예제 #10
0
class TestLogQuantityCreation:
    @pytest.mark.parametrize('lq, lu',
                             zip(lq_subclasses + [u.LogQuantity],
                                 lu_subclasses + [u.LogUnit]))
    def test_logarithmic_quantities(self, lq, lu):
        """Check logarithmic quantities are all set up correctly"""
        assert lq._unit_class == lu
        assert type(lu()._quantity_class(1.)) is lq

    @pytest.mark.parametrize('lq_cls, physical_unit',
                             itertools.product(lq_subclasses, pu_sample))
    def test_subclass_creation(self, lq_cls, physical_unit):
        """Create LogQuantity subclass objects for some physical units,
        and basic check on transformations"""
        value = np.arange(1., 10.)
        log_q = lq_cls(value * physical_unit)
        assert log_q.unit.physical_unit == physical_unit
        assert log_q.unit.function_unit == log_q.unit._default_function_unit
        assert_allclose(log_q.physical.value, value)
        with pytest.raises(ValueError):
            lq_cls(value, physical_unit)

    @pytest.mark.parametrize(
        'unit', (u.mag, u.mag(), u.mag(u.Jy), u.mag(u.m), u.Unit(
            2 * u.mag), u.MagUnit('', 2. * u.mag), u.MagUnit(
                u.Jy, -1 * u.mag), u.MagUnit(u.m, -2. * u.mag)))
    def test_different_units(self, unit):
        q = u.Magnitude(1.23, unit)
        assert q.unit.function_unit == getattr(unit, 'function_unit', unit)
        assert q.unit.physical_unit is getattr(unit, 'physical_unit',
                                               u.dimensionless_unscaled)

    @pytest.mark.parametrize('value, unit',
                             ((1. * u.mag(u.Jy), None),
                              (1. * u.dex(u.Jy), None),
                              (1. * u.mag(u.W / u.m**2 / u.Hz), u.mag(u.Jy)),
                              (1. * u.dex(u.W / u.m**2 / u.Hz), u.mag(u.Jy))))
    def test_function_values(self, value, unit):
        lq = u.Magnitude(value, unit)
        assert lq == value
        assert lq.unit.function_unit == u.mag
        assert lq.unit.physical_unit == getattr(unit, 'physical_unit',
                                                value.unit.physical_unit)

    @pytest.mark.parametrize(
        'unit', (u.mag(), u.mag(u.Jy), u.mag(u.m), u.MagUnit('', 2. * u.mag),
                 u.MagUnit(u.Jy, -1 * u.mag), u.MagUnit(u.m, -2. * u.mag)))
    def test_indirect_creation(self, unit):
        q1 = 2.5 * unit
        assert isinstance(q1, u.Magnitude)
        assert q1.value == 2.5
        assert q1.unit == unit
        pv = 100. * unit.physical_unit
        q2 = unit * pv
        assert q2.unit == unit
        assert q2.unit.physical_unit == pv.unit
        assert q2.to_value(unit.physical_unit) == 100.
        assert (q2._function_view / u.mag).to_value(1) == -5.
        q3 = unit / 0.4
        assert q3 == q1

    def test_from_view(self):
        # Cannot view a physical quantity as a function quantity, since the
        # values would change.
        q = [100., 1000.] * u.cm / u.s**2
        with pytest.raises(TypeError):
            q.view(u.Dex)
        # But fine if we have the right magnitude.
        q = [2., 3.] * u.dex
        lq = q.view(u.Dex)
        assert isinstance(lq, u.Dex)
        assert lq.unit.physical_unit == u.dimensionless_unscaled
        assert np.all(q == lq)

    def test_using_quantity_class(self):
        """Check that we can use Quantity if we have subok=True"""
        # following issue #5851
        lu = u.dex(u.AA)
        with pytest.raises(u.UnitTypeError):
            u.Quantity(1., lu)
        q = u.Quantity(1., lu, subok=True)
        assert type(q) is lu._quantity_class
예제 #11
0
class TestLogUnitArithmetic:
    def test_multiplication_division(self):
        """Check that multiplication/division with other units is only
        possible when the physical unit is dimensionless, and that this
        turns the unit into a normal one."""
        lu1 = u.mag(u.Jy)

        with pytest.raises(u.UnitsError):
            lu1 * u.m

        with pytest.raises(u.UnitsError):
            u.m * lu1

        with pytest.raises(u.UnitsError):
            lu1 / lu1

        for unit in (u.dimensionless_unscaled, u.m, u.mag, u.dex):
            with pytest.raises(u.UnitsError):
                lu1 / unit

        lu2 = u.mag(u.dimensionless_unscaled)

        with pytest.raises(u.UnitsError):
            lu2 * lu1

        with pytest.raises(u.UnitsError):
            lu2 / lu1

        # But dimensionless_unscaled can be cancelled.
        assert lu2 / lu2 == u.dimensionless_unscaled

        # With dimensionless, normal units are OK, but we return a plain unit.
        tf = lu2 * u.m
        tr = u.m * lu2
        for t in (tf, tr):
            assert not isinstance(t, type(lu2))
            assert t == lu2.function_unit * u.m
            with u.set_enabled_equivalencies(u.logarithmic()):
                with pytest.raises(u.UnitsError):
                    t.to(lu2.physical_unit)
        # Now we essentially have a LogUnit with a prefactor of 100,
        # so should be equivalent again.
        t = tf / u.cm
        with u.set_enabled_equivalencies(u.logarithmic()):
            assert t.is_equivalent(lu2.function_unit)
            assert_allclose(
                t.to(u.dimensionless_unscaled,
                     np.arange(3.) / 100.),
                lu2.to(lu2.physical_unit, np.arange(3.)))

        # If we effectively remove lu1, a normal unit should be returned.
        t2 = tf / lu2
        assert not isinstance(t2, type(lu2))
        assert t2 == u.m
        t3 = tf / lu2.function_unit
        assert not isinstance(t3, type(lu2))
        assert t3 == u.m

        # For completeness, also ensure non-sensical operations fail
        with pytest.raises(TypeError):
            lu1 * object()
        with pytest.raises(TypeError):
            slice(None) * lu1
        with pytest.raises(TypeError):
            lu1 / []
        with pytest.raises(TypeError):
            1 / lu1

    @pytest.mark.parametrize('power', (2, 0.5, 1, 0))
    def test_raise_to_power(self, power):
        """Check that raising LogUnits to some power is only possible when the
        physical unit is dimensionless, and that conversion is turned off when
        the resulting logarithmic unit (such as mag**2) is incompatible."""
        lu1 = u.mag(u.Jy)

        if power == 0:
            assert lu1**power == u.dimensionless_unscaled
        elif power == 1:
            assert lu1**power == lu1
        else:
            with pytest.raises(u.UnitsError):
                lu1**power

        # With dimensionless, though, it works, but returns a normal unit.
        lu2 = u.mag(u.dimensionless_unscaled)

        t = lu2**power
        if power == 0:
            assert t == u.dimensionless_unscaled
        elif power == 1:
            assert t == lu2
        else:
            assert not isinstance(t, type(lu2))
            assert t == lu2.function_unit**power
            # also check we roundtrip
            t2 = t**(1. / power)
            assert t2 == lu2.function_unit
            with u.set_enabled_equivalencies(u.logarithmic()):
                assert_allclose(t2.to(u.dimensionless_unscaled, np.arange(3.)),
                                lu2.to(lu2.physical_unit, np.arange(3.)))

    @pytest.mark.parametrize('other', pu_sample)
    def test_addition_subtraction_to_normal_units_fails(self, other):
        lu1 = u.mag(u.Jy)
        with pytest.raises(u.UnitsError):
            lu1 + other

        with pytest.raises(u.UnitsError):
            lu1 - other

        with pytest.raises(u.UnitsError):
            other - lu1

    def test_addition_subtraction_to_non_units_fails(self):
        lu1 = u.mag(u.Jy)
        with pytest.raises(TypeError):
            lu1 + 1.

        with pytest.raises(TypeError):
            lu1 - [1., 2., 3.]

    @pytest.mark.parametrize('other', (u.mag, u.mag(), u.mag(u.Jy), u.mag(
        u.m), u.Unit(2 * u.mag), u.MagUnit('', 2. * u.mag)))
    def test_addition_subtraction(self, other):
        """Check physical units are changed appropriately"""
        lu1 = u.mag(u.Jy)
        other_pu = getattr(other, 'physical_unit', u.dimensionless_unscaled)

        lu_sf = lu1 + other
        assert lu_sf.is_equivalent(lu1.physical_unit * other_pu)

        lu_sr = other + lu1
        assert lu_sr.is_equivalent(lu1.physical_unit * other_pu)

        lu_df = lu1 - other
        assert lu_df.is_equivalent(lu1.physical_unit / other_pu)

        lu_dr = other - lu1
        assert lu_dr.is_equivalent(other_pu / lu1.physical_unit)

    def test_complicated_addition_subtraction(self):
        """for fun, a more complicated example of addition and subtraction"""
        dm0 = u.Unit('DM', 1. / (4. * np.pi * (10. * u.pc)**2))
        lu_dm = u.mag(dm0)
        lu_absST = u.STmag - lu_dm
        assert lu_absST.is_equivalent(u.erg / u.s / u.AA)

    def test_neg_pos(self):
        lu1 = u.mag(u.Jy)
        neg_lu = -lu1
        assert neg_lu != lu1
        assert neg_lu.physical_unit == u.Jy**-1
        assert -neg_lu == lu1
        pos_lu = +lu1
        assert pos_lu is not lu1
        assert pos_lu == lu1
예제 #12
0
 def nsa_absmags(self):
     absmags = np.array([
         nsa_absmag(self.drpall_row, band, kind='elpetro')
         for band in self.bands
     ]) * (u.ABmag - u.MagUnit(u.littleh**2))
     return absmags