Exemple #1
0
def test():
    from sedpy import observate
    import fsps
    import matplotlib.pyplot as pl

    filters = [
        'galex_NUV', 'sdss_u0', 'sdss_r0', 'sdss_r0', 'sdss_i0', 'sdss_z0',
        'bessell_U', 'bessell_B', 'bessell_V', 'bessell_R', 'bessell_I',
        'twomass_J', 'twomass_H'
    ]
    flist = observate.load_filters(filters)

    sps = fsps.StellarPopulation(compute_vega_mags=False)
    wave, spec = sps.get_spectrum(tage=1.0, zmet=2, peraa=True)

    sed = observate.getSED(wave, spec, flist)
    sed_unc = np.abs(np.random.normal(1, 0.3, len(sed)))

    wgrid = np.linspace(2e3, 13e3, 1000)
    fgrid = np.linspace(-13, -9, 100)
    psed, sedpoints = sed_to_psed(flist, sed, sed_unc, wgrid, fgrid)

    pl.imshow(np.exp(psed).T,
              cmap='Greys_r',
              interpolation='nearest',
              origin='upper',
              aspect='auto')
Exemple #2
0
def norm_spectrum(obs, norm_band_name='f475w', **kwargs):
    """Initial guess of spectral normalization using photometry.

    This obtains the multiplicative factor required to reproduce the the
    photometry in one band from the observed spectrum (model.obs['spectrum'])
    using the bsfh unit conventions.  Thus multiplying the observed spectrum by
    this factor gives a spectrum that is approximately erg/s/cm^2/AA at the
    central wavelength of the normalizing band.

    The inverse of the multiplication factor is saved as a fixed parameter to
    be used in producing the mean model.
    """
    from sedpy import observate

    norm_band = [i for i, f in enumerate(obs['filters'])
                 if norm_band_name in f.name][0]

    synphot = observate.getSED(obs['wavelength'], obs['spectrum'], obs['filters'])
    synphot = np.atleast_1d(synphot)
    # Factor by which the observed spectra should be *divided* to give you the
    #  photometry (or the cgs apparent spectrum), using the given filter as
    #  truth.  Alternatively, the factor by which the model spectrum (in cgs
    #  apparent) should be multiplied to give you the observed spectrum.
    norm = 10**(-0.4 * synphot[norm_band]) / obs['maggies'][norm_band]

    # Pivot the calibration polynomial near the filter used for approximate
    # normalization
    pivot_wave = obs['filters'][norm_band].wave_effective
    # model.params['pivot_wave'] = 4750.

    return norm, pivot_wave
Exemple #3
0
def plot_sfh(pars, specs, masses, sfrs, ages, sps=sps):


    # sfrs
    plot(ages[0], sfrs[0][i,:], '-o', label='old')
    plot(ages[1], sfrs[1][i,:], '-o', label='new')
    integrated_sfr = [np.trapz(sfrs[i], 10**ages[i], axis=1) for i in range(2)]
    sratio = integrated_sfr[1] / integrated_sfr[0]

    # masses
    plot(ages[0], masses[0][i,:], '-o', label='old')
    plot(ages[1], masses[1][i,:], '-o', label='new')
    m1 = interp1d(ages[0], masses[0], axis=1)(ages[1])
    mratio =  masses[1] / m1
    zero = (m1 == 0.0) | (masses[1] == 0.0)

    # Mass to light ratios
    from sedpy import observate
    filters = [observate.Filter('bessell_V')]
    w = sps.wavelengths
    lv = [observate.getSED(w, s / w**2, filterlist=filters) for s in specs]

    log_m2l = [np.log10(mass) + lum/2.5 for mass, lum in zip(masses, lv)]
    log_m2l1 = interp1d(ages[0], log_m2l[0], axis=1)(ages[1])
    
    pass
    def get_spectrum(self, outwave=None, filters=None, component=-1, **params):
        """
        """
        # Spectrum in Lsun/Hz per solar mass formed, restframe
        wave, spectrum, mfrac = self.get_galaxy_spectrum(**params)

        # Redshifting + Wavelength solution
        # We do it ourselves.
        a = 1 + self.params.get('zred', 0)
        af = a
        b = 0.0

        if 'wavecal_coeffs' in self.params:
            x = wave - wave.min()
            x = 2.0 * (x / x.max()) - 1.0
            c = np.insert(self.params['wavecal_coeffs'], 0, 0)
            # assume coeeficients give shifts in km/s
            b = chebval(x, c) / (lightspeed*1e-13)

        wa, sa = wave * (a + b), spectrum * af  # Observed Frame
        if outwave is None:
            outwave = wa

        # Observed frame photometry, as absolute maggies
        if filters is not None:
            # Magic to only do filter projections for unique filters, and get a
            # mapping back into this list of unique filters
            # note that this may scramble order of unique_filters
            fnames = [f.name for f in filters]
            unique_names, uinds, filter_ind = np.unique(fnames, return_index=True, return_inverse=True)
            unique_filters = np.array(filters)[uinds]
            mags = getSED(wa, lightspeed/wa**2 * sa * to_cgs, unique_filters)
            phot = np.atleast_1d(10**(-0.4 * mags))
        else:
            phot = 0.0

        # Distance dimming and unit conversion
        zred = self.params.get('zred', 0.0)
        if (zred == 0) or ('lumdist' in self.params):
            # Use 10pc for the luminosity distance (or a number
            # provided in the dist key in units of Mpc)
            dfactor = (self.params.get('lumdist', 1e-5) * 1e5)**2
        else:
            lumdist = cosmo.luminosity_distance(zred).value
            dfactor = (lumdist * 1e5)**2

        # Spectrum will be in maggies
        sa *= to_cgs / dfactor / (3631*jansky_cgs)

        # Convert from absolute maggies to apparent maggies
        phot /= dfactor

        # Mass normalization
        mass = np.atleast_1d(self.params['mass'])
        mass = np.squeeze(mass.tolist() + [mass.sum()])

        sa = (sa * mass[:, None])
        phot = (phot * mass[:, None])[component, filter_ind]

        return sa, phot, mfrac
Exemple #5
0
def norm_spectrum(obs, norm_band_name='f475w', **kwargs):
    """Initial guess of spectral normalization using photometry.

    This obtains the multiplicative factor required to reproduce the the
    photometry in one band from the observed spectrum (model.obs['spectrum'])
    using the bsfh unit conventions.  Thus multiplying the observed spectrum by
    this factor gives a spectrum that is approximately erg/s/cm^2/AA at the
    central wavelength of the normalizing band.

    The inverse of the multiplication factor is saved as a fixed parameter to
    be used in producing the mean model.
    """
    from sedpy import observate

    norm_band = [i for i, f in enumerate(obs['filters'])
                 if norm_band_name in f.name][0]

    synphot = observate.getSED(obs['wavelength'], obs['spectrum'], obs['filters'])
    synphot = np.atleast_1d(synphot)
    # Factor by which the observed spectra should be *divided* to give you the
    #  photometry (or the cgs apparent spectrum), using the given filter as
    #  truth.  Alternatively, the factor by which the model spectrum (in cgs
    #  apparent) should be multiplied to give you the observed spectrum.
    norm = 10**(-0.4 * synphot[norm_band]) / obs['maggies'][norm_band]

    # Pivot the calibration polynomial near the filter used for approximate
    # normalization
    pivot_wave = obs['filters'][norm_band].wave_effective
    # model.params['pivot_wave'] = 4750.

    return norm, pivot_wave
Exemple #6
0
    def predict_phot(self, filters):
        """Generate a prediction for the observed photometry.  This method assumes
        that the parameters have been set and that the following attributes are
        present and correct:
          + ``_wave`` - The SPS restframe wavelength array
          + ``_zred`` - Redshift
          + ``_norm_spec`` - Observed frame spectral fluxes, in units of maggies.
          + ``_eline_wave`` and ``_eline_lum`` - emission line parameters from the SPS model
          

        :param filters:
            List of :py:class:`sedpy.observate.Filter` objects.
            If there is no photometry, ``None`` should be supplied

        :returns phot:
            Observed frame photometry of the model SED through the given filters.
            ndarray of shape ``(len(filters),)``, in units of maggies.
            If ``filters`` is None, this returns 0.0
        """
        if filters is None:
            return 0.0

        # generate photometry w/o emission lines
        obs_wave = self.observed_wave(self._wave, do_wavecal=False)
        flambda = self._norm_spec * lightspeed / obs_wave**2 * (3631 *
                                                                jansky_cgs)
        mags = getSED(obs_wave, flambda, filters)
        phot = np.atleast_1d(10**(-0.4 * mags))

        # generate emission-line photometry
        if self.params.get('nebemlineinspec', False) is False:
            phot += self.nebline_photometry(filters)

        return phot
 def mags_from_sedpy(z, t, s):
     t0 = time.time()
     sps.params['logzsol'] = z
     sps.params['sigma_smooth'] = s
     sps.params['tage'] = t
     wave, spec = sps.get_spectrum(peraa=True, tage=sps.params['tage'])
     mags = observate.getSED(wave, spec, filters)
     return time.time() - t0
Exemple #8
0
 def mags_from_sedpy(z, t, s):
     t0 = time.time()
     sps.params['logzsol'] = z
     sps.params['sigma_smooth'] = s
     sps.params['tage'] = t
     wave, spec  = sps.get_spectrum(peraa=True,
                                    tage = sps.params['tage'])
     mags = observate.getSED(wave, spec, filters)
     return time.time()-t0
Exemple #9
0
def zsfh_to_obs(sfhlist, zlist, lfbandnames=None, select_function=None,
                bandnames=None, sps=None, isocs=None, **kwargs):
    """
    Go from a list of SFHs (one for each metallicity) to a broadband SED and set of
    luminosity functions for a stellar population.
    """
    sed_values, lf_values = {}, []
    #basti = np.any(sps.zlegend[0:2] == 0.0006) #Hack to check for Basti Isochrones
    nsfh = len(sfhlist)
    assert len(zlist) == nsfh

    ###########
    # SED
    ############
    if bandnames is not None:
        filterlist = observate.load_filters(bandnames)
        spec, wave, mass = rsed.one_region_sed(copy.deepcopy(sfhlist), total_zmet, sps)
        mags = observate.getSED(wave, spec*rsed.to_cgs, filterlist=filterlist)
        maggies = 10**(-0.4 * np.atleast_1d(mags))
        sed_values['sed_ab_maggies'] = maggies
        sed_values['sed_filters'] = bandnames

    #############
    # LFs
    ############
    #create the SSP CLFs, using nearest neighbor interpolation for the metallicity
    all_lf_base = []
    bins = rsed.lfbins
    for i,zmet in enumerate(zlist):
        if isocs is not None:
            isoc = isocs[i]
        else:
            sps.params['zmet'] = np.abs(sps.zlegend - zmet).argmin() + 1
            isoc = sps.isochrones()
            print("Using Zmet={0} in place of requested "
            "Zmet={1}".format(sps.zlegend[sps.params['zmet']-1],zmet))

        ldat = isochrone_to_clfs(copy.deepcopy(isoc), lfbandnames,
                                 select_function=select_function, **kwargs)
        all_lf_base += [ldat]
    #use the SSP CLFs to generate a total LF (for each band)
    for i, band in enumerate(lfbandnames):
        lf_oneband = {}
        lf_base = [zbase[i] for zbase in all_lf_base]
        lfs_zt, lf, logages = rsed.one_region_lfs(copy.deepcopy(sfhlist), lf_base)
        lf_oneband['bandname'] = band
        lf_oneband['clf'] = lf
        lf_oneband['clf_mags'] = bins
        lf_oneband['logages'] = logages
        lf_oneband['clfs_zt'] = lfs_zt
        
        lf_values += [lf_oneband]
        
    #############
    # Write output
    ############
    return sed_values, lf_values
    def one_sed(self, component_index=0, filterlist=[]):
        """Get the SED of one component for a multicomponent composite SFH.
        Should set this up to work as an iterator.

        :param component_index:
            Integer index of the component to calculate the SED for.

        :param filterlist:
            A list of strings giving the (FSPS) names of the filters onto which
            the spectrum will be projected.

        :returns spec:
            The restframe spectrum in units of Lsun/Hz.

        :returns maggies:
            Broadband fluxes through the filters named in ``filterlist``,
            ndarray.  Units are observed frame absolute maggies: M = -2.5 *
            log_{10}(maggies).

        :returns extra:
            The extra information corresponding to this component.
        """
        # Pass the model parameters through to the sps object, and keep track
        # of the mass of this component
        mass = 1.0
        for k, vs in list(self.params.items()):
            try:
                v = vs[component_index]
            except (IndexError, TypeError):
                v = vs
            if k in self.csp.params.all_params:
                self.csp.params[k] = deepcopy(v)
            if k == 'mass':
                mass = v
        # Now get the spectrum.  The spectrum is in units of
        # Lsun/Hz/per solar mass *formed*, and is restframe
        w, spec = self.csp.get_spectrum(tage=self.csp.params['tage'],
                                        peraa=False)
        # redshift and get photometry.  Note we are boosting fnu by (1+z) *here*
        a, b = (1 + self.csp.params['zred']), 0.0
        wa, sa = w * (a + b), spec * a  # Observed Frame
        if filterlist is not None:
            mags = getSED(wa, lightspeed / wa**2 * sa * to_cgs, filterlist)
            phot = np.atleast_1d(10**(-0.4 * mags))
        else:
            phot = 0.0

        # now some mass normalization magic
        mfrac = self.csp.stellar_mass
        if np.all(self.params.get('mass_units', 'mstar') == 'mstar'):
            # Convert normalization units from per stellar masss to per mass formed
            mass /= mfrac
        # Output correct units
        return mass * sa, mass * phot, mfrac
Exemple #11
0
def project_filter(wave, spectrum, bands=["sdss_r0"]):
    """
    :param wave: 
        Wavelengths in angstroms ndarray of shape (nw,)

    :param spectrum: 
        Spectrum, in units of f_lambda (magnitudes will be correct if they are
        units of erg/s/cm^2). same shape as `wave`
    """

    filters = load_filters(bands)
    mags = getSED(wave, spectrum, filterlist=filters)
    return mags
Exemple #12
0
    def process_component(self, i, outwave, filters):
        """Basically do all the COMPSP stuff for one component.
        """
        cspec = self.basis_spec[i, :].copy()
        cphot = 0
        inwave = self.ssp.wavelengths

        if self.safe:
            cspec = np.interp(self.params['outwave'], vac2air(inwave),
                              cspec / a)
            cphot = 10**(-0.4 * getSED(inwave, cspec / a, filters))
            return cspec, cphot

        # Dust attenuation
        tage = self.params['tage'][i]
        tesc = self.params.get('dust_tesc', 0.01)
        dust1 = self.params.get('dust1', 0.0)
        dust2 = self.params['dust2']
        a = (1 + self.params.get('zred', 0.0))
        dust = (tage < tesc) * dust1 + dust2
        att = self.params['dust_curve'][0](inwave, **self.params)
        cspec *= np.exp(-att * dust)

        if filters is not None:
            cphot = 10**(-0.4 * getSED(inwave * a, cspec / a, filters))

        # Wavelength scale.  Broadening and redshifting and placing on output
        # wavelength grid
        if self.params.get('lsf', [None])[0] is not None:
            cspec = smoothspec(
                vac2air(inwave) * a, cspec / a, self.params['sigma_smooth'],
                **self.params)
        else:
            sigma = self.params.get('sigma_smooth', 0.0)
            cspec = self.ssp.smoothspec(inwave, cspec, sigma)
            cspec = np.interp(self.params['outwave'], vac2air(inwave * a),
                              cspec / a)

        return cspec, cphot
Exemple #13
0
    def one_sed(self, icomp=0, wave=None, filters=None, **extras):
        """Pull out individual component parameters from the param dictionary
        and generate spectra for those components
        """
        cpars = {}
        for k in self.dust_parlist:
            try:
                cpars[k] = np.squeeze(self.params[k][icomp])
            except(IndexError, TypeError):
                cpars[k] = np.squeeze(self.params[k])

        spec = cpars['mass'] * modified_BB(wave, **cpars)
        phot = 10**(-0.4 * getSED(wave*1e4, spec, filters))
        return spec, phot, None
Exemple #14
0
    def one_sed(self, icomp=0, wave=None, filters=None, **extras):
        """Pull out individual component parameters from the param dictionary
        and generate spectra for those components
        """
        cpars = {}
        for k in self.dust_parlist:
            try:
                cpars[k] = np.squeeze(self.params[k][icomp])
            except (IndexError, TypeError):
                cpars[k] = np.squeeze(self.params[k])

        spec = cpars['mass'] * modified_BB(wave, **cpars)
        phot = 10**(-0.4 * getSED(wave * 1e4, spec, filters))
        return spec, phot, None
Exemple #15
0
    def one_sed(self, component_index=0, filterlist=[]):
        """Get the SED of one component for a multicomponent composite SFH.
        Should set this up to work as an iterator.

        :param component_index:
            Integer index of the component to calculate the SED for.

        :param filterlist:
            A list of strings giving the (FSPS) names of the filters onto which
            the spectrum will be projected.

        :returns spec:
            The restframe spectrum in units of Lsun/Hz.

        :returns maggies:
            Broadband fluxes through the filters named in ``filterlist``,
            ndarray.  Units are observed frame absolute maggies: M = -2.5 *
            log_{10}(maggies).

        :returns extra:
            The extra information corresponding to this component.
        """
        # Pass the model parameters through to the sps object, and keep track
        # of the mass of this component
        mass = 1.0
        for k, vs in list(self.params.items()):
            try:
                v = vs[component_index]
            except (IndexError, TypeError):
                v = vs
            if k in self.csp.params.all_params:
                if k == 'zmet':
                    vv = np.abs(v - (np.arange(len(self.csp.zlegend)) +
                                     1)).argmin() + 1
                else:
                    vv = v.copy()
                self.csp.params[k] = vv
            if k == 'mass':
                mass = v
        # Now get the magnitudes and spectrum.  The spectrum is in units of
        # Lsun/Hz/per solar mass *formed*
        w, spec = self.csp.get_spectrum(tage=self.csp.params['tage'],
                                        peraa=False)
        mags = getSED(w, lightspeed / w**2 * spec * to_cgs, filterlist)
        mfrac = self.csp.stellar_mass
        if np.all(self.params.get('mass_units', 'mstar') == 'mstar'):
            # Convert normalization units from per stellar masss to per mass formed
            mass /= mfrac
        # Output correct units
        return mass * spec, mass * 10**(-0.4 * (mags)), mfrac
Exemple #16
0
    def process_component(self, i, outwave, filters):
        """Basically do all the COMPSP stuff for one component.
        """
        cspec = self.basis_spec[i, :].copy()
        cphot = 0
        inwave = self.ssp.wavelengths

        if self.safe:
            cspec = np.interp(self.params['outwave'], vac2air(inwave), cspec/a)
            cphot = 10**(-0.4 * getSED(inwave, cspec/a, filters))
            return cspec, cphot

        # Dust attenuation
        tage = self.params['tage'][i]
        tesc = self.params.get('dust_tesc', 0.01)
        dust1 = self.params.get('dust1', 0.0)
        dust2 = self.params['dust2']
        a = (1 + self.params.get('zred', 0.0))
        dust = (tage < tesc) * dust1 + dust2
        att = self.params['dust_curve'][0](inwave, **self.params)
        cspec *= np.exp(-att*dust)

        if filters is not None:
            cphot = 10**(-0.4 * getSED(inwave*a, cspec / a, filters))

        # Wavelength scale.  Broadening and redshifting and placing on output
        # wavelength grid
        if self.params.get('lsf', [None])[0] is not None:
            cspec = smoothspec(vac2air(inwave) * a, cspec / a,
                               self.params['sigma_smooth'], **self.params)
        else:
            sigma = self.params.get('sigma_smooth', 0.0)
            cspec = self.ssp.smoothspec(inwave, cspec, sigma)
            cspec = np.interp(self.params['outwave'], vac2air(inwave * a), cspec/a)

        return cspec, cphot
Exemple #17
0
    def one_sed(self, component_index=0, filterlist=[]):
        """Get the SED of one component for a multicomponent composite SFH.
        Should set this up to work as an iterator.

        :param component_index:
            Integer index of the component to calculate the SED for.

        :param filterlist:
            A list of strings giving the (FSPS) names of the filters onto which
            the spectrum will be projected.

        :returns spec:
            The restframe spectrum in units of Lsun/Hz.

        :returns maggies:
            Broadband fluxes through the filters named in ``filterlist``,
            ndarray.  Units are observed frame absolute maggies: M = -2.5 *
            log_{10}(maggies).

        :returns extra:
            The extra information corresponding to this component.
        """
        # Pass the model parameters through to the sps object, and keep track
        # of the mass of this component
        mass = 1.0
        for k, vs in list(self.params.items()):
            try:
                v = vs[component_index]
            except(IndexError, TypeError):
                v = vs
            if k in self.csp.params.all_params:
                if k == 'zmet':
                    vv = np.abs(v - (np.arange(len(self.csp.zlegend)) + 1)).argmin() + 1
                else:
                    vv = v.copy()
                self.csp.params[k] = vv
            if k == 'mass':
                mass = v
        # Now get the magnitudes and spectrum.  The spectrum is in units of
        # Lsun/Hz/per solar mass *formed*
        w, spec = self.csp.get_spectrum(tage=self.csp.params['tage'], peraa=False)
        mags = getSED(w, lightspeed/w**2 * spec * to_cgs, filterlist)
        mfrac = self.csp.stellar_mass
        if np.all(self.params.get('mass_units', 'mstar') == 'mstar'):
            # Convert normalization units from per stellar masss to per mass formed
            mass /= mfrac
        # Output correct units
        return mass * spec, mass * 10**(-0.4*(mags)), mfrac
Exemple #18
0
def rectify_basis(wave, spectra, wlow=0, whigh=np.inf,
                  exclude=[], outwave=None, filters=None, **extras):
    """Mask a spectral basis using lists of include and exclude ranges
    """
    if filters is not None:
        flist = observate.load_filters(filters)
        sed = observate.getSED(wave, spectra, filterlist=flist)
        return np.array([f.wave_effective for f in flist]), 10**(-0.4 * sed)

    if outwave is not None:
        onedinterp = interpolate(wave, spectra, axis=-1)
        spectra = onedinterp(outwave)
        wave = outwave

    g = (wave >= wlow) & (wave <= whigh)
    for (lo, hi) in exclude:
        g = g & ((wave < lo) | (wave > hi))
    return wave[g], spectra[:, g]
def observe(fnames):

    #  units: lambda (A), flux: fnu normalized to unity
    dat = load_data()
    filters = load_filters(fnames)

    out = {}
    for name in dat.dtype.names:
        if name == 'blank' or name == 'lambda':
            continue

        # sourcewave: Spectrum wavelength (in AA), ndarray of shape (nwave).
        # sourceflux: Associated flux (assumed to be in erg/s/cm^2/AA), ndarray of shape (nsource,nwave).
        # filterlist: List of filter objects, of length nfilt.
        # array of AB broadband magnitudes, of shape (nsource, nfilter).
        out[name] = getSED(dat['lambda'], (lightspeed/dat['lambda']**2)*dat[name], filters)

    return out
Exemple #20
0
    def generateSEDs(self, pars, filterlist, wave_min=90, wave_max=1e7,
                     keepspec=False, intspec=False, attenuator=None, **extras):
        """
        :returns sed:
            ndarray of shape (nobj,nfilter)

        :returns lbol:
            ndarray of shape (nobj)

        :returns outspectra:
            ndarray of shape (nobj,nwave)
        """
        # Don't use too much memory at once
        maxmod = 1e7 / self.wavelength.shape[0]

        ngrid = pars.shape[0]
        sed = np.zeros([int(ngrid),len(filterlist)])
        lbol = np.zeros(int(ngrid))
        outspectra = None
        if keepspec:
            outspectra = np.zeros([ngrid,self.wavelength.shape[0]])
        elif intspec:
            outspectra = np.zeros(self.wavelength.shape[0])

        # split big model grids to avoid memory constraints
        i = 0
        while (i*maxmod <= ngrid):
            s1, s2 = int((i)*maxmod), int(np.min([(i+1) * maxmod-1, ngrid]))
            spec = self.spectra_from_pars(pars[int(s1):int(s2)], **extras)
            if attenuator is not None:
                spec = attenuator.attenuate_spectrum(self.wavelength, spec,
                                                     pars[s1:s2], **extras)
            sed[s1:s2,:] = observate.getSED(self.wavelength, spec, filterlist)
            lbol[s1:s2] = observate.Lbol(self.wavelength, spec,
                                         wave_min=wave_min, wave_max=wave_max)
            i += 1
            if keepspec:
                outspectra[s1:s2,:] = spec
            elif intspec:
                outspectra += spec.sum(axis=0)

        return sed, lbol, outspectra
Exemple #21
0
def get_mags(wave,spectrum,z,lumdist,formed_mass,filterlist):
    
    # filter parameters
    filters = load_filters(filterlist)

    # redshift offset the spectrum
    a = 1+z
    wa, sa = wave*a, spectrum*a

    # get the absolute magnitudes
    mags = getSED(wa, lightspeed/wa**2 * sa * to_cgs, filters)
    phot = np.atleast_1d(10**(-0.4 * mags))
    
    # get the observed magnitudes
    dfactor = (lumdist*1e5)**2
    phot /= dfactor
    phot *= formed_mass
    phot = mgy_to_mag(phot)
    
    return phot
Exemple #22
0
def all_region_sed(regions, sps, filters=['galex_NUV'], lf_bases=None):
    """
    Given a cloud name (lmc | smc) and a filter, determine the
    broadband flux of each region in that cloud based on the SFHs of
    Harris & Zaritsky 2004 or 2009.  The sfhs are given separately for
    each metallicity; we treat each metallicity independently and sum
    the resulting spectra before determining the broadband flux.
    """

    from sedpy import observate
    header = regions.pop('header', None)  #dump the header

    sps.params['sfh'] = 0  #ssp
    sps.params['imf_type'] = 0  #salpeter
    filterlist = observate.load_filters(filters)

    #set up output
    try:
        nb = len(lfbins)
    except:
        nb = 1
    regname, alllocs = [], []
    allmags = np.zeros([len(regions), len(filterlist)])
    all_lfs = np.zeros([len(regions), nb])

    #loop over regions
    for j, (k, data) in enumerate(regions.iteritems()):
        spec, lf, wave = one_region_sed(data['sfhs'],
                                        data['zmet'],
                                        sps,
                                        lf_bases=lf_bases)

        #project filters
        mags = observate.getSED(wave, spec * bsp.to_cgs, filterlist=filterlist)
        mags = np.atleast_1d(mags)
        allmags[j, :] = mags
        all_lfs[j, :] = lf
        regname.append(k)
        alllocs += [data['loc'].strip()]

    return alllocs, regname, allmags, all_lfs
Exemple #23
0
def test():
    from sedpy import observate
    import fsps
    import matplotlib.pyplot as pl

    filters = ['galex_NUV', 'sdss_u0', 'sdss_r0', 'sdss_r0', 'sdss_i0', 'sdss_z0',
               'bessell_U', 'bessell_B', 'bessell_V', 'bessell_R', 'bessell_I',
               'twomass_J','twomass_H']
    flist = observate.load_filters(filters)

    sps = fsps.StellarPopulation(compute_vega_mags=False)
    wave, spec = sps.get_spectrum(tage=1.0, zmet=2, peraa=True)

    sed = observate.getSED(wave, spec, flist)
    sed_unc = np.abs(np.random.normal(1, 0.3, len(sed)))

    wgrid = np.linspace( 2e3, 13e3, 1000)
    fgrid = np.linspace( -13, -9, 100)
    psed, sedpoints = sed_to_psed(flist, sed, sed_unc, wgrid, fgrid)

    pl.imshow(np.exp(psed).T, cmap='Greys_r',
              interpolation='nearest', origin ='upper', aspect='auto')
Exemple #24
0
    def get_colors_emission_line(self,
                                 zGrid,
                                 age,
                                 ebv,
                                 HaEw,
                                 colorList=None,
                                 logzsol=0,
                                 **kwargs):
        FilterList = observate.load_filters(self.filter_names)
        color_idxs = self._define_colors(colorList)

        ncolors = len(color_idxs)
        nzGrid = len(zGrid)
        color_grid = np.zeros([ncolors, nzGrid])
        for i, z in enumerate(zGrid):
            WaveModel, SpecModel = self.added_emission_line_spectra(
                age, ebv, HaEw, redshift=z, logzsol=logzsol, **kwargs)
            mags = observate.getSED(WaveModel * (1 + z),
                                    SpecModel,
                                    filterlist=FilterList)
            colors = [mags[c[0]] - mags[c[1]] for c in color_idxs]
            color_grid[:, i] = colors
        return color_grid
Exemple #25
0
    def _getPhotometry_iSEDfit(self, iseddict):
        ''' Returns AB magnitude photometry
        '''
        assert set(iseddict.keys()).issuperset(
            set(['tau', 'av', 'mu', 'age', 'mstar', 'zmetal']))

        self.pop.params['sfh'] = 1
        self.pop.params['tau'] = iseddict['tau']

        self.pop.params['dust_type'] = 2
        self.pop.params['dust2'] = 0.92 * iseddict['av'] * iseddict[
            'mu']  # ln(10) * 0.4 * A(V)

        self.pop.params['logzsol'] = np.log10(iseddict['zmetal'] / 0.019)

        self.pop.params['add_neb_emission'] = True
        self.pop.params['add_neb_continuum'] = True

        w, sp = self.pop.get_spectrum(tage=iseddict['age'], peraa=False)

        a = 1. + iseddict['z']  # scale factor

        wave = w * a

        mass = 10**iseddict[
            'mstar'] / self.pop.stellar_mass  # stellar mass scaling

        d_lum = self.cosmo.luminosity_distance(iseddict['z']).value
        d_factor = (d_lum * 1e5)**2

        spec = mass * sp * a * self.to_cgs / d_factor * self.lightspeed / wave**2  # in erg/s/cm^2/AA

        return getSED(wave,
                      spec,
                      filterlist=load_filters([
                          'sdss_u0', 'sdss_g0', 'sdss_r0', 'sdss_i0', 'sdss_z0'
                      ]))
Exemple #26
0
    def get_spectrum(self, outwave=None, filters=None, peraa=False, **kwargs):
        """Return an attenuated, smoothed, distance dimmed stellar spectrum and SED.

        :returns spec:
            The spectrum on the outwave grid (assumed in air), in AB maggies.
            If peraa is True then the spectrum is erg/s/cm^2/AA.

        :returns phot:
            Observed frame photometry in units of AB maggies.  If ``lumdist``
            is not present in the parameters then these are absolute maggies,
            otherwise they are apparent.

        :returns x:
            A blob of extra quantities (e.g. mass, uncertainty)
        """
        self.update(**kwargs)

        # star spectrum (in Lsun/Hz)
        wave, spec, unc = self.get_star_spectrum(**self.params)
        spec *= self.normalize()

        # dust
        if 'dust_curve' in self.params:
            att = self.params['dust_curve'](self._wave, **self.params)
            spec *= np.exp(-att)

        # Redshifting + Wavelength solution.  We also convert to in-air.
        a = 1 + self.params.get('zred', 0)
        b = 0.0

        if 'wavecal_coeffs' in self.params:
            x = wave - wave.min()
            x = 2.0 * (x / x.max()) - 1.0
            c = np.insert(self.params['wavecal_coeffs'], 0, 0)
            # assume coeeficients give shifts in km/s
            b = chebval(x, c) / (lightspeed*1e-13)

        wa, sa = vac2air(wave) * (a + b), spec * a
        if outwave is None:
            outwave = wa

        # Broadening, interpolation onto output wavelength grid
        if 'sigma_smooth' in self.params:
            smspec = self.smoothspec(wa, sa, self.params['sigma_smooth'],
                                     outwave=outwave, **self.params)
        elif outwave is not wa:
            smspec = np.interp(outwave, wa, sa, left=0, right=0)
        else:
            smspec = sa

        # Photometry (observed frame absolute maggies)
        if filters is not None:
            mags = getSED(wa, sa * lightspeed / wa**2 * to_cgs, filters)
            phot = np.atleast_1d(10**(-0.4 * mags))
        else:
            phot = 0.0

        # Distance dimming.  Default to 10pc distance (i.e. absolute)
        dfactor = (self.params.get('lumdist', 1e-5) * 1e5)**2
        if peraa:
            # spectrum will be in erg/s/cm^2/AA
            smspec *= to_cgs / dfactor * lightspeed / outwave**2
        else:
            # Spectrum will be in maggies
            smspec *= to_cgs / dfactor / 1e3 / (3631*jansky_mks)

        # Convert from absolute maggies to apparent maggies
        phot /= dfactor

        return smspec, phot, None
Exemple #27
0
def main(cloud, agb_dust, lf_band, basti=False):
    #Run parameters
    filters = [
        'galex_NUV', 'spitzer_irac_ch1', 'spitzer_irac_ch4', 'spitzer_mips_24'
    ]
    min_tpagb_age = 0.0
    ldir, outdir = 'lf_data/', 'results_predicted/'

    #########
    # Initialize the ingredients (SPS, SFHs, LFs)
    #########
    # SPS
    sps = fsps.StellarPopulation(add_agb_dust_model=True)
    sps.params['sfh'] = 0
    sps.params['agb_dust'] = agb_dust
    dust = ['nodust', 'agbdust']
    sps.params['imf_type'] = 0.0  #salpeter

    filterlist = observate.load_filters(filters)

    # SFHs
    if cloud.lower() == 'lmc':
        regions = utils.lmc_regions()
        nx, ny, dm = 48, 38, 18.5
        zlist = [7, 11, 13, 16]
        if basti:
            zlist = [3, 4, 5, 6]
    elif cloud.lower() == 'smc':
        regions = utils.smc_regions()
        nx, ny, dm = 20, 23, 18.9
        zlist = [7, 13, 16]
        if basti:
            zlist = [3, 5, 6]

    else:
        print('do not understand your MC designation')

    fstring = '{0}z{1:02.0f}_tau{2:02.0f}_irac{3}_n2_test_lf.txt'
    if basti:
        fstring = '{0}z{1:02.0f}_tau{2:02.0f}_basti_vega_n2_irac{3}_SSP.txt'
    lffiles = [fstring.format(ldir, z, agb_dust * 10, lf_band) for z in zlist]
    rheader = regions.pop('header')  #dump the header info from the reg. dict

    # LFs

    lf_bases = [read_lfs(f) for f in lffiles]
    #zero out select ages
    for j, base in enumerate(lf_bases):
        blank = base['ssp_ages'] <= min_tpagb_age
        base['lf'][blank, :] = 0
        plot_lf(base, wlengths[lf_band], lffiles[j])

    #except(NameError):
    #    lf_bases = None
    print(lffiles)
    #############
    # Loop over each region, do SFH integrations, filter convolutions
    # and populate output images and LF cubes
    ############

    im = np.zeros([len(filters), nx, ny])  #flux in each band in each region
    bins = rsed.lbins
    agb = np.zeros([len(bins), nx, ny])  #cumulative LF in each region
    for n, dat in regions.iteritems():
        spec, lf, wave = rsed.one_region_sed(dat['sfhs'],
                                             dat['zmet'],
                                             sps,
                                             lf_bases=lf_bases)
        mags = observate.getSED(wave,
                                spec * rsed.to_cgs,
                                filterlist=filterlist)
        maggies = 10**(-0.4 * np.atleast_1d(mags))
        x, y = utils.regname_to_xy(n, cloud=cloud)
        agb[:, x, y] = lf[:, None] / np.size(x)
        im[:, x, y] = maggies[:, None] / np.size(x)

    #############
    # Write output
    ############
    for i, f in enumerate(filters):
        write_image(im[i, :, :].T, cloud, f, outdir=outdir, agb_dust=agb_dust)

    #write out AGB N(>M) images as fits
    #for lim in np.arange(-6.7, -9.5, -0.5):
    #    ind = np.searchsorted(bins, lim) -1
    #    pyfits.writeto('test.fits', agb[ind,:,:].T, clobber = True)

    #write out AGB N(>M) images as a pickle file
    agb_cube = {}
    agb_cube['agb_clf_cube'] = agb
    agb_cube['mag_bins'] = bins
    out = open(
        "{0}clf.{1}.tau{2:02.0f}.irac{3}.p".format(outdir, cloud.lower(),
                                                   agb_dust * 10, lf_band),
        "wb")
    pickle.dump(agb_cube, out)
    out.close()

    # Plot the total LF
    wave = wlengths[lf_band]
    fig, ax = pl.subplots(1, 1)
    lf_tot = agb.sum(-1).sum(-1)
    ax.plot(bins + dm, lf_tot)
    ax.set_ylabel(r'$N(<M)$ (total for cloud)')
    ax.set_xlabel(r'$m_{}$ (Vega apparent)'.format(wave))
    ax.set_title(cloud.upper())
    ax.set_yscale('log')
    fig.savefig('{0}total_agb_clf.{1}.tau{2:02.0f}.irac{3}.png'.format(
        outdir, cloud.lower(), agb_dust * 10, lf_band))
    pl.close(fig)
Exemple #28
0
    def get_spectrum(self, outwave=None, filters=None, peraa=False, **kwargs):
        """Return an attenuated, smoothed, distance dimmed stellar spectrum and SED.

        :returns spec:
            The spectrum on the outwave grid (assumed in air), in AB maggies.
            If peraa is True then the spectrum is erg/s/cm^2/AA.

        :returns phot:
            Observed frame photometry in units of AB maggies.  If ``lumdist``
            is not present in the parameters then these are absolute maggies,
            otherwise they are apparent.

        :returns x:
            A blob of extra quantities (e.g. mass, uncertainty)
        """
        self.update(**kwargs)

        # star spectrum (in Lsun/Hz)
        wave, spec, unc = self.get_star_spectrum(**self.params)
        spec *= self.normalize()

        # dust
        if 'dust_curve' in self.params:
            att = self.params['dust_curve'](self._wave, **self.params)
            spec *= np.exp(-att)

        # Redshifting + Wavelength solution.  We also convert to in-air.
        a = 1 + self.params.get('zred', 0)
        b = 0.0

        if 'wavecal_coeffs' in self.params:
            x = wave - wave.min()
            x = 2.0 * (x / x.max()) - 1.0
            c = np.insert(self.params['wavecal_coeffs'], 0, 0)
            # assume coeeficients give shifts in km/s
            b = chebval(x, c) / (lightspeed*1e-13)

        wa, sa = vac2air(wave) * (a + b), spec * a
        if outwave is None:
            outwave = wa

        # Broadening, interpolation onto output wavelength grid
        if 'sigma_smooth' in self.params:
            smspec = self.smoothspec(wa, sa, self.params['sigma_smooth'],
                                     outwave=outwave, **self.params)
        elif outwave is not wa:
            smspec = np.interp(outwave, wa, sa, left=0, right=0)
        else:
            smspec = sa

        # Photometry (observed frame absolute maggies)
        if filters is not None:
            mags = getSED(wa, sa * lightspeed / wa**2 * to_cgs, filters)
            phot = np.atleast_1d(10**(-0.4 * mags))
        else:
            phot = 0.0

        # Distance dimming.  Default to 10pc distance (i.e. absolute)
        dfactor = (self.params.get('lumdist', 1e-5) * 1e5)**2
        if peraa:
            # spectrum will be in erg/s/cm^2/AA
            smspec *= to_cgs / dfactor * lightspeed / outwave**2
        else:
            # Spectrum will be in maggies
            smspec *= to_cgs / dfactor / 1e3 / (3631*jansky_mks)

        # Convert from absolute maggies to apparent maggies
        phot /= dfactor

        return smspec, phot, None
Exemple #29
0
        'tau': tau * 1e9,
        'sf_slope': -sf_slope / 1e9,
        'sf_trunc': sf_trunc * 1e9
    }
    mw, mys, mstar = mysps.get_galaxy_spectrum(**sfh_params)
    myspec[i, :] = mys
    # Do some plotting for each age
    wax.plot(sspages,
             mysps.all_ssp_weights,
             '-o',
             label=r'{}={:4.2f}'.format(pname, tage))
    rax.plot(mw, mys / s, label=r'{}={:4.2f}'.format(pname, tage))
    dax.plot(mw, s - mys, label=r'{}={:4.2f}'.format(pname, tage))

# Get synthetic photometry for both sps objects
mags = observate.getSED(sps.wavelengths, spec, filterlist=filters)
mymags = observate.getSED(sps.wavelengths, myspec, filterlist=filters)

# Plot mags vs age
iband = 0
fig, ax = pl.subplots()
ax.plot(ages, mags[:, iband], '-o', label='FSPS, tres={}'.format(int(tres)))
ax.plot(ages, mymags[:, iband], '-o', label='Pro')
ax.set_xlabel('tage (Gyr)')
ax.set_ylabel(r'$M_{{AB}}$ ({})'.format(filters[iband].name))
ax.text(0.1,
        0.85,
        r'$\tau_{{SF}}={:4.2f}, \, \Delta t_{{trunc}}={:4.2f}$'.format(
            tau, delt_trunc),
        transform=ax.transAxes)
ax.legend(loc=0)
Exemple #30
0
def main(cloud, agb_dust, lf_band, basti=False):
    #Run parameters
    filters = ['galex_NUV', 'spitzer_irac_ch1', 'spitzer_irac_ch4', 'spitzer_mips_24']
    min_tpagb_age = 0.0
    ldir, outdir = 'lf_data/', 'results_predicted/'
    
    #########
    # Initialize the ingredients (SPS, SFHs, LFs)
    #########
    # SPS
    sps = fsps.StellarPopulation(add_agb_dust_model = True)
    sps.params['sfh'] = 0
    sps.params['agb_dust'] = agb_dust
    dust = ['nodust', 'agbdust']
    sps.params['imf_type'] = 0.0 #salpeter

    filterlist = observate.load_filters(filters)
    
    # SFHs
    if cloud.lower() == 'lmc':
        regions = utils.lmc_regions()
        nx, ny, dm = 48, 38, 18.5
        zlist = [7, 11, 13, 16]
        if basti:
            zlist = [3,4,5,6]
    elif cloud.lower() == 'smc':
        regions = utils.smc_regions()
        nx, ny, dm = 20, 23, 18.9
        zlist = [7, 13, 16]
        if basti:
            zlist = [3,5,6]

    else:
        print('do not understand your MC designation')
        
    fstring = '{0}z{1:02.0f}_tau{2:02.0f}_irac{3}_n2_test_lf.txt'
    if basti:
        fstring = '{0}z{1:02.0f}_tau{2:02.0f}_basti_vega_n2_irac{3}_SSP.txt'
    lffiles = [fstring.format(ldir, z, agb_dust*10, lf_band) for z in zlist]
    rheader = regions.pop('header') #dump the header info from the reg. dict
    
    # LFs
    
    lf_bases = [read_lfs(f) for f in lffiles]
    #zero out select ages
    for j, base in enumerate(lf_bases):
        blank = base['ssp_ages'] <= min_tpagb_age
        base['lf'][blank,:] = 0
        plot_lf(base, wlengths[lf_band], lffiles[j])

    #except(NameError):
    #    lf_bases = None
    print(lffiles)
    #############
    # Loop over each region, do SFH integrations, filter convolutions
    # and populate output images and LF cubes
    ############
    
    im = np.zeros([ len(filters), nx, ny]) #flux in each band in each region
    bins = rsed.lbins
    agb = np.zeros([ len(bins), nx, ny]) #cumulative LF in each region
    for n, dat in regions.iteritems():
        spec, lf, wave = rsed.one_region_sed(dat['sfhs'], dat['zmet'],
                                             sps, lf_bases=lf_bases)
        mags = observate.getSED(wave, spec * rsed.to_cgs,
                                filterlist = filterlist)
        maggies = 10**(-0.4 * np.atleast_1d(mags))
        x, y = utils.regname_to_xy(n, cloud=cloud)
        agb[:, x, y] = lf[:, None] / np.size(x)
        im[:, x, y] = maggies[:, None]/ np.size(x)

    #############
    # Write output
    ############
    for i, f in enumerate(filters):
        write_image(im[i,:,:].T, cloud, f, outdir=outdir, agb_dust=agb_dust)
    
    #write out AGB N(>M) images as fits
    #for lim in np.arange(-6.7, -9.5, -0.5):
    #    ind = np.searchsorted(bins, lim) -1
    #    pyfits.writeto('test.fits', agb[ind,:,:].T, clobber = True)

    #write out AGB N(>M) images as a pickle file
    agb_cube = {}
    agb_cube['agb_clf_cube'] = agb
    agb_cube['mag_bins'] = bins
    out = open("{0}clf.{1}.tau{2:02.0f}.irac{3}.p".format(outdir, cloud.lower(), agb_dust*10, lf_band), "wb")
    pickle.dump(agb_cube, out)
    out.close()

    # Plot the total LF
    wave = wlengths[lf_band]
    fig, ax = pl.subplots(1,1)
    lf_tot = agb.sum(-1).sum(-1)
    ax.plot(bins + dm, lf_tot)
    ax.set_ylabel(r'$N(<M)$ (total for cloud)')
    ax.set_xlabel(r'$m_{}$ (Vega apparent)'.format(wave))
    ax.set_title(cloud.upper())
    ax.set_yscale('log')
    fig.savefig('{0}total_agb_clf.{1}.tau{2:02.0f}.irac{3}.png'.format(outdir, cloud.lower(), agb_dust*10, lf_band))
    pl.close(fig)
Exemple #31
0
Fichier : loo.py Projet : bd-j/psi
    ax.plot(psi.wavelengths, predicted[bad,:], label='predicted')
    ax.plot(psi.wavelengths, psi.training_spectra[bad,:], label='actual')
    ax.text(0.05, 0.9, "#{}, RMS={:4.1f}%".format(psi.training_labels[bad]['miles_id'], rms[bad]),
            transform=ax.transAxes, fontsize=10)
    ax.text(0.7, 0.05, title, transform=ax.transAxes, fontsize=10)
    if i == 0:
        ax.legend(loc=0, prop={'size':8})
    if i < 9:
        ax.set_xticklabels([])
badfig.savefig('figures/worst10_{}.pdf'.format(ts))

# B-V colors
from sedpy import observate
filt = observate.load_filters(['hipparcos_V', 'hipparcos_B'])
#filt = observate.load_filters(['bessell_V', 'bessell_B'])
pmags_actual = observate.getSED(psi.wavelengths, psi.training_spectra, filterlist=filt)
pmags_predicted = observate.getSED(psi.wavelengths, predicted, filterlist=filt)
# Compare colors to observations
mid, b, v = np.genfromtxt('../../data/tycho2_b_v.dat', unpack=True)
bv = b - v
mid = mid.astype(int)
inds = np.zeros(len(mid)) - 1
mlist = psi.training_labels['miles_id'].tolist()
for i, m in enumerate(mid):
    if m in mlist:
        inds[i] = mlist.index(m)
inds = inds.astype(int)
good = inds >= 0

fig, axes = pl.subplots(2, 1)
ax= axes[0]
Exemple #32
0
]

# Calculate SKIRT attenuation curve (requires dust and nodust spectra)
dustSpec_SKIRT = np.load(
    '/scratch/ntf229/RT_fit/resources/SKIRT/' + galaxies[i] +
    '/maxLevel13/wavelengths250/numPhotons3e8/inc0/dust/spec.npy'
) / 3631  # convert from Jy to maggies
dustSpec_SKIRT = 22.5 - 2.5 * np.log10(
    dustSpec_SKIRT * 1e9)  # convert to Pogson magnitudes

# Calculate r-band luminosity for each SKIRT spectrum
f_lambda_cgs = (1 / 33333) * (1 / (wave_SKIRT**2)) * (dustSpec_SKIRT * 3631)

filterlist = observate.load_filters(
    ["sdss_z0", "wise_w3", "herschel_pacs_100"])  # ~ 1, 10, 100 microns
mags = observate.getSED(angstroms, f_lambda_cgs,
                        filterlist=filters)  # AB magnitudes

# DustPedia Sample
file = np.loadtxt('DustPedia_Aperture_Photometry_2.2.csv', dtype=str)

# file[0] are column names
# columns are separated by commas
# empty columns are still separated by a comma
# All the photometric measurements are in Jy

full_sdss_z0 = []
full_wise_w3 = []
full_pacs_100 = []

count = 0
Exemple #33
0
    sps.params['sf_slope'] = sf_slope
    sps.params['sf_trunc'] = sf_trunc
    w, s = sps.get_spectrum(tage=tage, peraa=True)
    spec[i, :] = s
    # Set up Pro parameters, with unit conversions, get spectrum, and store it.
    sfh_params = {'tage': tage*1e9, 'tau': tau*1e9,
                  'sf_slope': -sf_slope / 1e9, 'sf_trunc': sf_trunc*1e9}
    mw, mys, mstar = mysps.get_galaxy_spectrum(**sfh_params)
    myspec[i, :] = mys
    # Do some plotting for each age
    wax.plot(sspages, mysps.all_ssp_weights, '-o', label=r'{}={:4.2f}'.format(pname, tage))
    rax.plot(mw, mys / s, label=r'{}={:4.2f}'.format(pname, tage))
    dax.plot(mw, s - mys, label=r'{}={:4.2f}'.format(pname, tage))

# Get synthetic photometry for both sps objects
mags = observate.getSED(sps.wavelengths, spec, filterlist=filters)
mymags = observate.getSED(sps.wavelengths, myspec, filterlist=filters)

# Plot mags vs age
iband = 0
fig, ax = pl.subplots()
ax.plot(ages, mags[:, iband], '-o', label='FSPS, tres={}'.format(int(tres)))
ax.plot(ages, mymags[:, iband], '-o', label='Pro')
ax.set_xlabel('tage (Gyr)')
ax.set_ylabel(r'$M_{{AB}}$ ({})'.format(filters[iband].name))
ax.text(0.1, 0.85, r'$\tau_{{SF}}={:4.2f}, \, \Delta t_{{trunc}}={:4.2f}$'.format(tau, delt_trunc),
        transform=ax.transAxes)
ax.legend(loc=0)
fig.savefig('figures/sft_compare.pdf')
# Prettify axes
rax.set_xlim(1e3, 2e4)
Exemple #34
0
    def get_spectrum(self, outwave=None, filters=None, component=-1, **params):
        """Get a spectrum and SED for the given params, choosing from different
        possible components.

        :param outwave: (default: None)
            Desired *vacuum* wavelengths.  Defaults to the values in
            `sps.wavelength`.

        :param peraa: (default: False)
            If `True`, return the spectrum in erg/s/cm^2/AA instead of AB
            maggies.

        :param filters: (default: None)
            A list of filter objects for which you'd like photometry to be
            calculated.

        :param component: (optional, default: -1)
            An optional array where each element gives the index of the
            component from which to choose the magnitude.  scalar or iterable
            of same length as `filters`

        :param **params:
            Optional keywords giving parameter values that will be used to
            generate the predicted spectrum.

        :returns spec:
            Observed frame component spectra in AB maggies, unless `peraa=True` in which
            case the units are erg/s/cm^2/AA.  (ncomp+1, nwave)

        :returns phot:
            Observed frame photometry in AB maggies, ndarray of shape (ncomp+1, nfilters)

        :returns mass_frac:
            The ratio of the surviving stellar mass to the total mass formed.
        """

        # Spectrum in Lsun/Hz per solar mass formed, restframe
        wave, spectrum, mfrac = self.get_galaxy_spectrum(**params)

        # Redshifting + Wavelength solution
        # We do it ourselves.
        a = 1 + self.params.get('zred', 0)
        af = a
        b = 0.0

        if 'wavecal_coeffs' in self.params:
            x = wave - wave.min()
            x = 2.0 * (x / x.max()) - 1.0
            c = np.insert(self.params['wavecal_coeffs'], 0, 0)
            # assume coeeficients give shifts in km/s
            b = chebval(x, c) / (lightspeed * 1e-13)

        wa, sa = wave * (a + b), spectrum * af  # Observed Frame
        if outwave is None:
            outwave = wa

        # Observed frame photometry, as absolute maggies
        if filters is not None:
            # Magic to only do filter projections for unique filters, and get a
            # mapping back into this list of unique filters
            # note that this may scramble order of unique_filters
            fnames = [f.name for f in filters]
            unique_names, uinds, filter_ind = np.unique(fnames,
                                                        return_index=True,
                                                        return_inverse=True)
            unique_filters = np.array(filters)[uinds]
            mags = getSED(wa, lightspeed / wa**2 * sa * to_cgs, unique_filters)
            phot = np.atleast_1d(10**(-0.4 * mags))
        else:
            phot = 0.0
            filter_ind = 0

        # Distance dimming and unit conversion
        zred = self.params.get('zred', 0.0)
        if (zred == 0) or ('lumdist' in self.params):
            # Use 10pc for the luminosity distance (or a number
            # provided in the dist key in units of Mpc)
            dfactor = (self.params.get('lumdist', 1e-5) * 1e5)**2
        else:
            lumdist = cosmo.luminosity_distance(zred).value
            dfactor = (lumdist * 1e5)**2

        # Spectrum will be in maggies
        sa *= to_cgs / dfactor / (3631 * jansky_cgs)

        # Convert from absolute maggies to apparent maggies
        phot /= dfactor

        # Mass normalization
        mass = np.atleast_1d(self.params['mass'])
        mass = np.squeeze(mass.tolist() + [mass.sum()])

        sa = (sa * mass[:, None])
        phot = (phot * mass[:, None])[component, filter_ind]

        return sa, phot, mfrac
Exemple #35
0
def total_galaxy_data(sfhfilename, zindex, filternames = None,
                      basti=False, lfstring=None, agb_dust=1.0):

    total_sfhs = [load_angst_sfh(sfhfilename)]
    rsed.lfbins += total_sfhs[0]['dmod'][0]
    zlist = [zindex]
    
    #########
    # Initialize the ingredients (SPS, SFHs, LFs)
    #########
    # SPS
    if filternames is not None:
        sps = fsps.StellarPopulation(add_agb_dust_model = True)
        sps.params['sfh'] = 0
        sps.params['agb_dust'] = agb_dust
        dust = ['nodust', 'agbdust']
        sps.params['imf_type'] = 0.0 #salpeter
        filterlist = observate.load_filters(filternames)
        zmets = [sps.zlegend[zindex-1]]
    else:
        filterlist = None
        
    #############
    # Sum the region SFHs into a total integrated SFH, and do the
    # temporal interpolations to generate integrated spectra, LFs, and
    # SEDs
    ############
    
    # Get LFs broken out by age and metallicity as well as the total
    # LFs. these are stored as a list of different metallicities
    bins = rsed.lfbins 
    if lfstring is not None:
        lffiles = [lfstring.format(z) for z in zlist]
        lf_base = [read_villaume_lfs(f) for f in lffiles]
        lfs_zt, lf, logages = rsed.one_region_lfs(copy.deepcopy(total_sfhs), lf_base)
    else:
        lfs_zt, lf, logages = None, None, None
    # Get spectrum and magnitudes
    if filterlist is not None:
        spec, wave, mass = rsed.one_region_sed(copy.deepcopy(total_sfhs), zmets, sps )
        mags = observate.getSED(wave, spec*rsed.to_cgs, filterlist=filterlist)
        maggies = 10**(-0.4 * np.atleast_1d(mags))
    else:
        maggies, mass = None, None
    
    #############
    # Write output
    ############
    total_values = {}
    total_values['agb_clf'] = lf
    total_values['agb_clfs_zt'] = lfs_zt
    total_values['clf_mags'] = bins.copy()
    total_values['logages'] = logages
    total_values['sed_ab_maggies'] = maggies
    total_values['sed_filters'] = filternames
    total_values['lffile'] = lfstring
    total_values['mstar'] = mass
    total_values['zlist'] = zlist

    rsed.lfbins -= total_sfhs[0]['dmod'][0]
    
    return total_values, total_sfhs
Exemple #36
0
    def get_spectrum(self, outwave=None, filters=None, peraa=False, **params):
        """Get a spectrum and SED for the given params.
        ripped from SSPBasis
        addition: check for flag nebeminspec. if not true,
        add emission lines directly to photometry
        """

        # Spectrum in Lsun/Hz per solar mass formed, restframe
        wave, spectrum, mfrac = self.get_galaxy_spectrum(**params)

        # Redshifting + Wavelength solution
        # We do it ourselves.
        a = 1 + self.params.get('zred', 0)
        af = a
        b = 0.0

        if 'wavecal_coeffs' in self.params:
            x = wave - wave.min()
            x = 2.0 * (x / x.max()) - 1.0
            c = np.insert(self.params['wavecal_coeffs'], 0, 0)
            # assume coeeficients give shifts in km/s
            b = chebval(x, c) / (lightspeed*1e-13)

        wa, sa = wave * (a + b), spectrum * af  # Observed Frame
        if outwave is None:
            outwave = wa
        
        spec_aa = lightspeed/wa**2 * sa # convert to perAA
        # Observed frame photometry, as absolute maggies
        if filters is not None:
            mags = observate.getSED(wa, spec_aa * to_cgs, filters)
            phot = np.atleast_1d(10**(-0.4 * mags))
        else:
            phot = 0.0

        ### if we don't have emission lines, add them
        if (not self.params['nebemlineinspec']) and self.params['add_neb_emission']:
            phot += self.nebline_photometry(filters,a-1)*to_cgs

        # Spectral smoothing.
        do_smooth = (('sigma_smooth' in self.params) and
                     ('sigma_smooth' in self.reserved_params))
        if do_smooth:
            # We do it ourselves.
            smspec = self.smoothspec(wa, sa, self.params['sigma_smooth'],
                                     outwave=outwave, **self.params)
        elif outwave is not wa:
            # Just interpolate
            smspec = np.interp(outwave, wa, sa, left=0, right=0)
        else:
            # no interpolation necessary
            smspec = sa

        # Distance dimming and unit conversion
        zred = self.params.get('zred', 0.0)
        if (zred == 0) or ('lumdist' in self.params):
            # Use 10pc for the luminosity distance (or a number
            # provided in the dist key in units of Mpc)
            dfactor = (self.params.get('lumdist', 1e-5) * 1e5)**2
        else:
            lumdist = WMAP9.luminosity_distance(zred).value
            dfactor = (lumdist * 1e5)**2
        if peraa:
            # spectrum will be in erg/s/cm^2/AA
            smspec *= to_cgs / dfactor * lightspeed / outwave**2
        else:
            # Spectrum will be in maggies
            smspec *= to_cgs / dfactor / 1e3 / (3631*jansky_mks)

        # Convert from absolute maggies to apparent maggies
        phot /= dfactor

        # Mass normalization
        mass = np.sum(self.params.get('mass', 1.0))
        if np.all(self.params.get('mass_units', 'mstar') == 'mstar'):
            # Convert from current stellar mass to mass formed
            mass /= mfrac

        return smspec * mass, phot * mass, mfrac
Exemple #37
0
def total_cloud_data(cloud,
                     filternames=None,
                     basti=False,
                     lfstring=None,
                     agb_dust=1.0,
                     one_metal=None):

    #########
    # SPS
    #########
    #
    if filternames is not None:
        sps = fsps.StellarPopulation(add_agb_dust_model=True)
        sps.params['sfh'] = 0
        sps.params['agb_dust'] = agb_dust
        dust = ['nodust', 'agbdust']
        sps.params['imf_type'] = 0.0  #salpeter
        filterlist = observate.load_filters(filternames)
    else:
        filterlist = None
    ##########
    # SFHs
    ##########
    regions, nx, ny, zlist, zlist_basti = cloud_info[cloud.lower()]
    if basti:
        zlist = basti_zlist
    if 'header' in regions.keys():
        rheader = regions.pop(
            'header')  #dump the header info from the reg. dict
    total_sfhs = None
    for n, dat in regions.iteritems():
        total_sfhs = sum_sfhs(total_sfhs, dat['sfhs'])
        total_zmet = dat['zmet']
    #collapse SFHs to one metallicity
    if one_metal is not None:
        ts = None
        for sfh in total_sfhs:
            ts = sum_sfhs(ts, sfh)
        total_sfh = ts
        zlist = [zlist[one_metal]]
        total_zmet = [total_zmet[one_metal]]
    #############
    # LFs
    ############
    bins = rsed.lfbins
    if lfstring is not None:
        # these are stored as a list of different metallicities
        lffiles = [lfstring.format(z) for z in zlist]
        lf_base = [read_villaume_lfs(f) for f in lffiles]
        #get LFs broken out by age and metallicity as well as the total
        lfs_zt, lf, logages = rsed.one_region_lfs(copy.deepcopy(total_sfhs),
                                                  lf_base)
    else:
        lfs_zt, lf, logages = None, None, None
    ###########
    # SED
    ############
    if filterlist is not None:
        spec, wave, mass = rsed.one_region_sed(copy.deepcopy(total_sfhs),
                                               total_zmet, sps)
        mags = observate.getSED(wave,
                                spec * rsed.to_cgs,
                                filterlist=filterlist)
        maggies = 10**(-0.4 * np.atleast_1d(mags))
    else:
        maggies, mass = None, None

    #############
    # Write output
    ############
    total_values = {}
    total_values['agb_clf'] = lf
    total_values['agb_clfs_zt'] = lfs_zt
    total_values['clf_mags'] = bins
    total_values['logages'] = logages
    total_values['sed_ab_maggies'] = maggies
    total_values['sed_filters'] = filternames
    total_values['lffile'] = lfstring
    total_values['mstar'] = mass
    total_values['zlist'] = zlist
    return total_values, total_sfhs
Exemple #38
0
def total_galaxy_data(sfhfilename,
                      zindex,
                      filternames=None,
                      basti=False,
                      lfstring=None,
                      agb_dust=1.0):

    total_sfhs = [load_angst_sfh(sfhfilename)]
    rsed.lfbins += total_sfhs[0]['dmod'][0]
    zlist = [zindex]

    #########
    # Initialize the ingredients (SPS, SFHs, LFs)
    #########
    # SPS
    if filternames is not None:
        sps = fsps.StellarPopulation(add_agb_dust_model=True)
        sps.params['sfh'] = 0
        sps.params['agb_dust'] = agb_dust
        dust = ['nodust', 'agbdust']
        sps.params['imf_type'] = 0.0  #salpeter
        filterlist = observate.load_filters(filternames)
        zmets = [sps.zlegend[zindex - 1]]
    else:
        filterlist = None

    #############
    # Sum the region SFHs into a total integrated SFH, and do the
    # temporal interpolations to generate integrated spectra, LFs, and
    # SEDs
    ############

    # Get LFs broken out by age and metallicity as well as the total
    # LFs. these are stored as a list of different metallicities
    bins = rsed.lfbins
    if lfstring is not None:
        lffiles = [lfstring.format(z) for z in zlist]
        lf_base = [read_villaume_lfs(f) for f in lffiles]
        lfs_zt, lf, logages = rsed.one_region_lfs(copy.deepcopy(total_sfhs),
                                                  lf_base)
    else:
        lfs_zt, lf, logages = None, None, None
    # Get spectrum and magnitudes
    if filterlist is not None:
        spec, wave, mass = rsed.one_region_sed(copy.deepcopy(total_sfhs),
                                               zmets, sps)
        mags = observate.getSED(wave,
                                spec * rsed.to_cgs,
                                filterlist=filterlist)
        maggies = 10**(-0.4 * np.atleast_1d(mags))
    else:
        maggies, mass = None, None

    #############
    # Write output
    ############
    total_values = {}
    total_values['agb_clf'] = lf
    total_values['agb_clfs_zt'] = lfs_zt
    total_values['clf_mags'] = bins.copy()
    total_values['logages'] = logages
    total_values['sed_ab_maggies'] = maggies
    total_values['sed_filters'] = filternames
    total_values['lffile'] = lfstring
    total_values['mstar'] = mass
    total_values['zlist'] = zlist

    rsed.lfbins -= total_sfhs[0]['dmod'][0]

    return total_values, total_sfhs
    #  and IR luminosities
    wave, spec, mass, lir = bsp.bursty_sps(lt,
                                           sfr,
                                           sps,
                                           lookback_time=t_lookback,
                                           av=av,
                                           dav=dav,
                                           nsplit=30)
    for j, jt in enumerate(t_lookback):
        pl.plot(wave,
                spec[j, :] * wave * bsp.to_cgs,
                label='{0} @ {1}'.format(objname[i], tl[j]))

    # Project onto filters to get
    #   absolute magnitudes
    mags = observate.getSED(wave, spec * bsp.to_cgs, filterlist=filterlist)

    # Get the intrinsic spectrum and project onto filters
    wave, spec, mass, _ = bsp.bursty_sps(lt,
                                         sfr,
                                         sps,
                                         lookback_times=t_lookback,
                                         av=None,
                                         dav=None)
    mags_int = observate.getSED(wave, spec * bsp.to_cgs, filterlist=filterlist)

pl.xlim(1e3, 1e4)
pl.ylim(1e-3, 1e1)
pl.yscale('log')
pl.xlabel(r'wavelength ($\AA$)')
pl.ylabel(r'$\lambda$L$_\lambda$ (erg/s/cm$^2$ @ 10pc)')
def standard_star_compare():
    # This is the filters and magnitudes for the calibrator star
    filters = load_filters(["sdss_g0", "sdss_r0", "sdss_i0", "sdss_z0"])

    # Get a reasonable set of model spectra
    libwave, libflux, libparams = get_library()

    #store all the flux calibration vectors into an ndarray
    flux_calib_ndarray = []
    #print(flux_calib_ndarray.shape)

    #NEED TO CHANGE 0 TO INDEX BASED ON CROSSMATCH
    #loop over 0
    for i, val in enumerate(std_stars_df):

        star_mags = np.array([mask_std_stars['psfMag_g'][i],\
                          mask_std_stars['psfMag_r'][i],\
                          mask_std_stars['psfMag_i'][i],\
                          mask_std_stars['psfMag_z'][i]])

        #bino spectrum for calibration star
        data_wave, data_flux = spec_fetcher(val['Slit ID'])
        data_flux *= 1e-19  # header units

        # choose the model with colors closest to the calibrator
        best_model = choose_model(star_mags, filters, libwave, libflux)

        # Now work out the normalization of the model from the average magnitude offset
        best_sed = getSED(libwave, best_model, filters)
        dm = np.mean(star_mags - best_sed)
        conv = 10**(-0.4 * dm)

        # Here, finally, is the fluxed model (erg/s/cm^2/AA)
        fluxed_model = best_model * conv

        # Now get the model on the same wavelength vector as the data
        z = 0.0  # redshift of the star, if known. #?
        a = (1 + z)
        fluxed_model_interp = np.interp(data_wave, libwave * a, fluxed_model)
        calibration = data_flux / fluxed_model_interp

        # You probably want to median filter the calibration vector.  # Perhaps
        # after some sigma clipping.  differences on small scales could be due to
        # model imperfections (wrong metallicity, wrong gravity for model, LSF
        # mismatch)
        # you could also fit the calibration vector with a polynomial, taking into
        # account errors
        smoothed_calibration = medfilt(calibration, 101)

        #fig, axes = plt.subplots(1, 1, sharex=True, figsize=(13, 11))
        #plt.plot(data_wave, calibration, label="raw calibration")
        plt.plot(data_wave, smoothed_calibration, label="smoothed calibration")
        plt.xlabel("Wavelength [A]")
        plt.ylabel("actual / input")

        flux_calib_ndarray.append(smoothed_calibration)
        #print(np.min(smoothed_calibration))
        #ax.legend()
        #ax.set_ylabel("actual / input")
        #plt.ylim([0, 0.1])
        #plt.xlim([7500, 7700])

    flux_calib_ndarray = np.array(flux_calib_ndarray)
    #mean_calib = flux_calib_ndarray.mean(axis = 0)
    #mean_calib = np.true_divide(flux_calib_ndarray.sum(0),(flux_calib_ndarray!=0).sum(0)) #ignore all the 0 values
    flux_calib_ndarray[flux_calib_ndarray == 0] = np.nan
    mean_calib = np.nanmean(flux_calib_ndarray, axis=0)
    mean_calib[np.isnan(mean_calib) == True] = 0.
    plt.plot(data_wave, mean_calib, label="mean calibration", c='k', ls="--")
    return mean_calib
Exemple #41
0
    def get_spectrum(self, outwave=None, filters=None, peraa=False, **params):
        """Get a spectrum and SED for the given params.

        :param outwave: (default: None)
            Desired *vacuum* wavelengths.  Defaults to the values in
            `sps.wavelength`.

        :param peraa: (default: False)
            If `True`, return the spectrum in erg/s/cm^2/AA instead of AB
            maggies.

        :param filters: (default: None)
            A list of filter objects for which you'd like photometry to be calculated. 

        :param **params:
            Optional keywords giving parameter values that will be used to
            generate the predicted spectrum.

        :returns spec:
            Observed frame spectrum in AB maggies, unless `peraa=True` in which
            case the units are erg/s/cm^2/AA.

        :returns phot:
            Observed frame photometry in AB maggies.

        :returns mass_frac:
            The ratio of the surviving stellar mass to the total mass formed.
        """
        # Spectrum in Lsun/Hz per solar mass formed, restframe
        wave, spectrum, mfrac = self.get_galaxy_spectrum(**params)

        # Redshifting + Wavelength solution
        # We do it ourselves.
        a = 1 + self.params.get('zred', 0)
        af = a
        b = 0.0

        if 'wavecal_coeffs' in self.params:
            x = wave - wave.min()
            x = 2.0 * (x / x.max()) - 1.0
            c = np.insert(self.params['wavecal_coeffs'], 0, 0)
            # assume coeeficients give shifts in km/s
            b = chebval(x, c) / (lightspeed*1e-13)

        wa, sa = wave * (a + b), spectrum * af  # Observed Frame
        if outwave is None:
            outwave = wa

        # Observed frame photometry, as absolute maggies
        if filters is not None:
            mags = getSED(wa, lightspeed/wa**2 * sa * to_cgs, filters)
            phot = np.atleast_1d(10**(-0.4 * mags))
        else:
            phot = 0.0

        # Spectral smoothing.
        do_smooth = (('sigma_smooth' in self.params) and
                     ('sigma_smooth' in self.reserved_params))
        if do_smooth:
            # We do it ourselves.
            smspec = self.smoothspec(wa, sa, self.params['sigma_smooth'],
                                     outwave=outwave, **self.params)
        elif outwave is not wa:
            # Just interpolate
            smspec = np.interp(outwave, wa, sa, left=0, right=0)
        else:
            # no interpolation necessary
            smspec = sa

        # Distance dimming and unit conversion
        zred = self.params.get('zred', 0.0)
        if (zred == 0) or ('lumdist' in self.params):
            # Use 10pc for the luminosity distance (or a number
            # provided in the dist key in units of Mpc)
            dfactor = (self.params.get('lumdist', 1e-5) * 1e5)**2
        else:
            lumdist = cosmo.luminosity_distance(zred).value
            dfactor = (lumdist * 1e5)**2
        if peraa:
            # spectrum will be in erg/s/cm^2/AA
            smspec *= to_cgs / dfactor * lightspeed / outwave**2
        else:
            # Spectrum will be in maggies
            smspec *= to_cgs / dfactor / (3631*jansky_cgs)

        # Convert from absolute maggies to apparent maggies
        phot /= dfactor

        # Mass normalization
        mass = np.sum(self.params.get('mass', 1.0))
        if np.all(self.params.get('mass_units', 'mformed') == 'mstar'):
            # Convert input normalization units from current stellar mass to mass formed
            mass /= mfrac

        return smspec * mass, phot * mass, mfrac
Exemple #42
0
def build_obs(objid=0, luminosity_distance=None, **kwargs):
    """Load photometry from an ascii file.  Assumes the following columns:
    `objid`, `filterset`, [`mag0`,....,`magN`] where N >= 11.  The User should
    modify this function (including adding keyword arguments) to read in their
    particular data format and put it in the required dictionary.

    :param objid:
        The object id for the row of the photomotery file to use.  Integer.
        Requires that there be an `objid` column in the ascii file.

    :param phottable:
        Name (and path) of the ascii file containing the photometry.

    :param luminosity_distance: (optional)
        The Johnson 2013 data are given as AB absolute magnitudes.  They can be
        turned into apparent magnitudes by supplying a luminosity distance.

    :returns obs:
        Dictionary of observational data.
    """

    from prospect.utils.obsutils import fix_obs

    #filterlist = load_filters(['sdss_u0', 'sdss_g0', 'sdss_r0', 'sdss_i0', 'sdss_z0',
    #               'galex_FUV', 'galex_NUV', 'wise_w1', 'wise_w2',
    #               'wise_w3', 'wise_w4'])

    filterlist = load_filters(args.filters)

    microns = np.load('{0}/Prospector_files/wave.npy'.format(args.path))
    angstroms = microns * 1e4

    spec = np.load('{0}/Prospector_files/spec.npy'.format(
        args.path))  # units of Jy
    f_lambda_cgs = (1 / 33333) * (1 / (angstroms**2)) * spec

    mags = getSED(angstroms, f_lambda_cgs,
                  filterlist=filterlist)  # AB magnitudes

    #print('AB mags', mags)
    #np.save('ab_mags.npy', mags)

    maggies = 10**(-0.4 * mags)  # convert to maggies

    wave_eff = np.zeros(len(filterlist))

    for i in range(len(filterlist)):
        filterlist[i].get_properties()
        wave_eff[i] = filterlist[i].wave_effective

    print('maggies', maggies)
    print('effective wavelengths', wave_eff)

    # Build output dictionary.
    obs = {}
    obs['filters'] = filterlist
    obs['maggies'] = maggies
    obs['maggies_unc'] = obs['maggies'] * 0.07
    obs['phot_mask'] = np.isfinite(np.squeeze(maggies))
    obs['wavelength'] = None
    obs['spectrum'] = None
    obs['unc'] = None

    obs['objid'] = None

    # This ensures all required keys are present and adds some extra useful info
    obs = fix_obs(obs)

    return obs
Exemple #43
0
def get_redshifted_photometry(lambda_aa, f_lambda_aa, redshift_grid, filter_list, apply_madau_igm=False):
    """
    -

    Parameters
    ----------
    lambda_aa, f_lambda_aa: ndarray (size, )
        wavelength (in Angstrom) and rest-frame spectral energy distribution f_nu(lambda)
    redshift_grid: ndarray (size, )
        array of redshift values to compute the photometry on
    filter_list: list of strings
        names of the photometric filters (will load with the SEDPY package)

    Returns
    -------

    https://www.roe.ac.uk/ifa/postgrad/pedagogy/2008_phillips.pdf
    https://arxiv.org/pdf/astro-ph/0210394.pdf

    """

    numBands = len(filter_list)
    redshift_factors = np.zeros((redshift_grid.size,))
    redshifted_fluxes = np.zeros((redshift_grid.size, numBands))
    redshifted_fluxes2 = np.zeros((redshift_grid.size, numBands))

    for iz, redshift in enumerate(redshift_grid):

        lambda_aa_redshifted = lambda_aa * (1 + redshift)

        redshift_factors[iz] = (
            D_L(redshift) ** 2.0 * (4 * np.pi) * (1 + redshift)
        ) ** -1
        # separate redshift factor
        f_lambda_aa_redshifted = f_lambda_aa
        if apply_madau_igm:
            tau = igm_madau_tau(lambda_aa, redshift)
            f_lambda_aa_redshifted *= np.exp(-tau)

        f_nu_aa_redshifted = f_lambda_aa_redshifted * lambda_aa_redshifted ** 2 / 3e18


        # get magnitudes using sedpy
        mags = observate.getSED(
            lambda_aa_redshifted, f_lambda_aa_redshifted, filterlist=filter_list
        )
        redshifted_fluxes[iz, :] = 10 ** (
            -0.4 * (mags + 48.60)
        )  # need to convert back from AB to cgs

        for ib, filter in enumerate(filter_list):

            filt_lambda, filt_spec = filter.wavelength * 1, filter.transmission * 1

            # need to normalize by this integral to satisfy photometry equations
            filt_spec /= np.trapz(filt_spec / filt_lambda, x=filt_lambda)

            # interpolate filter on redshifted lambda_aa_redshifted grid
            tspec = interp(lambda_aa_redshifted, filt_lambda, filt_spec)
            # print(lambda_aa_redshifted)
            redshifted_fluxes2[iz, ib] = np.trapz(
                f_nu_aa_redshifted * tspec / lambda_aa_redshifted,
                x=lambda_aa_redshifted,
            )

            # tODO: implement the other way around.
            # tspec = interp(filt_lambda, spec_lambda * (1 + zred), spec_f_lambda)
            # redshifted_fluxes3[iz, ib] = np.trapz(tspec * filt_spec / filt_lambda, x=filt_lambda)

    return redshifted_fluxes, redshifted_fluxes2, redshift_factors
Exemple #44
0
    def get_spectrum(self, outwave=None, filters=None, peraa=False, **params):
        """Get a spectrum and SED for the given params.

        :param outwave: (default: None)
            Desired *vacuum* wavelengths.  Defaults to the values in
            `sps.wavelength`.

        :param peraa: (default: False)
            If `True`, return the spectrum in erg/s/cm^2/AA instead of AB
            maggies.

        :param filters: (default: None)
            A list of filter objects for which you'd like photometry to be calculated. 

        :param **params:
            Optional keywords giving parameter values that will be used to
            generate the predicted spectrum.

        :returns spec:
            Observed frame spectrum in AB maggies, unless `peraa=True` in which
            case the units are erg/s/cm^2/AA.

        :returns phot:
            Observed frame photometry in AB maggies.

        :returns mass_frac:
            The ratio of the surviving stellar mass to the total mass formed.
        """
        # Spectrum in Lsun/Hz per solar mass formed, restframe
        wave, spectrum, mfrac = self.get_galaxy_spectrum(**params)

        # Redshifting + Wavelength solution
        # We do it ourselves.
        a = 1 + self.params.get('zred', 0)
        af = a
        b = 0.0

        if 'wavecal_coeffs' in self.params:
            x = wave - wave.min()
            x = 2.0 * (x / x.max()) - 1.0
            c = np.insert(self.params['wavecal_coeffs'], 0, 0)
            # assume coeeficients give shifts in km/s
            b = chebval(x, c) / (lightspeed*1e-13)

        wa, sa = wave * (a + b), spectrum * af  # Observed Frame
        if outwave is None:
            outwave = wa

        # Observed frame photometry, as absolute maggies
        if filters is not None:
            mags = getSED(wa, lightspeed/wa**2 * sa * to_cgs, filters)
            phot = np.atleast_1d(10**(-0.4 * mags))
        else:
            phot = 0.0

        # Spectral smoothing.
        do_smooth = (('sigma_smooth' in self.params) and
                     ('sigma_smooth' in self.reserved_params))
        if do_smooth:
            # We do it ourselves.
            smspec = self.smoothspec(wa, sa, self.params['sigma_smooth'],
                                     outwave=outwave, **self.params)
        elif outwave is not wa:
            # Just interpolate
            smspec = np.interp(outwave, wa, sa, left=0, right=0)
        else:
            # no interpolation necessary
            smspec = sa

        # Distance dimming and unit conversion
        zred = self.params.get('zred', 0.0)
        if (zred == 0) or ('lumdist' in self.params):
            # Use 10pc for the luminosity distance (or a number
            # provided in the dist key in units of Mpc)
            dfactor = (self.params.get('lumdist', 1e-5) * 1e5)**2
        else:
            lumdist = cosmo.luminosity_distance(zred).value
            dfactor = (lumdist * 1e5)**2
        if peraa:
            # spectrum will be in erg/s/cm^2/AA
            smspec *= to_cgs / dfactor * lightspeed / outwave**2
        else:
            # Spectrum will be in maggies
            smspec *= to_cgs / dfactor / (3631*jansky_cgs)

        # Convert from absolute maggies to apparent maggies
        phot /= dfactor

        # Mass normalization
        mass = np.sum(self.params.get('mass', 1.0))
        if np.all(self.params.get('mass_units', 'mformed') == 'mstar'):
            # Convert input normalization units from current stellar mass to mass formed
            mass /= mfrac

        return smspec * mass, phot * mass, mfrac
Exemple #45
0
    def create_grid(self,fname,ebv=None,ages=None,HaEW=None,zGrid=None,\
                    csiGrid = None, alphaGrid =None, o3o2Grid=None,\
                    colorList=None,debug=False):
        def _write_grid(fname):
            fout = h5py.File(fname, "w")
            gridDataset = fout.create_dataset("grid", data=model_grid)

            gridDataset.attrs["shape"] = model_grid.shape
            gridDataset.attrs["colors"] = color_idxs
            for i, name in enumerate(allGridNames):
                fout.create_dataset(name, data=allGrids[i])
                gridDataset.attrs[f"AXIS{i}"] = name

            fout.close()
            return None

        color_idxs = self._define_colors(colorList)

        if debug is True:
            print("CLRS", color_idxs)
        if zGrid is None:
            zGrid = np.linspace(1, 3, 50)

        if ebv is None:
            ebv = [0, 0.1, 0.2, 0.3]

        if ages is None:
            ages = np.logspace(-3, np.log10(2), 50)

        if HaEW is None:
            HaEW = np.linspace(0, 200, 100)

        if csiGrid is None:
            csiGrid = np.asarray([1.0])

        if alphaGrid is None:
            alphaGrid = np.asarray([0.0])

        if o3o2Grid is None:
            o3o2Grid = np.asarray([0.35])

        FilterList = observate.load_filters(self.filter_names)

        ncolors = len(color_idxs)
        nAges = len(ages)
        nHa = len(HaEW)
        ndust = len(ebv)
        nzGrid = len(zGrid)
        ncsiGrid = len(csiGrid)
        no3o2Grid = len(o3o2Grid)
        nalphaGrid = len(alphaGrid)

        allGrids = [
            color_idxs, HaEW, ebv, ages, csiGrid, o3o2Grid, alphaGrid, zGrid
        ]
        allGridNames = [
            "colors", "Ha", "dust", "ages", "csi", "o3o2", "alpha", "redshift"
        ]
        nElements = [len(grid) for grid in allGrids]
        model_grid = np.zeros(nElements)

        if debug is True:
            print("Start creating grid: ", model_grid.shape)
        tstart = time.time()
        for i, value in enumerate(ebv):
            if debug is True:
                print(i)
            self.model.params['dust2'] = value * 4.05  # E(B-V) * RV
            for j, age in enumerate(ages):
                wave, spec = self.model.get_spectrum(tage=age, peraa=True)
                emLineSpec = EmissionSpectrum(wave)
                for k, Ha in enumerate(HaEW):
                    for ii, csi in enumerate(csiGrid):
                        for jj, o3o2 in enumerate(o3o2Grid):
                            for kk, alpha in enumerate(alphaGrid):
                                for nn, z in enumerate(zGrid):
                                    emLineSpec.halpha_model(spec,
                                                            Ha,
                                                            logzsol=0,
                                                            csi=csi,
                                                            alpha=alpha,
                                                            o3o2=o3o2,
                                                            redshift=z)
                                    mags = observate.getSED(
                                        wave * (1 + z),
                                        spec + emLineSpec.flux,
                                        filterlist=FilterList)
                                    colors = [
                                        mags[c[0]] - mags[c[1]]
                                        for c in color_idxs
                                    ]
                                    model_grid[:, k, i, j, ii, jj, kk,
                                               nn] = colors
        tend = time.time()
        if debug is True:
            print(f"Elapsed {tend-tstart} secs on grid creation")
        _write_grid(fname)

        # self.model.params['dust2'] = 0.00 * 4.05 # E(B-V) * RV
        # mags= self.model.get_mags(tage=ages[0],redshift=zGrid[0], bands=self.filter_names)
        # print(mags[:-1]-mags[1:])
        #
        # wave, spec = self.model.get_spectrum(tage=ages[0],peraa=True)
        # emLineSpec = EmissionSpectrum(wave)
        # emLineSpec.halpha_model(spec, HaEW[1], logzsol=0)
        # mags = observate.getSED(wave*(1+zGrid[0]), spec, filterlist=FilterList)
        # print(mags[:-1]-mags[1:])
        #
        #
        # selLims = (2900,9600)
        # fig = mpl.figure(figsize=(12,8))
        # ax = fig.add_axes([0.05,0.05,0.9,0.6])
        # axLines = fig.add_axes([0.05,0.65,0.9,0.3],sharex=ax)
        # emLineSpec.plot_spectrum(ax=axLines,color="LimeGreen")
        # selection = (wave>selLims[0]) & (wave<selLims[1])
        # ax.plot(wave[selection],spec[selection]+emLineSpec.flux[selection],color="LimeGreen")
        # ax.plot(wave[selection],spec[selection],color="k")
        # ax.set_xlim(selLims[0],selLims[1])
        # axLines.tick_params(labelbottom=False)
        # mpl.show()

        #
        # self.model.params['dust2'] = 0.20 * 4.05 # E(B-V) * RV
        # print(self.model.get_mags(tage=0.1,redshift=2.0, bands=self.filter_names))
        return
Exemple #46
0
for i in range(len(galaxies)):
    for j in range(len(dustFraction)):
        if dust or partialDust:
            wave = np.load(SKIRT_path1 + galaxies[i] + SKIRT_path2 +
                           dustFraction[j] + SKIRT_path3 +
                           'wave.npy') * 1e4  # convert to Angstroms
            spec = np.load(SKIRT_path1 + galaxies[i] + SKIRT_path2 +
                           dustFraction[j] + SKIRT_path3 + 'spec.npy')  # in Jy
        else:
            wave = np.load(SKIRT_path1 + galaxies[i] + SKIRT_path2 +
                           'wave.npy') * 1e4  # convert to Angstroms
            spec = np.load(SKIRT_path1 + galaxies[i] + SKIRT_path2 +
                           'spec.npy')  # in Jy
        filterlist = observate.load_filters(bands)
        f_lambda_cgs = (1 / 33333) * (1 / (wave**2)) * spec
        mags = observate.getSED(wave, f_lambda_cgs,
                                filterlist=filterlist)  # in AB Magnitudes
        jy = 1e26 * 10**(
            -1 * (mags + 48.6) / 2.5
        )  # convert from AB mags to Janskys (same order as bands)
        for k in range(len(bands)):
            SKIRT_flux[i, j, k] = jy[k]
        # load gas text files
        textFilePath = '/scratch/ntf229/RT_fit/resources/NIHAO/TextFiles/' + galaxies[
            i] + '/'
        gas = np.loadtxt(textFilePath + 'gas.txt')
        stars = np.loadtxt(textFilePath + 'stars.txt')
        #youngStars = np.loadtxt(textFilePath+'youngStars.txt')
        starMasses = stars[:, 7]  # units of M_sun
        #youngStarMasses = youngStars[:,7] * 1e7
        totStarMass[i] = np.sum(starMasses)
        #gasDensity = np.loadtxt(textFilePath+'gas_density.txt')
Exemple #47
0
    #convert into a high resolution sfh, with *no* intrabin sfr variations
    lt, sfr, fb = bsp.burst_sfh(fwhm_burst=0.05, f_burst=0., contrast=1.,
                                sfh=sfh, bin_res=20.)
    
    # Get the attenuated spectra
    #  and IR luminosities
    wave, spec, mass, lir = bsp.bursty_sps(lt, sfr, sps, lookback_time=t_lookback,
                                           av=av, dav=dav, nsplit=30)
    for j, jt in enumerate(t_lookback):
        pl.plot(wave, spec[j,:] * wave * bsp.to_cgs,
                label = '{0} @ {1}'.format(objname[i], tl[j]))
        
    # Project onto filters to get
    #   absolute magnitudes
    mags = observate.getSED(wave, spec * bsp.to_cgs, filterlist = filterlist)
    
    # Get the intrinsic spectrum and project onto filters
    wave, spec, mass, _ = bsp.bursty_sps(lt, sfr, sps, lookback_times=t_lookback,
                                         av=None, dav=None)
    mags_int = observate.getSED(wave, spec * bsp.to_cgs, filterlist = filterlist)


pl.xlim(1e3, 1e4)
pl.ylim(1e-3,1e1)
pl.yscale('log')
pl.xlabel(r'wavelength ($\AA$)')
pl.ylabel(r'$\lambda$L$_\lambda$ (erg/s/cm$^2$ @ 10pc)')
pl.legend(loc = 'lower right')
pl.savefig('demo_bsp.png')
pl.show()