示例#1
0
    def bandflux(self, band):
        """Perform synthentic photometry in a given bandpass.
      
        The bandpass transmission is interpolated onto the wavelength grid
        of the spectrum. The result is a weighted sum of the spectral flux
        density values (weighted by transmission values).
        
        Parameters
        ----------
        band : Bandpass object or name of registered bandpass.

        Returns
        -------
        bandflux : float
            Total flux in ph/s/cm^2. If part of bandpass falls
            outside the spectrum, `None` is returned instead.
        bandfluxerr : float
            Error on flux. Only returned if the `error` attribute is not
            `None`.
        """

        band = get_bandpass(band)
        bwave, btrans = band.to_unit(self._wunit)

        if (bwave[0] < self._wave[0] or
            bwave[-1] > self._wave[-1]):
            return None

        idx = ((self._wave > bwave[0]) & 
               (self._wave < bwave[-1]))
        d = self._wave[idx]
        f = self._flux[idx]

        #TODO: use spectral density equivalencies once they can do photons.
        # first convert to ergs / s /cm^2 / (wavelength unit)
        target_unit = u.erg / u.s / u.cm**2 / self._wunit
        if self._unit != target_unit:
            f = self._unit.to(target_unit, f, 
                              u.spectral_density(self._wunit, d))

        # Then convert ergs to photons: photons = Energy / (h * nu)
        f = f / const.h.cgs.value / self._wunit.to(u.Hz, d, u.spectral())

        trans = np.interp(d, bwave, btrans)
        binw = np.gradient(d)
        ftot = np.sum(f * trans * binw)

        if self._error is None:
            return ftot

        else:
            e = self._error[idx]

            # Do the same conversion as above
            if self._unit != target_unit:
                e = self._unit.to(target_unit, e, 
                                  u.spectral_density(self._wunit, d))
            e = e / const.h.cgs.value / self._wunit.to(u.Hz, d, u.spectral())
            etot = np.sqrt(np.sum((e * binw) ** 2 * trans))
            return ftot, etot
示例#2
0
def test_spectraldensity3():
    # Define F_nu in Jy
    f_nu = u.Jy

    # Define F_lambda in ergs / cm^2 / s / micron
    f_lambda = u.erg / u.cm ** 2 / u.s / u.micron

    # 1 GHz
    one_ghz = u.Quantity(1, u.GHz)

    # Convert to ergs / cm^2 / s / Hz
    assert_allclose(f_nu.to(u.erg / u.cm ** 2 / u.s / u.Hz, 1.), 1.e-23, 10)

    # Convert to ergs / cm^2 / s at 10 Ghz
    assert_allclose(f_nu.to(u.erg / u.cm ** 2 / u.s, 1.,
                    equivalencies=u.spectral_density(one_ghz * 10)),
                    1.e-13, 10)

    # Convert to F_lambda at 1 Ghz
    assert_allclose(f_nu.to(f_lambda, 1.,
                    equivalencies=u.spectral_density(one_ghz)),
                    3.335640951981521e-20, 10)

    # Convert to Jy at 1 Ghz
    assert_allclose(f_lambda.to(u.Jy, 1.,
                    equivalencies=u.spectral_density(one_ghz)),
                    1. / 3.335640951981521e-20, 10)

    # Convert to ergs / cm^2 / s at 10 microns
    assert_allclose(f_lambda.to(u.erg / u.cm ** 2 / u.s, 1.,
                    equivalencies=u.spectral_density(u.Quantity(10, u.micron))),
                    10., 10)
示例#3
0
文件: data.py 项目: pllim/specviz
    def set_units(self, disp_unit, data_unit):
        if self.dispersion_unit.is_equivalent(disp_unit,
                                              equivalencies=spectral()):
            self._dispersion = self.dispersion.data.to(
                disp_unit, equivalencies=spectral()).value

            # Finally, change the unit
            self.dispersion_unit = disp_unit
        else:
            logging.warning("Units are not compatible.")

        if self.unit.is_equivalent(data_unit,
                                   equivalencies=spectral_density(
                                       self.dispersion.data)):
            self._data = self.data.data.to(
                data_unit, equivalencies=spectral_density(
                    self.dispersion.data)).value

            self._uncertainty = self._uncertainty.__class__(
                self.raw_uncertainty.data.to(
                    data_unit, equivalencies=spectral_density(
                        self.dispersion.data)).value)

            # Finally, change the unit
            self._unit = data_unit
        else:
            logging.warning("Units are not compatible.")
def test_conversion_to_and_from_physical_quantities():
    """Ensures we can convert from regular quantities."""
    mst = [10., 12., 14.] * u.STmag
    flux_lambda = mst.physical
    mst_roundtrip = flux_lambda.to(u.STmag)
    # check we return a logquantity; see #5178.
    assert isinstance(mst_roundtrip, u.Magnitude)
    assert mst_roundtrip.unit == mst.unit
    assert_allclose(mst_roundtrip.value, mst.value)
    wave = [4956.8, 4959.55, 4962.3] * u.AA
    flux_nu = mst.to(u.Jy, equivalencies=u.spectral_density(wave))
    mst_roundtrip2 = flux_nu.to(u.STmag, u.spectral_density(wave))
    assert isinstance(mst_roundtrip2, u.Magnitude)
    assert mst_roundtrip2.unit == mst.unit
    assert_allclose(mst_roundtrip2.value, mst.value)
示例#5
0
def test_conversion_to_and_from_physical_quantities():
    """Ensures we can convert from regular quantities."""
    mst = [10., 12., 14.] * u.STmag
    flux_lambda = mst.physical
    mst_roundtrip = flux_lambda.to(u.STmag)
    # check we return a logquantity; see #5178.
    assert isinstance(mst_roundtrip, u.Magnitude)
    assert mst_roundtrip.unit == mst.unit
    assert_allclose(mst_roundtrip.value, mst.value)
    wave = [4956.8, 4959.55, 4962.3] * u.AA
    flux_nu = mst.to(u.Jy, equivalencies=u.spectral_density(wave))
    mst_roundtrip2 = flux_nu.to(u.STmag, u.spectral_density(wave))
    assert isinstance(mst_roundtrip2, u.Magnitude)
    assert mst_roundtrip2.unit == mst.unit
    assert_allclose(mst_roundtrip2.value, mst.value)
示例#6
0
def _bbChi(stuff, wave, flux):
    temp, const = stuff
    bb = BlackBody1D(temperature=temp * u.K)
    bbFlux = [x.value for x in bb(wave).to(FLAM, u.spectral_density(wave))]

    bbFlux = [x * const for x in bbFlux]
    return _chisq(bbFlux, flux)
示例#7
0
def main():

    # commandline parser
    parser = initialize_parser()
    args = parser.parse_args()

    # read an observed spectrum
    # read in the observed spectrum
    # assumed to be astropy table compatibile and include units
    specfile = args.spectrumfile
    outputname = specfile.split(".")[0]
    if not os.path.isfile(specfile):
        pack_path = pkg_resources.resource_filename("pahfit", "data/")
        test_specfile = "{}/{}".format(pack_path, specfile)
        if os.path.isfile(test_specfile):
            specfile = test_specfile
        else:
            raise ValueError(
                "Input spectrumfile {} not found".format(specfile))

    # get the table format (from extension of filename)
    tformat = specfile.split(".")[-1]
    if tformat == "ecsv":
        tformat = "ascii.ecsv"
    obs_spectrum = Table.read(specfile, format=tformat)
    obs_x = obs_spectrum["wavelength"].to(u.micron, equivalencies=u.spectral())
    obs_y = obs_spectrum["flux"].to(u.Jy,
                                    equivalencies=u.spectral_density(obs_x))

    # strip units as the observed spectrum is in the internal units
    obs_x = obs_x.value
    obs_y = obs_y.value

    # read in the PAHFIT results
    pmodel = PAHFITBase(obs_x, obs_y, filename=args.fitfilename)

    # plot result
    fontsize = 18
    font = {"size": fontsize}
    mpl.rc("font", **font)
    mpl.rc("lines", linewidth=2)
    mpl.rc("axes", linewidth=2)
    mpl.rc("xtick.major", width=2)
    mpl.rc("ytick.major", width=2)

    fig, ax = plt.subplots(figsize=(15, 10))

    pmodel.plot(ax, obs_x, obs_y, pmodel.model)

    ax.set_yscale("linear")
    ax.set_xscale("log")

    # use the whitespace better
    fig.tight_layout()

    # show or save
    if args.savefig:
        fig.savefig("{}.{}".format(outputname, args.savefig))
    else:
        plt.show()
示例#8
0
def bbfunc(wavelengths, temperature):
    """Planck law for blackbody radiation in PHOTLAM per steradian.

    Parameters
    ----------
    wavelengths : array_like or `astropy.units.quantity.Quantity`
        Wavelength values. If not a Quantity, assumed to be in Angstrom.

    temperature : float or `astropy.units.quantity.Quantity`
        Blackbody temperature. If not a Quantity, assumed to be in Kelvin.

    Returns
    -------
    fluxes : `astropy.units.quantity.Quantity`
        Blackbody radiation in PHOTLAM per steradian.

    """
    if not isinstance(wavelengths, u.Quantity):
        wavelengths = u.Quantity(wavelengths, unit=u.AA)

    # Calculations must use Hz
    freq = wavelengths.to(u.Hz, equivalencies=u.spectral())

    # Calculations must use Kelvin
    temperature = units.validate_quantity(temperature, u.K)

    # Calculate blackbody radiation in FNU, then convert to PHOTLAM
    factor = np.expm1(const.h * freq / (const.k_B * temperature))
    bb_nu = 2 * const.h * freq * freq * freq / (const.c ** 2 * factor)
    bb_lam = units.FNU.to(units.PHOTLAM, bb_nu.cgs.value,
                          equivalencies=u.spectral_density(wavelengths))

    return u.Quantity(bb_lam, unit=units.PHOTLAM/u.sr)
示例#9
0
def calculate_f_xuv(spectrum):
    """
    Calculates the total XUV flux given the spectrum at the planet (Equation
    14 of Vissapragada et al. 2022, where the minimum threshold is 13.6 eV. This
    function currently assumes the spectrum is truncated at 13.6 eV and does not
    include lower energies. 

    Parameters
    ----------
    spectrum (``dict``):
        Spectrum of the host star arriving at the planet covering fluxes up to
        the wavelength corresponding to the energy to ionize hydrogen (13.6 eV,
        or 911.65 Angstrom). Can be generated using ``tools.make_spectrum_dict``
        or ``tools.generate_muscles_spectrum``. Currently we assume that the
        spectrum does not include lower energies than 13.6 eV.
    Returns
    -------
    f_xuv (``astropy.Quantity``):
        The integrated XUV flux.
    """
    wav_grid = spectrum['wavelength'] * spectrum['wavelength_unit']
    flux_grid = spectrum['flux_lambda'] * spectrum['flux_unit']
    flux_grid = flux_grid.to(u.erg / u.s / u.cm / u.cm / u.Hz,
                             equivalencies=u.spectral_density(wav_grid))
    wavs_hz = wav_grid.to(u.Hz, equivalencies=u.spectral())[::-1]
    flux_grid = flux_grid[::-1]
    f_xuv = simpson(flux_grid, x=wavs_hz) * u.erg / u.s / u.cm**2
    return f_xuv
示例#10
0
def spec_av_cross(r_grid, spectrum, t_coef, species):
    """
    Calculates the heating cross-section for photoionization using Equation (16)
    of Vissapragada et al. (2022).

    Parameters
    ----------
    r_grid (``numpy.ndarray``):
        The radius grid for the calculation. An astropy unit (like u.Rjup) must
        be specified for each value on the grid.
  
    spectrum (``dict``):
        Spectrum of the host star arriving at the planet covering fluxes up to
        the wavelength corresponding to the energy to ionize hydrogen (13.6 eV,
        or 911.65 Angstrom). Can be generated using ``tools.make_spectrum_dict``
        or ``tools.generate_muscles_spectrum``. Currently we assume that the
        spectrum does not include lower energies than 13.6 eV.

    t_coef (``numpy.ndarray``):
        The transmission coefficient profile for the wind as a function of 
        frequency and altitude. In the optically-thin part of the outflow this
        should be very close to 1.
 
    species (``str``):
        The photoionzation target for which we are calculating the heating
        cross-section. Must be one of 'hydrogen', 'helium', or 'helium+'.
    Returns
    -------
    cross (``astropy.Quantity``):
        Heating cross-section in cm**2 for the selected species.
    """
    wav_grid = spectrum['wavelength'] * spectrum['wavelength_unit']
    flux_grid = spectrum['flux_lambda'] * spectrum['flux_unit']
    flux_grid = flux_grid.to(u.erg / u.s / u.cm / u.cm / u.Hz,
                             equivalencies=u.spectral_density(wav_grid))
    wavs_hz = wav_grid.to(u.Hz, equivalencies=u.spectral())[::-1]
    flux_grid = flux_grid[::-1]
    xx, yy = np.meshgrid(wavs_hz, r_grid)

    threshold = threshes[species]
    crosses = {
        'hydrogen': h_photo_cross,
        'helium': helium_photo_cross,
        'helium+': heplus_photo_cross
    }
    cross = crosses[species]
    evgrid = xx.to(u.eV, equivalencies=u.spectral())
    eta_grid = 1 - threshold / evgrid
    spec_grid, __ = np.meshgrid(flux_grid, r_grid)
    crossgrid = cross(xx)
    crossgrid[xx.to(u.eV, equivalencies = u.spectral()) < \
        threshold] = 0.*u.cm**2

    numgrid = eta_grid * spec_grid * crossgrid * t_coef
    numgrid = numgrid.to(u.erg / u.s / u.Hz)
    num = simpson(numgrid, x=wavs_hz, axis=-1) * u.erg / u.s

    F_XUV = calculate_f_xuv(spectrum)
    cross = num / F_XUV
    return cross.to(u.cm**2)
示例#11
0
文件: utils.py 项目: cwfinn/igmtools
def flux2mag(flux, band):
    """
    Converts flux in erg / s / cm^2 / Angstrom to AB magnitudes.

    flux : float
        Flux (erg / s / cm^2 / Angstrom).

    band : `igmtools.photometry.Passband`
        The passband.

    Returns
    -------
    magnitude : float
        AB magnitude.

    """

    if hasattr(flux, 'unit'):
        flux = flux.to(erg / s / cm**2 / angstrom)

    else:
        flux = flux * erg / s / cm**2 / angstrom

    fnu = flux.to(erg / s / cm**2 / Hz,
                  equivalencies=spectral_density(band.effective_wavelength))
    magnitude = -2.5 * log10(fnu.value) - 48.6

    return magnitude
示例#12
0
文件: utils.py 项目: cwfinn/igmtools
def mag2flux(magnitude, band):
    """
    Converts a given AB magnitude into flux in the given band in
    erg / s / cm^2 / Angstrom.

    Parameters
    ----------
    magnitude : float
        AB magnitude.

    band : `igmtools.photometry.Passband`
        The passband.

    Returns
    -------
    flux : `astropy.units.Quantity`
        Flux in erg / s / cm^2 / Angstrom.

    """

    fnu = 10**(-(magnitude + 48.6) / 2.5) * erg / s / cm**2 / Hz
    flux = fnu.to(erg / s / cm**2 / angstrom,
                  equivalencies=spectral_density(band.effective_wavelength))

    return flux
示例#13
0
    def _show_arithmetic_dialog(self):
        if self.viewer.current_layer is None:
            return

        if self.viewer._layer_arithmetic_dialog.exec_():
            formula = self.viewer._layer_arithmetic_dialog\
                .ui_layer_arithmetic_dialog.formulaLineEdit.text()

            current_window = self.viewer.current_sub_window
            current_layers = window_manager.get_layers(current_window)
            new_layer = layer_manager.add_from_formula(formula,
                                                       layers=current_layers)

            if new_layer is None:
                logging.warning("Formula not valid.")
                return

            # If units match, plot the resultant on the same sub window,
            # otherwise create a new sub window to plot the spectra
            data_units_equiv = new_layer.data.unit.is_equivalent(
                current_window._plot_units[1],
                equivalencies=spectral_density(new_layer.dispersion))
            disp_units_equiv = new_layer.dispersion.unit.is_equivalent(
                current_window._plot_units[0], equivalencies=spectral())

            if data_units_equiv and disp_units_equiv:
                self.add_sub_window(layer=new_layer, window=current_window)
            else:
                logging.info("{} not equivalent to {}.".format(
                    new_layer.data.unit, current_window._plot_units[1]))
                self.add_sub_window(layer=new_layer)
示例#14
0
    def get_thermal_emission(self, wvs, band="TwoMass-J"):
        '''
        The telescope emission as a function of wavelength

        Outputs:
        thermal_emission - usnits of photons/s/cm**2/angstrom
        '''

        diffraction_limit = (wvs / self.diameter.to(u.micron) * u.radian).to(
            u.arcsec)
        solidangle = diffraction_limit**2 * 1.13

        # TODO: blackbody_lambda is deprecated, change to BlackBody
        #bb_lam = BlackBody(self.temperature,scale=1.0*u.erg/(u.cm**2*u.AA*u.s*u.sr))
        #inst_therm = bb_lam(wvs)

        thermal_emission = blackbody_lambda(wvs, self.temperature)
        thermal_emission *= solidangle
        thermal_emission = thermal_emission.to(
            u.ph / (u.s * u.cm**2 * u.AA),
            equivalencies=u.spectral_density(wvs))

        thermal_emission *= self.get_telescope_emissivity(wvs, band=band)

        return thermal_emission
示例#15
0
    def withFluxDensity(self, target_flux_density, wavelength):
        """ Return a new SED with flux density set to `target_flux_density` at wavelength
        `wavelength`.  See ChromaticObject docstring for information about how SED normalization
        affects ChromaticObject normalization.

        @param target_flux_density  The target normalization in photons/nm/cm^2/s.
        @param wavelength           The wavelength, in nm, at which the flux density will be set.

        @returns the new normalized SED.
        """
        from astropy import units
        _photons = units.astrophys.photon/(units.s * units.cm**2 * units.nm)

        if self.dimensionless:
            raise TypeError("Cannot set flux density of dimensionless SED.")
        if isinstance(wavelength, units.Quantity):
            wavelength_nm = wavelength.to(units.nm, units.spectral())
            current_flux_density = self(wavelength_nm.value)
        else:
            wavelength_nm = wavelength * units.nm
            current_flux_density = self(wavelength)
        if isinstance(target_flux_density, units.Quantity):
            target_flux_density = target_flux_density.to(
                    _photons, units.spectral_density(wavelength_nm)).value
        factor = target_flux_density / current_flux_density
        return self * factor
示例#16
0
def plot_3cr(t):
    """ Reproduction of Stockton & Ridgway 1996 """
    jy = t["S_178_"]  # already in units of Janksy b/c Vizier astroquery
    # Convert Janksy to SI equivalent
    power = jy.to(u.W / u.m**2 / u.Hz,
                  equivalencies=u.spectral_density(178 * u.MHz))
    # Stockton & Ridgway assume H0 = 50 km/s/Mpc, we take 70
    distance = [CosmologyCalculator(z, 70).DL_Mpc for z in t["z"]]
    t["P"] = power  # already has units
    t["d"] = distance * u.Mpc

    # Sketchy factor pi. 4*pi would be understandable, but now plot matches
    # when H_0 = 50
    p178 = numpy.pi*t["d"].to(u.m)**2 * t["P"]

    pyplot.figure(figsize=(12,12))
    pyplot.scatter(t["z"], p178, marker="+", s=50, c="k")
    for i in ["405.0", "348.0", "123.0", "20.0", "427.1",
                "295.0", "265.0", "237.0", "268.1", "280.0"]:
        index = numpy.where(t["_3CR"] == i)[0][0]
        pyplot.text(t[index]["z"], p178[index].value,
                    i[:-2] if i[-1]=="0" else i, fontsize=22)
    pyplot.xlim(-0.05, 1.1)
    pyplot.ylim(-1.5e27, 3.2e28)
    pyplot.xlabel(r"$z$")
    pyplot.ylabel(r"$P_{178}$ (W Hz$^{-1}$)")
    pyplot.savefig("out/3CR.pdf", dpi=300)
示例#17
0
    def _find_spectral_column(table, columns_to_search, spectral_axis):
        """
        Figure out which column in a table holds the fluxes or uncertainties.
        Take the first column that has units compatible with
        u.spectral_density() equivalencies. If none meet that criterion,
        look for other likely length units such as 'adu' or 'cts/s'.
        """
        additional_valid_units = [u.Unit('adu'), u.Unit('ct/s')]
        found_column = None

        # First, search for a column with units compatible with Janskies
        for c in columns_to_search:
            try:
                # Check for multi-D flux columns
                if table[c].ndim == 1:
                    spec_ax = spectral_axis
                else:
                    # Assume leading dimension corresponds to spectral_axis
                    spec_shape = np.ones(table[c].ndim, dtype=np.int)
                    spec_shape[0] = -1
                    spec_ax = spectral_axis.reshape(spec_shape)
                table[c].to("Jy", equivalencies=u.spectral_density(spec_ax))
                found_column = c
                break
            except:
                continue

        # If no success there, check for other possible flux units
        if found_column is None:
            for c in columns_to_search:
                if table[c].unit in additional_valid_units:
                    found_column = c
                    break

        return found_column
示例#18
0
    def _calculate_spectrum(self, solar_path):
        """
        Pre-calculates absolute surface brightness spectral flux density of the Zodiacal Light at the ecliptic poles.
        """
        # Load absolute solar spectrum from Collina, Bohlin & Castelli (1996)
        sun = fits.open(solar_path)
        sun_waves = sun[1].data['WAVELENGTH'] * u.Angstrom
        # sfd = spectral flux density
        sun_sfd = sun[1].data[
            'FLUX'] * u.erg * u.second**-1 * u.cm**-2 * u.Angstrom**-1

        self.waves = sun_waves.to(u.micron)

        # Covert to zodiacal light spectrym by following the normalisation and reddening
        # prescription of Leinert et al (1997) with the revised parameters from
        # Aldering (2001), as used in the HST ETC (Giavalsico, Sahi, Bohlin (2202)).

        # Reddening factor
        rfactor = np.where(sun_waves < ZodiacalLight.lambda_c, \
                           1.0 + ZodiacalLight.f_blue * np.log(sun_waves/ZodiacalLight.lambda_c), \
                           1.0 + ZodiacalLight.f_red * np.log(sun_waves/ZodiacalLight.lambda_c))
        # Apply normalisation and reddening
        sfd = sun_sfd * ZodiacalLight.zl_normalisation * rfactor
        # #DownWithErgs
        self.sfd = sfd.to(u.Watt * u.m**-2 * u.arcsecond**-2 * u.micron**-1)
        # Also calculate in photon spectral flux density units. Fudge needed because equivalencies
        # don't currently include surface brightness units.
        fudge = sfd * u.arcsecond**2
        fudge = fudge.to(u.photon * u.second**-1 * u.m**-2 * u.micron**-1,
                         equivalencies=u.spectral_density(self.waves))
        self.photon_sfd = fudge / u.arcsecond**2
示例#19
0
文件: calib.py 项目: migueldvb/mskpy
def e490(smooth=False, unit=u.Unit('W/(m2 um)')):
    """The ASTM (2000) E490-00 solar spectrum (at 1 AU).

    Parameters
    ----------
    smooth : bool
      Return a lower-resolution (histogrammed) spectrum (see Notes).
    unit : astropy Unit
      Return flux in these units (must be spectral flux density).

    Returns
    -------
    w : Quantity
      Spectrum wavelength.
    f : Quantity
      Spectrum flux density.

    Notes
    -----
    The smoothed spectrum, up to 10 um, is the original E490 table,
    rebinned.  At > 10 um, the original resolution is retained.

    """
    if smooth:
        w, f = np.loadtxt(_e490_sm).T
    else:
        w, f = np.loadtxt(_e490).T

    w = w * u.um
    f = f * u.W / u.m**2 / u.um
    if f.unit != unit:
        equiv = u.spectral_density(w.unit, w.value)
        f = f.to(unit, equivalencies=equiv)

    return w, f
示例#20
0
    def evaluate(x, temperature):
        """Evaluate the model.

        Parameters
        ----------
        x : number or ndarray
            Wavelengths in Angstrom.

        temperature : number
            Temperature in Kelvin.

        Returns
        -------
        y : number or ndarray
            Blackbody radiation in PHOTLAM per steradian.

        """
        # Silence Numpy
        old_np_err_cfg = np.seterr(all='ignore')

        wave = u.Quantity(np.ascontiguousarray(x), unit=u.AA)
        bbnu_flux = blackbody_nu(wave, temperature)
        bbflux = (bbnu_flux * u.sr).to(
            units.PHOTLAM, u.spectral_density(wave)) / u.sr  # PHOTLAM/sr

        # Restore Numpy settings
        dummy = np.seterr(**old_np_err_cfg)

        return bbflux.value
示例#21
0
文件: units.py 项目: krislars/synphot
def spectral_density_vega(wav, vegaflux):
    """Flux equivalencies between PHOTLAM and VEGAMAG.

    Parameters
    ----------
    wav : `~astropy.units.quantity.Quantity`
        Quantity associated with values being converted
        (e.g., wavelength or frequency).

    vegaflux : `~astropy.units.quantity.Quantity`
        Flux of Vega at ``wav``.

    Returns
    -------
    eqv : list
        List of equivalencies.

    """
    vega_photlam = vegaflux.to(PHOTLAM,
                               equivalencies=u.spectral_density(wav)).value

    def converter(x):
        """Set nan/inf to -99 mag."""
        val = -2.5 * np.log10(x / vega_photlam)
        result = np.zeros(val.shape, dtype=np.float64) - 99
        mask = np.isfinite(val)
        result[mask] = val[mask]
        return result

    def iconverter(x):
        return vega_photlam * 10**(-0.4 * x)

    return [(PHOTLAM, VEGAMAG, converter, iconverter)]
示例#22
0
    def convert_value(self, value, wave=None, new_unit=None):
        if isinstance(value, Quantity):
            value = value.value
        elif not isinstance(value, int) \
                and not isinstance(value, float) \
                and not isinstance(value, np.ndarray):
            raise ValueError("Expected float or int, got {} instead.".format(type(value)))

        if self.type in [NONE_CubeVizUnit, UNKNOWN_CubeVizUnit]:
            return value

        new_value = value

        if new_unit is None:
            new_unit = self._unit

        if hasattr(u.spectral_density, "pixel_area"):
            u.spectral_density.pixel_area = self.controller.pixel_area

        if wave is not None:
            new_value = (value * self._original_unit).to(new_unit, equivalencies=u.spectral_density(wave)).value
        else:
            new_value = (value * self._original_unit).to(new_unit).value

        if isinstance(new_value, Quantity):
            new_value = new_value.value

        return new_value
示例#23
0
    def __init__(self,
                 wave,
                 flux,
                 wave_unit=u.AA,
                 unit=(u.erg / u.s / u.cm**2 / u.AA)):
        self.wave = np.asarray(wave, dtype=np.float64)
        self.flux = np.asarray(flux, dtype=np.float64)
        if self.wave.shape != self.flux.shape:
            raise ValueError('shape of wavelength and flux must match')
        if self.wave.ndim != 1:
            raise ValueError('only 1-d arrays supported')

        # internally, wavelength is in Angstroms:
        if wave_unit != u.AA:
            self.wave = wave_unit.to(u.AA, self.wave, u.spectral())
        self._wave_unit = u.AA

        # internally, flux is in F_lambda:
        if unit != FLAMBDA_UNIT:
            self.flux = unit.to(FLAMBDA_UNIT, self.flux,
                                u.spectral_density(u.AA, self.wave))
        self._unit = FLAMBDA_UNIT

        # Set up interpolation.
        # This appears to be the fastest-evaluating interpolant in
        # scipy.interpolate.
        self._tck = splrep(self.wave, self.flux, k=1)
示例#24
0
    def __init__(self, *args, **kwargs):
        fwhm = kwargs.pop('fwhm', None)
        total_flux = kwargs.pop('total_flux', None)

        super(GaussianFlux1D, self).__init__(*args, **kwargs)

        if fwhm is None:
            fwhm = self.stddev * gaussian_sigma_to_fwhm
        else:
            self.stddev = fwhm * gaussian_fwhm_to_sigma

        gaussian_amp_to_totflux = np.sqrt(2.0 * np.pi) * self.stddev

        if total_flux is None:
            u_str = 'PHOTLAM'
            total_flux = self.amplitude * gaussian_amp_to_totflux
        else:
            u_str = 'FLAM'
            # total_flux is passed in unaltered, any conversion error would
            # happen here.
            tf_unit = u.erg / (u.cm * u.cm * u.s)
            if isinstance(total_flux, u.Quantity):
                total_flux = total_flux.to(tf_unit)
            else:
                total_flux = total_flux * tf_unit
            self.amplitude = (total_flux /
                              (gaussian_amp_to_totflux * u.AA)).to(
                                  units.PHOTLAM,
                                  u.spectral_density(self.mean.value *
                                                     u.AA)).value  # noqa
            total_flux = total_flux.value

        self.meta['expr'] = 'em({0:g}, {1:g}, {2:g}, {3})'.format(
            self.mean.value, fwhm, total_flux, u_str)
示例#25
0
文件: items.py 项目: bsipocz/specviz
 def flux(self):
     """
     Converts data_item.flux - which consists of the flux axis with units - into the new flux unit
     """
     return self.data_item.flux.to(self.data_unit,
                                   equivalencies=spectral_density(
                                       self.data_item.spectral_axis)).value
示例#26
0
文件: fit_bb.py 项目: dmargala/blupe
def blackbody_lambda(in_x, temperature):
    """Like :func:`blackbody_nu` but for :math:`B_{\\lambda}(T)`.

    Parameters
    ----------
    in_x : number, array-like, or `~astropy.units.Quantity`
        Frequency, wavelength, or wave number.
        If not a Quantity, it is assumed to be in Angstrom.

    temperature : number or `~astropy.units.Quantity`
        Blackbody temperature.
        If not a Quantity, it is assumed to be in Kelvin.

    Returns
    -------
    flux : `~astropy.units.Quantity`
        Blackbody monochromatic flux in
        :math:`erg \\; cm^{-2} s^{-1} \\AA^{-1} sr^{-1}`.

    """
    if getattr(in_x, 'unit', None) is None:
        in_x = u.Quantity(in_x, u.AA)

    bb_nu = blackbody_nu(in_x, temperature) * u.sr  # Remove sr for conversion
    flux = bb_nu.to(FLAM, u.spectral_density(in_x))

    return flux / u.sr  # Add per steradian to output flux unit
示例#27
0
    def convert(self, wave, flux, exception=False):
        ''' Convert arrays to target units.

        Parameters
        ----------
        wave: Quantity
          spectral coordinate array to be converted to target units
        flux: Quantity
          flux array to be converted to target units
        exception: boolean, optional, default=False
          if False, a units conversion exception will result in an
          error message being printed at the console. If True, the
          error message is printed AND the exception is raised again.
          This behavior helps in debugging scripts.

        Returns
        -------
           two Quantity instances with the converted wave and flux arrays.
           In case of error, the original input references are returned.
        '''
        try:
            converted_wave = wave.to(self._wunit, equivalencies=u.spectral())
            converted_flux = flux.to(self._funit, equivalencies=u.spectral_density(wave))

            return converted_wave, converted_flux

        except (ValueError, astropy.units.core.UnitsError) as e:
            print("UNITS CONVERSION ERROR: ", e, file=sys.stderr)
            if exception:
                raise e
            return wave, flux
示例#28
0
文件: calib.py 项目: migueldvb/mskpy
def e490(smooth=False, unit=u.Unit('W/(m2 um)')):
    """The ASTM (2000) E490-00 solar spectrum (at 1 AU).

    Parameters
    ----------
    smooth : bool
      Return a lower-resolution (histogrammed) spectrum (see Notes).
    unit : astropy Unit
      Return flux in these units (must be spectral flux density).

    Returns
    -------
    w : Quantity
      Spectrum wavelength.
    f : Quantity
      Spectrum flux density.

    Notes
    -----
    The smoothed spectrum, up to 10 um, is the original E490 table,
    rebinned.  At > 10 um, the original resolution is retained.

    """
    if smooth:
        w, f = np.loadtxt(_e490_sm).T
    else:
        w, f = np.loadtxt(_e490).T

    w = w * u.um
    f = f * u.W / u.m**2 / u.um
    if f.unit != unit:
        equiv = u.spectral_density(w.unit, w.value)
        f = f.to(unit, equivalencies=equiv)

    return w, f
示例#29
0
def spectral_density_vega(wav, vegaflux):
    """Flux equivalencies between PHOTLAM and VEGAMAG.

    Parameters
    ----------
    wav : `~astropy.units.quantity.Quantity`
        Quantity associated with values being converted
        (e.g., wavelength or frequency).

    vegaflux : `~astropy.units.quantity.Quantity`
        Flux of Vega at ``wav``.

    Returns
    -------
    eqv : list
        List of equivalencies.

    """
    vega_photlam = vegaflux.to(
        PHOTLAM, equivalencies=u.spectral_density(wav)).value

    def converter(x):
        """Set nan/inf to -99 mag."""
        val = -2.5 * np.log10(x / vega_photlam)
        result = np.zeros(val.shape, dtype=np.float64) - 99
        mask = np.isfinite(val)
        result[mask] = val[mask]
        return result

    def iconverter(x):
        return vega_photlam * 10**(-0.4 * x)

    return [(PHOTLAM, VEGAMAG, converter, iconverter)]
示例#30
0
    def _show_arithmetic_dialog(self):
        if self.viewer.current_layer is None:
            return

        if self.viewer._layer_arithmetic_dialog.exec_():
            formula = self.viewer._layer_arithmetic_dialog\
                .ui_layer_arithmetic_dialog.formulaLineEdit.text()

            current_window = self.viewer.current_sub_window
            current_layers = window_manager.get_layers(current_window)
            new_layer = layer_manager.add_from_formula(formula,
                                                       layers=current_layers)

            if new_layer is None:
                logging.warning("Formula not valid.")
                return

            # If units match, plot the resultant on the same sub window,
            # otherwise create a new sub window to plot the spectra
            data_units_equiv = new_layer.data.unit.is_equivalent(
                current_window._plot_units[1],
                equivalencies=spectral_density(new_layer.dispersion))
            disp_units_equiv = new_layer.dispersion.unit.is_equivalent(
                current_window._plot_units[0], equivalencies=spectral())

            if data_units_equiv and disp_units_equiv:
                self.add_sub_window(layer=new_layer, window=current_window)
            else:
                logging.info("{} not equivalent to {}.".format(
                    new_layer.data.unit, current_window._plot_units[1]))
                self.add_sub_window(layer=new_layer)
示例#31
0
    def convert_value(self, value, wave=None, new_unit=None):
        if isinstance(value, Quantity):
            value = value.value
        elif not isinstance(value, int) \
                and not isinstance(value, float) \
                and not isinstance(value, np.ndarray):
            raise ValueError("Expected float or int, got {} instead.".format(
                type(value)))

        if self.type in [NONE_CubeVizUnit, UNKNOWN_CubeVizUnit]:
            return value

        new_value = value

        if new_unit is None:
            new_unit = self._unit

        if hasattr(u.spectral_density, "pixel_area"):
            u.spectral_density.pixel_area = self.controller.pixel_area

        if wave is not None:
            new_value = (value * self._original_unit).to(
                new_unit, equivalencies=u.spectral_density(wave)).value
        else:
            new_value = (value * self._original_unit).to(new_unit).value

        if isinstance(new_value, Quantity):
            new_value = new_value.value

        return new_value
示例#32
0
    def calibrate_flux(self, hdu):
        '''
        do flux calibration by undoing what the simulator did so far (as much as possible)
        input is the result of compute_snr()
        '''
        data = hdu.data * u.electron	# per dit, pixel, spectral channel, and M1-area

        mirr_list = self.cmds.mirrors_telescope
        mirr_area = np.pi / 4 * np.sum(mirr_list["Outer"]**2 - \
                                       mirr_list["Inner"]**2) * u.m**2

        data = data / (hdu.header['EXPTIME'] * u.s
                       * (np.mean(self.wavelen)*u.um * (1.5 *u.km/u.s) / const.c).to(u.um)
                       * mirr_area)
        # e-/s/um/m2

        # wavelengths of data cube
        det_wavelen = (self.det_velocities
                       * u.m/u.s).to(u.um, equivalencies=u.doppler_optical(self.restcoo))

        # interpolate transmission onto wavelength-grid of detector:
        trans = np.interp(det_wavelen.value, self.wavelen, self.transmission)

        data /= trans[:, np.newaxis, np.newaxis]

        data = (data * u.photon/u.electron).to(u.Jy,
                                               equivalencies=u.spectral_density(self.restcoo))

        data = data / (self.det_pixscale/1000. * u.arcsec)**2
        # Jy/arcsec2

        calhdu = fits.PrimaryHDU(data.value, header=hdu.header)
        calhdu.header['BUNIT'] = ('Jy/arcsec2', 'Jansky per arcsec**2')
        return calhdu
示例#33
0
    def withFluxDensity(self, target_flux_density, wavelength):
        """ Return a new SED with flux density set to `target_flux_density` at wavelength
        `wavelength`.  See ChromaticObject docstring for information about how SED normalization
        affects ChromaticObject normalization.

        @param target_flux_density  The target normalization in photons/nm/cm^2/s.
        @param wavelength           The wavelength, in nm, at which the flux density will be set.

        @returns the new normalized SED.
        """
        from astropy import units
        _photons = units.astrophys.photon / (units.s * units.cm**2 * units.nm)

        if self.dimensionless:
            raise TypeError("Cannot set flux density of dimensionless SED.")
        if isinstance(wavelength, units.Quantity):
            wavelength_nm = wavelength.to(units.nm, units.spectral())
            current_flux_density = self(wavelength_nm.value)
        else:
            wavelength_nm = wavelength * units.nm
            current_flux_density = self(wavelength)
        if isinstance(target_flux_density, units.Quantity):
            target_flux_density = target_flux_density.to(
                _photons, units.spectral_density(wavelength_nm)).value
        factor = target_flux_density / current_flux_density
        return self * factor
示例#34
0
文件: utils.py 项目: cwfinn/igmtools
def flux2mag(flux, band):
    """
    Converts flux in erg / s / cm^2 / Angstrom to AB magnitudes.

    flux : float
        Flux (erg / s / cm^2 / Angstrom).

    band : `igmtools.photometry.Passband`
        The passband.

    Returns
    -------
    magnitude : float
        AB magnitude.

    """

    if hasattr(flux, "unit"):
        flux = flux.to(erg / s / cm ** 2 / angstrom)

    else:
        flux = flux * erg / s / cm ** 2 / angstrom

    fnu = flux.to(erg / s / cm ** 2 / Hz, equivalencies=spectral_density(band.effective_wavelength))
    magnitude = -2.5 * log10(fnu.value) - 48.6

    return magnitude
def flux_to_dust(flux, z, temp, distance, wavelength_observed):
	#convert lamda obs into lamda emmit as well as convert micron to m
	wavelength = (wavelength_observed * 1E-6)   / (z + 1.0)
	d = distance*3.08567758E22 #converts Mpc to m

	#find conversion factor for jy to si
	lm3 = u.W*u.m**-2*u.m**-1
	jy_to_si = u.Jy.to(lm3, equivalencies=u.spectral_density(u.m,wavelength))

	#convert flux in Jy to Si Units
	s = flux*jy_to_si

	#find kappa note beta is fixed at 2
	k_l = kappa(wavelength)

	#find value of plack equation
	b_l = planck(wavelength,temp) 

	#caculate dust mass in kg
	mass = (s * d**2) / (k_l * b_l)

	#convert to log10(Dust/Msol)
	m = np.log10(mass/2E30)

	return m
示例#36
0
def blackbody_lambda(wavelength, temperature):
    """
    Calculate the blackbody spectral density per unit wavelength.

    Parameters
    ----------
    wavelength : `~astropy.units.Quantity`
        Wavelength array to evaluate on.

    temperature : `~astropy.units.Quantity`
        Blackbody temperature.
    """

    # Convert to units for calculations, also force double precision
    with u.add_enabled_equivalencies(u.spectral() + u.temperature()):
        freq = u.Quantity(wavelength, u.Hz, dtype=np.float64)
        temp = u.Quantity(temperature, u.K, dtype=np.float64)

    log_boltz = const.h * freq / (const.k_B * temp)
    boltzm1 = np.expm1(log_boltz)

    bb_nu = (2.0 * const.h * freq ** 3 / (const.c ** 2 * boltzm1))

    flam = u.erg / (u.cm**2 * u.s * u.AA)
    flux = bb_nu.to(flam, u.spectral_density(wavelength))

    return flux / u.sr  # Add per steradian to output flux unit
示例#37
0
    def convert_from_original_unit(self, value, wave=None, **kwargs):
        """
        Given a value from the data, convert it to current
        units.
        :param value: float
        :param wave: float: wavelength
        :param kwargs:
        :return: converted value
        """
        if self.unit is None and wave is None:
            return value

        new_value = value

        new_value *= 10**(self._original_power - self.power)
        new_value *= self._original_spectral_flux_density.to(self.spectral_flux_density,
                                                             equivalencies=u.spectral_density(wave))
        if self.has_area:
            pixel_area = self.controller.pixel_area

            if self.area.decompose() == u.pix.decompose() \
                    and 'solid angle' in self._original_area.physical_type:
                area = (self._original_area / pixel_area).decompose()
                new_value /= area.to(self.area)
            elif 'solid angle' in self.area.physical_type \
                    and self._original_area.decompose() == u.pix.decompose():
                area = (self._original_area * pixel_area).decompose()
                new_value /= area.to(self.area)
            else:
                new_value /= self._original_area.to(self.area)

        if isinstance(new_value, u.Quantity):
            new_value = new_value.value

        return new_value
示例#38
0
    def evaluate(x, temperature):
        """Evaluate the model.

        Parameters
        ----------
        x : number or ndarray
            Wavelengths in Angstrom.

        temperature : number
            Temperature in Kelvin.

        Returns
        -------
        y : number or ndarray
            Blackbody radiation in PHOTLAM per steradian.

        """
        # Silence Numpy
        old_np_err_cfg = np.seterr(all="ignore")

        wave = np.ascontiguousarray(x) * u.AA
        bbnu_flux = blackbody_nu(wave, temperature)
        bbflux = (bbnu_flux * u.sr).to(units.PHOTLAM, u.spectral_density(wave)) / u.sr  # PHOTLAM/sr

        # Restore Numpy settings
        np.seterr(**old_np_err_cfg)

        return bbflux.value
示例#39
0
def convert_specific_intensity(wavelength: np.ndarray,
                               specInt: np.ndarray, outUnits) -> units.quantity.Quantity:
    '''
    Convert a specific intensity between different units.

    Parameters
    ----------
    wavelength : np.ndarray or astropy.Quantity
        If no units are provided then this is assumed to be in nm.
    specInt : np.ndarray or astropy.Quantity
        If no units are provided then this is assumed to be in J/s/m2/sr/Hz,
        the default for Lightweaver.
    outUnits : str or astropy.Unit
        The units to convert specInt to e.g. 'erg/s/cm2/sr/A'

    Returns
    -------
    result : astropy.Quantity
        specInt converted to the desired units.
    '''
    if not isinstance(wavelength, units.Quantity):
        wavelength = wavelength << units.nm

    if not isinstance(specInt, units.Quantity):
        specInt = specInt << units.J / units.s / units.m**2 / units.sr / units.Hz

    return specInt.to(outUnits, equivalencies=units.spectral_density(wavelength))
示例#40
0
    def evaluate(x, temperature):
        """Evaluate the model.

        Parameters
        ----------
        x : number or ndarray
            Wavelengths in Angstrom.

        temperature : number
            Temperature in Kelvin.

        Returns
        -------
        y : number or ndarray
            Blackbody radiation in PHOTLAM per steradian.

        """
        if ASTROPY_LT_2_0:
            from astropy.analytic_functions.blackbody import blackbody_nu
        else:
            from astropy.modeling.blackbody import blackbody_nu

        # Silence Numpy
        old_np_err_cfg = np.seterr(all='ignore')

        wave = np.ascontiguousarray(x) * u.AA
        bbnu_flux = blackbody_nu(wave, temperature)
        bbflux = (bbnu_flux * u.sr).to(
            units.PHOTLAM, u.spectral_density(wave)) / u.sr  # PHOTLAM/sr

        # Restore Numpy settings
        np.seterr(**old_np_err_cfg)

        return bbflux.value
示例#41
0
    def convert(self, wave, flux, exception=False):
        ''' Convert arrays to target units.

        Parameters
        ----------
        wave: Quantity
          spectral coordinate array to be converted to target units
        flux: Quantity
          flux array to be converted to target units
        exception: boolean, optional, default=False
          if False, a units conversion exception will result in an
          error message being printed at the console. If True, the
          error message is printed AND the exception is raised again.
          This behavior helps in debugging scripts.

        Returns
        -------
           two Quantity instances with the converted wave and flux arrays.
           In case of error, the original input references are returned.
        '''
        try:
            converted_wave = wave.to(self._wunit, equivalencies=u.spectral())
            converted_flux = flux.to(self._funit,
                                     equivalencies=u.spectral_density(wave))

            return converted_wave, converted_flux

        except (ValueError, astropy.units.core.UnitsError) as e:
            print("UNITS CONVERSION ERROR: ", e, file=sys.stderr)
            if exception:
                raise e
            return wave, flux
示例#42
0
    def _find_spectral_column(table,columns_to_search,spectral_axis):
        """
        Figure out which column in a table holds the fluxes or uncertainties.
        Take the first column that has units compatible with
        u.spectral_density() equivalencies. If none meet that criterion,
        look for other likely length units such as 'adu' or 'cts/s'.
        """
        additional_valid_units = [u.Unit('adu'),u.Unit('ct/s')]
        found_column = None

        # First, search for a column with units compatible with Janskies
        for c in columns_to_search:
            try:
                table[c].to("Jy",equivalencies=u.spectral_density(spectral_axis))
                found_column = c
                break
            except:
                continue

        # If no success there, check for other possible flux units
        if found_column is None:
            for c in columns_to_search:
                if table[c].unit in additional_valid_units:
                    found_column = c
                    break

        return found_column
示例#43
0
    def create_flux_equivalencies_list(self):
        """
        Gets all possible conversions for flux from current flux units.
        """
        # Get unit equivalencies.
        curr_flux_unit_equivalencies = u.Unit(
            self.spectrum.flux.unit).find_equivalent_units(
                equivalencies=u.spectral_density(
                    np.sum(self.spectrum.spectral_axis)),
                include_prefix_units=False)

        # Get local units.
        local_units = [
            u.Unit(unit) for unit in self._locally_defined_flux_units()
        ]

        # Remove overlap units.
        curr_flux_unit_equivalencies = list(
            set(curr_flux_unit_equivalencies) - set(local_units))

        # Convert equivalencies into readable versions of the units and sort them alphabetically.
        flux_unit_equivalencies_titles = sorted(
            self.convert_units_to_strings(curr_flux_unit_equivalencies))

        # Concatenate both lists with the local units coming first.
        flux_unit_equivalencies_titles = sorted(self.convert_units_to_strings(local_units)) + \
                                         flux_unit_equivalencies_titles

        return flux_unit_equivalencies_titles
示例#44
0
    def interpolate(self, target_spectrum):
        """
        interpolate(target_spectrum,clone=False)

        Interpolate spectrum to match target spectrum resolution.
        Does not modify current spectrum, but replaces it with a new one,
        which is a copy of the current spectrum but with the interpolated
        data on the x and y fields.
        The target spectrum has to be using the compatible units on the
        x and y axes as the current spectrum, or the interpolation will fail
        (including, e.g., units of wavenumbers/frequency/wavelength).

        Parameters
        ----------
        target_spectrum : `BaseSpectrum`
            The target spectrum which the x axis resolution of the current
            spectrum should be made to match.
        clone : `bool`, optional
            If set to True, returns a modified copy of the spectrum instead
            of operating on the existing spectrum.
        """
        if not self.x.unit.is_equivalent(target_spectrum.x.unit,
                                         equivalencies=u.spectral()):
            raise u.UnitsError('Spectra have incompatible units on x axis!')
        if not self.y.unit.is_equivalent(target_spectrum.y.unit,
                                         equivalencies=u.spectral_density(
                                             self.x)):
            raise u.UnitsError('Spectra have incompatible units on y axis!')
        newX = target_spectrum.x.to(self.x.unit, equivalencies=u.spectral())
        newY = np.interp(newX, self.x, self.y)
        self.x = newX
        self.y = newY
        self.name = '{0}(interpolated: {1})'.format(self.name,
                                                    target_spectrum.name)
示例#45
0
def blackbody_lambda(in_x, temperature):
    """Like :func:`blackbody_nu` but for :math:`B_{\\lambda}(T)`.

    Parameters
    ----------
    in_x : number, array-like, or `~astropy.units.Quantity`
        Frequency, wavelength, or wave number.
        If not a Quantity, it is assumed to be in Angstrom.

    temperature : number, array-like, or `~astropy.units.Quantity`
        Blackbody temperature.
        If not a Quantity, it is assumed to be in Kelvin.

    Returns
    -------
    flux : `~astropy.units.Quantity`
        Blackbody monochromatic flux in
        :math:`erg \\; cm^{-2} s^{-1} \\mathring{A}^{-1} sr^{-1}`.

    """
    if getattr(in_x, 'unit', None) is None:
        in_x = u.Quantity(in_x, u.AA)

    bb_nu = blackbody_nu(in_x, temperature) * u.sr  # Remove sr for conversion
    flux = bb_nu.to(FLAM, u.spectral_density(in_x))

    return flux / u.sr  # Add per steradian to output flux unit
示例#46
0
    def check_spectral(self):
        """Return boolean indicating if SED has units compatible with a spectral density."""
        from astropy import units
        _photons = units.astrophys.photon / (units.s * units.cm**2 * units.nm)

        return self.flux_type.is_equivalent(
            _photons, units.spectral_density(1 * units.nm))
示例#47
0
    def fluxd(self, geom, wave, unit=u.Unit('W / (m2 um)')):
        from numpy import pi
        from ..calib import solar_flux

        if not np.iterable(wave):
            wave = np.array([wave.value]) * wave.unit

        delta = geom['delta']
        phase = geom['phase']
        fsun = solar_flux(wave, unit=unit) / geom['rh'].to(u.au).value**2

        refl = 1 + (wave - 0.55 * u.um).value * self.S / 10.
        if np.any(refl > self.refl_max):
            refl[refl > self.refl_max] = self.refl_max
        if np.any(refl < 0.0):
            refl[refl < 0.0] = 0.0

        #fsca = fsun * Ap * phasef(phase) * pi * R**2 / pi / delta**2
        fsca = (fsun * self.Ap * refl
                * self.phasef(np.abs(phase.to(u.deg).value))
                * (self.R / delta).decompose()**2)

        if unit != fsca.unit:
            fsca = fsca.to(unit, equivalencies=u.spectral_density(u.um, wave))

        return fsca
示例#48
0
def test_spectraldensity6():
    """ Test surface brightness conversions. """
    slam = u.erg / (u.cm**2 * u.s * u.AA * u.sr)
    snu = u.erg / (u.cm**2 * u.s * u.Hz * u.sr)

    wave = u.Quantity([4956.8, 4959.55, 4962.3], u.AA)
    sb_flam = [3.9135e-14, 4.0209e-14, 3.9169e-14]
    sb_fnu = [3.20735792e-25, 3.29903646e-25, 3.21727226e-25]

    # S(nu) <--> S(lambda)
    assert_allclose(snu.to(slam, sb_fnu, u.spectral_density(wave)),
                    sb_flam,
                    rtol=1e-6)
    assert_allclose(slam.to(snu, sb_flam, u.spectral_density(wave)),
                    sb_fnu,
                    rtol=1e-6)
示例#49
0
文件: calib.py 项目: mkelley/mskpy
def cohen_standard(star, unit=u.Unit('W/(m2 um)')):
    """Cohen spectral templates.

    Parameters
    ----------
    star : string
      The name of a star.  This must match the filename of a template.
      For example, use HD6112 or alpha-lyr.  The suffix .tem is
      appended.
    unit : astropy Unit
      Return these units, must be spectral flux density.

    Returns
    -------
    wave : Quantity
      The wavelengths.
    flux : Quantity
      The fluxes.

    Notes
    -----
    The path to the templates is defined in `calib._midirdir`.

    """
    import os
    import re

    templatefile = "{0}/cohen/{1}.tem".format(_midirdir, star)
    if not os.path.exists(templatefile):
        raise ValueError("{0} not found.".format(templatefile))

    # Cohen template format:
    #  1-11   E11.4  um        Lambda      Wavelength
    # 12-22   E11.4  W/cm2/um  F_Lambda    Monochromatic specific intensity
    # 23-33   E11.4  W/cm2/um  e_F_Lambda *Total uncertainty in F_Lambda
    # 34-44   E11.4  %         Local       Local bias
    # 45-55   E11.4  %         Global      Global bias

    # many of the template files have a header
    tableheader = re.compile("Wavelength.*Irradiance.*Total")
    with open(templatefile, 'r') as inf:
        lines = inf.readlines()
        for i, line in enumerate(lines):
            if len(tableheader.findall(line)) > 0:
                break

    if i == (len(lines) - 1):
        # no header, just read it in
        skiprows = 0
    else:
        skiprows = i + 2

    wave, fd, efd = np.loadtxt(templatefile, skiprows=skiprows, unpack=True,
                               usecols=(0, 1, 2))

    wave = wave * u.um
    fd = (fd * u.Unit('W/(cm2 um)')).to(unit, u.spectral_density(wave))

    return wave, fd
示例#50
0
def test_spectraldensity2():
    # flux density
    flambda = u.erg / u.angstrom / u.cm ** 2 / u.s
    fnu = u.erg / u.Hz / u.cm ** 2 / u.s

    a = flambda.to(fnu, 1, u.spectral_density(u.Quantity(3500, u.AA)))
    assert_allclose(a, 4.086160166177361e-12)

    # luminosity density
    llambda = u.erg / u.angstrom / u.s
    lnu = u.erg / u.Hz / u.s

    a = llambda.to(lnu, 1, u.spectral_density(u.Quantity(3500, u.AA)))
    assert_allclose(a, 4.086160166177361e-12)

    a = lnu.to(llambda, 1, u.spectral_density(u.Quantity(3500, u.AA)))
    assert_allclose(a, 2.44728537142857e11)
示例#51
0
    def __init__(self,x,y,xUnit,yUnit,params={}):
        '''
        Inputs:
                x = wavelength/frequency values, 1d array-like
                y = spectral flux density, 1d array-like
                xUnit = astropy.units.Unit of physical type length or frequency
                yUnit = astropy.units.Unit of physical type luminosity/flux density /length or frequency

        '''
        self.type = 'spectrum'
        # Validate x input
        wavelengths = np.asarray(x)
        spec = np.asarray(y)
        if wavelengths.ndim!=1:
            raise ValueError('Wavelength/Frequency must be given as a 1d array')
        if wavelengths.shape!=spec.shape:
            raise ValueError('Wavelength/Frequency array and flux density array have different shapes.')
        if u.get_physical_type(xUnit) not in ['frequency','length']:
            raise TypeError(xUnit,' is neither a unit of frequency nor a unit of length. Get it together.')
        wavelengths = wavelengths * xUnit
        wavelengths.to('micron',equivalencies=u.spectral())
        if not np.all(np.ediff1d(wavelengths)>0.):
            if u.get_physical_type(xUnit) == 'frequency':
                raise ValueError('Frequencies must be monotonically decreasing.')
            else:
                raise ValueError('Wavelengths must be monotonically increasing.')
        self.wavelengths = wavelengths
        
        # Validate y input
        spec = np.asarray(y)
        if spec.ndim!=1:
            raise ValueError('Spectrum must be given as a 1d array')
            
        # Define desired flux units from base units
        uFnu = u.Unit('erg')/u.Unit('s')/u.Unit('Hz') 
        uFnuN = u.Unit('erg')/u.Unit('s')/u.Unit('Hz')/u.Unit('cm')**2 # astropy equivalency only works when area uncluded
        uFlam = u.Unit('erg')/u.Unit('s')/u.Unit('Angstrom')
        uFlamN = u.Unit('erg')/u.Unit('s')/u.Unit('Angstrom')/u.Unit('cm')**2
        
        # Need F_nu, but if there's no area, need to add because too lazy to add equivalency 
        if yUnit.is_equivalent(uFnu):
            spec = spec * yUnit / (4*np.pi*((10 * u.Unit('parsec')).to('cm'))**2)
            #spec = spec * yUnit / u.Unit('m')**2
        elif yUnit.is_equivalent(uFlam):
            spec = spec * yUnit/ (4*np.pi*((10 * u.Unit('parsec')).to('cm'))**2)
            #spec = spec * yUnit/ u.Unit('m')**2
        else:
            spec = (spec * yUnit) . to(uFnuN)
        
        if not spec.unit.is_equivalent(uFlamN) and not spec.unit.is_equivalent(uFnuN):
            raise ValueError(spec.unit,' not recognized as a unit of spectral flux density.')
        spec = spec.to(uFnuN,equivalencies=u.spectral_density(wavelengths))
        
        if wavelengths[-1]<wavelengths[0]: # then we originally had flux units
            wavelengths = np.flipud(wavelengths)
            spec = np.flipud(spec)
        self.spec = spec
        self.params = params
示例#52
0
文件: items.py 项目: nmearl/specviz
 def flux(self):
     """
     Returns the fluxes of the underlying :class:`~specutils.Spectrum1D`
     object converted to the current data display units (given by
     `PlotDataItem.data_unit`).
     """
     return self.data_item.flux.to(self.data_unit,
                                   equivalencies=spectral_density(
                                       self.data_item.spectral_axis)).value
示例#53
0
    def fluxd(self, geom, wave, unit=u.Jy):
        """Flux density.

        Parameters
        ----------
        geom : dict of Quantities
          A dictionary-like object with the keys 'rh' (heliocentric
          distance), 'delta' (observer-target distance), and 'phase'
          (phase angle).
        wave : Quantity
          The wavelengths at which to compute the emission.
        unit : astropy Units, optional
          The return units.  Must be spectral flux density.

        Returns
        -------
        fluxd : Quantity
          The flux density from the whole asteroid.

        """

        from numpy import pi
        from scipy.integrate import quad

        phase = geom['phase']
        if not np.iterable(wave):
            wave = np.array([wave.value]) * wave.unit
        T0 = self.T0(geom['rh']).to(u.Kelvin).value
        fluxd = np.zeros(len(wave))

        # Integrate theta from -pi/2 to pi/2: emission is emitted from
        # the daylit hemisphere: theta = (phase - pi/2) to (phase +
        # pi/2), therfore the theta limits become [-pi/2, pi/2 -
        # phase]
        #
        # Integrate phi from -pi/2 to pi/2 (or 2 * integral from 0 to
        # pi/2)
        #
        # Drop some units for efficiency
        phase_r = np.abs(phase.to(u.rad).value)
        wave_um = wave.to(u.um).value
        for i in range(len(wave_um)):
            fluxd[i] = quad(self._latitude_emission,
                            -pi / 2.0 + phase_r, pi / 2.0,
                            args=(wave_um[i], T0, phase_r),
                            epsrel=self.tol)[0]

        fluxd *= (self.epsilon * (self.D / geom['delta'])**2
                  / pi / 2.0).decompose() # W/m^2/Hz

        fluxd = fluxd * u.Unit('W / (m2 Hz)')
        equiv = u.spectral_density(u.um, wave.to(u.um).value)
        fluxd = fluxd.to(unit, equivalencies=equiv)
        if len(fluxd) == 1:
            return fluxd[0]
        else:
            return fluxd
示例#54
0
    def cont(self, value):

        if not isinstance(value, Data):
            raise ValueError('cont must be an instance of a Data object')

        self._cont = value.to(
            erg / cm ** 2 / s / angstrom,
            equivalencies=spectral_density(self.wavelength_observed))
        self.rcont = self._cont * (1 + self.redshift) ** 3
示例#55
0
    def __init__(
        self,
        wave,
        flux,
        error=None,
        unit=(u.erg / u.s / u.cm ** 2 / u.AA),
        wave_unit=u.AA,
        z=None,
        dist=None,
        meta=None,
    ):
        self.wave = np.asarray(wave, dtype=np.float64)
        self.flux = np.asarray(flux, dtype=np.float64)
        if self.wave.shape != self.flux.shape:
            raise ValueError("shape of wavelength and flux must match")
        if self.wave.ndim != 1:
            raise ValueError("only 1-d arrays supported")

        # internally, wavelength is in Angstroms:
        if wave_unit != u.AA:
            self.wave = wave_unit.to(u.AA, self.wave, u.spectral())
        self._wave_unit = u.AA

        # internally, flux is in F_lambda:
        if unit != FLAMBDA_UNIT:
            self.flux = unit.to(FLAMBDA_UNIT, self.flux, u.spectral_density(u.AA, self.wave))
        self._unit = FLAMBDA_UNIT

        # Set up interpolation.
        # This appears to be the fastest-evaluating interpolant in
        # scipy.interpolate.
        self._tck = splrep(self.wave, self.flux, k=1)

        # following are deprecated attributes:

        if z is not None:
            warn_once("z keyword in Spectrum", "1.4", "2.0")
        self._z = z

        if dist is not None:
            warn_once("dist keyword in Spectrum", "1.4", "2.0")
        self._dist = dist

        if error is not None:
            warn_once("error keyword in Spectrum", "1.4", "2.0")
            self._error = np.asarray(error)
            if self.wave.shape != self._error.shape:
                raise ValueError("shape of wavelength and variance must match")
        else:
            self._error = None

        if meta is None:
            self.meta = OrderedDict()
        else:
            warn_once("meta keyword in Spectrum", "1.4", "2.0")
            self.meta = deepcopy(meta)
示例#56
0
    def _rest_nm_to_photons(self, wave):
        from astropy import units
        _photons = units.astrophys.photon/(units.s * units.cm**2 * units.nm)

        wave_native_quantity = (wave * units.nm).to(self.wave_type, units.spectral())
        wave_native_value = wave_native_quantity.value
        flux_native_quantity = self._spec(wave_native_value) * self.flux_type
        return (flux_native_quantity
                .to(_photons, units.spectral_density(wave_native_quantity))
                .value)
示例#57
0
    def ccorrection(self, sf, channels=[1, 2, 3, 4]):
        """IRAC color correction.

        Seems to agree within 1% of the IRAC Instrument Handbook.
        Thier quoted values are good to ~1%.

        Parameters
        ----------
        sf : function
          A function that generates source flux density as a Quantity
          given wavelength as a Quantity.
        channels : list, optional
          A list of the IRAC channels for which to compute the color
          correction, e.g., `[1, 2]` for 3.6 and 4.5 um.

        Returns
        -------
        K : ndarray
          Color correction factor, where `Fcc = F / K`.

        """

        from scipy import interpolate
        import astropy.constants as const
        from ..calib import filter_trans
        from ..util import davint, takefrom

        nu0 = (const.c.si / self.wave).to(u.teraHertz).value
        K = np.zeros(len(channels))
        for ch in channels:
            tw, tr = filter_trans('IRAC CH{:}'.format(ch))
            nu = (const.c / tw).to(u.teraHertz).value

            sfnu = sf(tw).to(u.Jy, u.spectral_density(tw)).value

            i = ch - 1  # self.wave index
            sfnu /= sf(self.wave[i]).to(u.Jy, u.spectral_density(self.wave[i])).value

            sfnu, tr, nu = takefrom((sfnu, tr, nu), nu.argsort())
            K[i] = (davint(nu, sfnu * tr * nu0[i] / nu, nu[0], nu[-1])
                    / davint(nu, tr * (nu0[i] / nu)**2, nu[0], nu[-1]))

        return K
示例#58
0
def bbfunc(wavelengths, temperature):
    """Planck law for blackbody radiation in PHOTLAM per steradian.

    .. warning::

        Data points where overflow or underflow occurs will be set
        to zeroes.

    Parameters
    ----------
    wavelengths : array_like or `~astropy.units.quantity.Quantity`
        Wavelength values. If not a Quantity, assumed to be in Angstrom.

    temperature : float or `~astropy.units.quantity.Quantity`
        Blackbody temperature. If not a Quantity, assumed to be in Kelvin.

    Returns
    -------
    fluxes : `~astropy.units.quantity.Quantity`
        Blackbody radiation in PHOTLAM per steradian.

    """
    # Silence Numpy
    old_np_err_cfg = np.seterr(all='ignore')

    # Calculations must use Angstrom
    wavelengths = units.validate_quantity(
        wavelengths, u.AA, equivalencies=u.spectral()).astype(np.float64)

    # Calculations must use Kelvin
    temperature = units.validate_quantity(temperature, u.K).astype(np.float64)

    x = wavelengths * temperature

    # Catch division by zero
    mask = x > 0
    x = np.where(mask, units.HC / (const.k_B.cgs * x), 0.0)

    # Catch overflow/underflow
    mask = (x >= _VERY_SMALL) & (x < _VERY_LARGE)
    factor = np.where(mask, 1.0 / np.expm1(x), 0.0)

    # Convert FNU to PHOTLAM
    freq = u.Quantity(np.where(
        factor, wavelengths.to(u.Hz, equivalencies=u.spectral()), 0.0), u.Hz)
    bb_nu = 2.0 * const.h * factor * freq * freq * freq / const.c ** 2
    bb_lam = np.where(
        factor, units.FNU.to(units.PHOTLAM, bb_nu.cgs.value,
                             equivalencies=u.spectral_density(wavelengths)),
        0.0)

    # Restore Numpy settings
    dummy = np.seterr(**old_np_err_cfg)

    return u.Quantity(bb_lam, unit=units.PHOTLAM/u.sr)
示例#59
0
def test_spectraldensity5():
    """ Test photon luminosity density conversions. """
    L_la = u.erg / (u.s * u.AA)
    L_nu = u.erg / (u.s * u.Hz)
    phot_L_la = u.photon / (u.s * u.AA)
    phot_L_nu = u.photon / (u.s * u.Hz)

    wave = u.Quantity([4956.8, 4959.55, 4962.3], u.AA)
    flux_phot_L_la = [9.7654e-3, 1.003896e-2, 9.78473e-3]
    flux_phot_L_nu = [8.00335589e-14, 8.23668949e-14, 8.03700310e-14]
    flux_L_la = [3.9135e-14, 4.0209e-14, 3.9169e-14]
    flux_L_nu = [3.20735792e-25, 3.29903646e-25, 3.21727226e-25]

    # PHOTLAM <--> FLAM
    assert_allclose(phot_L_la.to(
        L_la, flux_phot_L_la, u.spectral_density(wave)), flux_L_la, rtol=1e-6)
    assert_allclose(L_la.to(
        phot_L_la, flux_L_la, u.spectral_density(wave)), flux_phot_L_la, rtol=1e-6)

    # PHOTLAM <--> FNU
    assert_allclose(phot_L_la.to(
        L_nu, flux_phot_L_la, u.spectral_density(wave)), flux_L_nu, rtol=1e-6)
    assert_allclose(L_nu.to(
        phot_L_la, flux_L_nu, u.spectral_density(wave)), flux_phot_L_la, rtol=1e-6)

    # PHOTLAM <--> PHOTNU
    assert_allclose(phot_L_la.to(
        phot_L_nu, flux_phot_L_la, u.spectral_density(wave)), flux_phot_L_nu, rtol=1e-6)
    assert_allclose(phot_L_nu.to(
        phot_L_la, flux_phot_L_nu, u.spectral_density(wave)), flux_phot_L_la, rtol=1e-6)

    # PHOTNU <--> FNU
    assert_allclose(phot_L_nu.to(
        L_nu, flux_phot_L_nu, u.spectral_density(wave)), flux_L_nu, rtol=1e-6)
    assert_allclose(L_nu.to(
        phot_L_nu, flux_L_nu, u.spectral_density(wave)), flux_phot_L_nu, rtol=1e-6)

    # PHOTNU <--> FLAM
    assert_allclose(phot_L_nu.to(
        L_la, flux_phot_L_nu, u.spectral_density(wave)), flux_L_la, rtol=1e-6)
    assert_allclose(L_la.to(
        phot_L_nu, flux_L_la, u.spectral_density(wave)), flux_phot_L_nu, rtol=1e-6)
示例#60
0
文件: fit_bb.py 项目: dmargala/blupe
def blackbody_nu(in_x, temperature):
    """Calculate blackbody flux per steradian, :math:`B_{\\nu}(T)`.

    .. note::

        Use `numpy.errstate` to suppress Numpy warnings, if desired.

    .. warning::

        Output values might contain ``nan`` and ``inf``.

    Parameters
    ----------
    in_x : number, array-like, or `~astropy.units.Quantity`
        Frequency, wavelength, or wave number.
        If not a Quantity, it is assumed to be in Hz.

    temperature : number or `~astropy.units.Quantity`
        Blackbody temperature.
        If not a Quantity, it is assumed to be in Kelvin.

    Returns
    -------
    flux : `~astropy.units.Quantity`
        Blackbody monochromatic flux in
        :math:`erg \\; cm^{-2} s^{-1} Hz^{-1} sr^{-1}`.

    Raises
    ------
    ValueError
        Invalid temperature.

    ZeroDivisionError
        Wavelength is zero (when converting to frequency).

    """
    # Convert to units for calculations, also force double precision
    with u.add_enabled_equivalencies(u.spectral() + u.temperature()):
        freq = u.Quantity(in_x, u.Hz, dtype=np.float64)
        temp = u.Quantity(temperature, u.K, dtype=np.float64)

    # Check if input values are physically possible
    if temp < 0:
        raise ValueError('Invalid temperature {0}'.format(temp))
    if np.any(freq <= 0):  # pragma: no cover
        warnings.warn('Input contains invalid wavelength/frequency value(s)',
                      AstropyUserWarning)

    # Calculate blackbody flux
    bb_nu = (2.0 * const.h * freq ** 3 /
             (const.c ** 2 * np.expm1(const.h * freq / (const.k_B * temp))))
    flux = bb_nu.to(FNU, u.spectral_density(freq))

    return flux / u.sr  # Add per steradian to output flux unit