def compare_mtot_pca_nsa(tab, jhu_mpa, mltype='ring', mlb='i', cb1='g', cb2='r'): jointab = t.join(tab, jhu_mpa, 'plateifu') mlb_ix = totalmass.StellarMass.bands_ixs[mlb] cb1_ix = totalmass.StellarMass.bands_ixs[cb1] cb2_ix = totalmass.StellarMass.bands_ixs[cb2] absmag_sun_mlb = totalmass.StellarMass.absmag_sun[mlb_ix] broadband_color = (jointab['nsa_absmag'][:, cb1_ix] - jointab['nsa_absmag'][:, cb2_ix]) mass_pca = jointab['mass_in_ifu'] + jointab['outer_mass_{}'.format(mltype)] nsa_h = 1. mass_nsa = (jointab['nsa_elpetro_mass'] * u.Msun * (nsa_h * u.littleh)**-2).to( u.Msun, u.with_H0(cosmo.H0)) jhumpa_h = 1. / .7 chabrier_to_kroupa_dex = .05 mass_jhumpa = (10.**(jointab['LOG_MSTAR'] + chabrier_to_kroupa_dex) * \ u.Msun * (jhumpa_h * u.littleh)**-2.).to(u.Msun, u.with_H0(cosmo.H0)) lowess_grid = np.linspace(broadband_color.min(), broadband_color.max(), 100).value lowess_pca_nsa, swt_nsa = smooth( x=broadband_color.value, y=np.log10(mass_pca / mass_nsa).value, xgrid=lowess_grid, bw=.01) print(lowess_pca_nsa) print(swt_nsa) lowess_pca_jhumpa, swt_jhumpa = smooth( x=broadband_color.value, y=np.log10(mass_pca / mass_jhumpa).value, xgrid=lowess_grid, bw=.01) print(lowess_pca_jhumpa) print(swt_jhumpa) swt_th = .2 * swt_nsa.max() good_lowess_nsa = (swt_nsa >= swt_th) good_lowess_jhumpa = (swt_jhumpa >= swt_th) fig, ax = plt.subplots(1, 1, figsize=(3, 3), dpi=300) ax.scatter(broadband_color, np.log10(mass_pca / mass_nsa), s=2., edgecolor='None', c='C0', label='NSA') ax.plot(lowess_grid[good_lowess_nsa], lowess_pca_nsa[good_lowess_nsa], linewidth=0.5, c='k', linestyle='-') ax.scatter(broadband_color, np.log10(mass_pca / mass_jhumpa), s=2., edgecolor='None', c='C1', label='JHU-MPA') ax.plot(lowess_grid[good_lowess_jhumpa], lowess_pca_jhumpa[good_lowess_jhumpa], linewidth=0.5, c='k', linestyle='--') ax.set_ylim([-.2, .5]); ax.set_xlim([-.1, 1.]) ax.legend(loc='best', prop={'size': 'xx-small'}) ax.tick_params(labelsize='xx-small') ax.set_xlabel(r'${}-{}$'.format(cb1, cb2), size='x-small') ax.set_ylabel(r'$\log \frac{M^*_{\rm PCA}}{M^*_{\rm catalog}}$', size='x-small') fig.tight_layout() fig.subplots_adjust(top=.95, left=.21, right=.97) fig.savefig(os.path.join(basedir, 'lib_diags/', 'dMasses.png'), dpi=fig.dpi)
def compare_mtot_pca_nsa(tab, jhu_mpa, mltype='ring', mlb='i', cb1='g', cb2='r'): jointab = t.join(tab, jhu_mpa, 'plateifu') cb1_nsa_mag = jointab[f'mag_nsa_{cb1}'] cb2_nsa_mag = jointab[f'mag_nsa_{cb2}'] broadband_color = cb1_nsa_mag - cb2_nsa_mag outer_mass = (jointab[f'outerml_{mltype}'] + \ jointab[f'logsollum_outer_{mlb}']).to(u.dex(u.Msun)) mass_pca = jointab['mass_in_ifu'].to(u.Msun) + outer_mass.to(u.Msun) nsa_h = 1. mass_nsa = (jointab['nsa_elpetro_mass'] * u.Msun * (nsa_h * u.littleh)**-2).to( u.Msun, u.with_H0(cosmo.H0)) jhumpa_h = 1. / .7 chabrier_to_kroupa_dex = .05 mass_jhumpa = (10.**(jointab['LOG_MSTAR'] + chabrier_to_kroupa_dex) * \ u.Msun * (jhumpa_h * u.littleh)**-2.).to(u.Msun, u.with_H0(cosmo.H0)) lowess_grid = np.linspace(np.nanmin(broadband_color), np.nanmax(broadband_color), 100).value lowess_pca_nsa, swt_nsa = smooth( x=broadband_color.value, y=np.log10(mass_pca / mass_nsa).value, xgrid=lowess_grid, bw=.01) lowess_pca_jhumpa, swt_jhumpa = smooth( x=broadband_color.value, y=np.log10(mass_pca / mass_jhumpa).value, xgrid=lowess_grid, bw=.01) swt_th = .2 * swt_nsa.max() good_lowess_nsa = (swt_nsa >= swt_th) good_lowess_jhumpa = (swt_jhumpa >= swt_th) fig, ax = plt.subplots(1, 1, figsize=(3, 3), dpi=300) ax.scatter(broadband_color, np.log10(mass_pca / mass_nsa), s=2., edgecolor='None', c='C0', label='NSA') ax.plot(lowess_grid[good_lowess_nsa], lowess_pca_nsa[good_lowess_nsa], linewidth=0.5, c='k', linestyle='-') ax.scatter(broadband_color, np.log10(mass_pca / mass_jhumpa), s=2., edgecolor='None', c='C1', label='JHU-MPA') ax.plot(lowess_grid[good_lowess_jhumpa], lowess_pca_jhumpa[good_lowess_jhumpa], linewidth=0.5, c='k', linestyle='--') ax.set_ylim([-.2, .5]); ax.set_xlim([-.1, 1.]) ax.legend(loc='best', prop={'size': 'xx-small'}) ax.tick_params(labelsize='xx-small') ax.set_xlabel(r'${}-{}$'.format(cb1, cb2), size='x-small') ax.set_ylabel(r'$\log \frac{M^*_{\rm PCA}}{M^*_{\rm catalog}}$', size='x-small') fig.tight_layout() fig.subplots_adjust(top=.95, left=.21, right=.97) fig.savefig(os.path.join(csp_basedir, 'lib_diags/', 'dMasses.png'), dpi=fig.dpi)
def angular_corr_func(thetas, zs, dn_dz_1, dn_dz_2): # thetas from degrees to radians thetas = (thetas * u.deg).to('radian').value # get dimensionless power spectrum deltasquare = power_spec_at_zs(zs, read=False, dimensionless=True) # power spectrum over k^2 first_term = deltasquare / (k_grid**2) # everything inside Bessel function # has 3 dimensions, k, theta, and z # therefore need to do outer product of two arrays, then broadcast 3rd array to 3D and multiply besselterm = j0( cosmo.comovingDistance(np.zeros(len(zs)), zs)[:, None, None] * np.outer(k_grid, thetas)) # Not sure if this is right # I think you need to convert H(z)/c from 1/Mpc to h/Mpc in order to cancel units of k, but not sure dz_d_chi = (apcosmo.H(zs) / const.c).to(u.littleh / u.Mpc, u.with_H0(apcosmo.H0)).value # product of redshift distributions, and dz/dchi differentials = dz_d_chi * dn_dz_1 * dn_dz_2 # total integrand is all terms multiplied out. This is a 3D array integrand = np.pi * differentials * np.transpose( first_term) * np.transpose(besselterm) # do k integral first along k axis k_int = np.trapz(integrand, k_grid, axis=1) # then integrate along z axis total = np.trapz(k_int, zs, axis=1) return total
def r200(self, cosmo, delta): # h^-1 Mpc rho = cosmo.critical_density(self.z) radius = (((3 / 4) * (self.cluster_mass) / (delta * np.pi * rho))**(1 / 3)).to(u.Mpc, u.with_H0(cosmo.H0)) return (radius * ((cosmo.H0 / 100).value) / u.littleh).to( u.Mpc / u.littleh) # littleh scaling
def luminosity(self, name, lum_distz, deredden=False, **kwargs): """ Calculate Emission Line Luminosity Parameters ---------- name: 'str' name of Maps key to Map that will be dereddened lum_distz: 'number', 'u.Quantity' luminosity distance in units of Mpc / littleh deredden: 'bool', optional, must be keyword if True, dereddens flux first kwargs: 'dict', optional, must be keyword keywords passed to deredden """ if not isinstance(lum_distz, u.Quantity): logging.warning( "No units provided for Luminosity Distance, assuming u.Mpc / u.littleh" ) lum_distz *= u.Mpc / u.littleh if deredden: flux = self.deredden(name, **kwargs) else: flux = self[name].masked flux_unit = self[name].unit lum = 4. * np.pi * flux.data * flux_unit * lum_distz**2 lum_out = lum.to(u.erg / u.s / u.pix, u.with_H0(WMAP9.H0)) return np.ma.masked_array(data=lum_out, mask=flux.mask)
def test_littleh(): H0_70 = 70*u.km/u.s/u.Mpc h70dist = 70 * u.Mpc/u.littleh assert_quantity_allclose(h70dist.to(u.Mpc, u.with_H0(H0_70)), 100*u.Mpc) # make sure using the default cosmology works cosmodist = cosmology.default_cosmology.get().H0.value * u.Mpc/u.littleh assert_quantity_allclose(cosmodist.to(u.Mpc, u.with_H0()), 100*u.Mpc) # Now try a luminosity scaling h1lum = .49 * u.Lsun * u.littleh**-2 assert_quantity_allclose(h1lum.to(u.Lsun, u.with_H0(H0_70)), 1*u.Lsun) # And the trickiest one: magnitudes. Using H0=10 here for the round numbers H0_10 = 10*u.km/u.s/u.Mpc # assume the "true" magnitude M = 12. # Then M - 5*log_10(h) = M + 5 = 17 withlittlehmag = 17 * (u.mag - u.MagUnit(u.littleh**2)) assert_quantity_allclose(withlittlehmag.to(u.mag, u.with_H0(H0_10)), 12*u.mag)
def get_jbh_stellar_mass_mwa_mask(self, sersic=False): """nsa_elpetro_mass Return mask of galaxies in self.targets_gz that fit within stellar mass range of JBH (2016) MW Stellar Mass estimates """ if sersic: key = "NSA_SERSIC_MASS" else: key = 'NSA_ELPETRO_MASS' NSA_STELLAR_MASS = (10**self.targets_gz[key] * u.solMass * u.littleh**-2).to(u.solMass, u.with_H0(WMAP9.H0)) return (NSA_STELLAR_MASS < (self.mw_stellar_mass_jbh + self.mw_stellar_mass_jbh_err)) & \ (NSA_STELLAR_MASS > (self.mw_stellar_mass_jbh - self.mw_stellar_mass_jbh_err))
def linear_to_angular_dist(distance, photo_z): """ Converts proper distance (Mpc) to angular distance (deg). Used to find angular separations within clusters. Parameters ---------- distance: float, array-like Distance in h^-1 * Mpc photo_z: float, array-like Associated redshift Returns ------- d: float, array-like Angular distance in deg """ return (distance.to(u.Mpc, u.with_H0(cosmo.H0)) * cosmo.arcsec_per_kpc_proper(photo_z)).to(u.deg)
def nsa_absmags_cosmocorr(self): return self.nsa_absmags.to(u.ABmag, u.with_H0(self.cosmo.H0))
def camb(wavenumber, redshift, cosmology, A_s, n_s): """ Return the CAMB computation of the linear matter power spectrum, on a two dimensional grid of wavenumber and redshift Parameters ---------- wavenumber : (nk,) array_like Array of wavenumbers in units of [Mpc^-1] at which to evaluate the linear matter power spectrum. redshift : (nz,) array_like Array of redshifts at which to evaluate the linear matter power spectrum. cosmology : astropy.cosmology.Cosmology Cosmology object providing omega_matter, omega_baryon, Hubble parameter and CMB temperature in the present day A_s : float Cosmology parameter, amplitude normalisation of curvature perturbation power spectrum n_s : float Cosmology parameter, spectral index of scalar perturbation power spectrum Returns ------- power_spectrum : (nk, nz) array_like Array of values for the linear matter power spectrum in [Mpc^3] evaluated at the input wavenumbers for the given primordial power spectrum parameters, cosmology. For nz redshifts and nk wavenumbers the returned array will have shape (nk, nz). Examples -------- >>> import numpy as np >>> from astropy.cosmology import default_cosmology >>> cosmology = default_cosmology.get() >>> redshift = np.array([0, 1]) >>> wavenumber = np.array([1.e-2, 1.e-1, 1e0]) >>> A_s = 2.e-9 >>> n_s = 0.965 >>> camb(wavenumber, redshift, cosmology, A_s, n_s) # doctest: +SKIP array([[2.34758952e+04, 8.70837957e+03], [3.03660813e+03, 1.12836115e+03], [2.53124880e+01, 9.40802814e+00]]) References ---------- doi : 10.1086/309179 arXiv: astro-ph/9911177 """ try: from camb import CAMBparams, get_results, model except ImportError: raise Exception("camb is required to use skypy.linear.camb") redshift = np.atleast_1d(redshift) h2 = cosmology.h * cosmology.h pars = CAMBparams() pars.set_cosmology(H0=cosmology.H0.value, ombh2=cosmology.Ob0 * h2, omch2=cosmology.Odm0 * h2, omk=cosmology.Ok0, TCMB=cosmology.Tcmb0.value, mnu=np.sum(cosmology.m_nu.value), standard_neutrino_neff=cosmology.Neff ) # camb requires redshifts to be in decreasing order redshift_order = np.argsort(redshift)[::-1] pars.InitPower.ns = n_s pars.InitPower.As = A_s pars.set_matter_power(redshifts=list(redshift[redshift_order]), kmax=np.max(wavenumber)) pars.NonLinear = model.NonLinear_none results = get_results(pars) k = wavenumber * (1. / u.Mpc) k_h = k.to((u.littleh / u.Mpc), u.with_H0(cosmology.H0)) kh, z, pzk = results.get_matter_power_spectrum(minkh=np.min(k_h.value), maxkh=np.max(k_h.value), npoints=len(k_h.value)) return pzk[redshift_order[::-1]].T
from astropy.visualization import astropy_mpl_style plt.style.use(astropy_mpl_style) import scipy.constants as sc from astropy.constants import codata2018 as ac from astropy.constants import iau2015 as aa import astropy.units as u from astropy.cosmology import Planck15 as cosmo import astropy.uncertainty as aun a = np.linspace(.01, 3, num=1000) # a=1 now Om0 = cosmo.Om0 Olambda0 = 1 - cosmo.Om0 - cosmo.Ob0 Orad0 = (2.5e-5 * u.littleh**-2).to(u.dimensionless_unscaled, equivalencies=u.with_H0()) def get_rho(a, w, O0): return (O0 * a**(-3 * (1 + w))) plt.plot(a, get_rho(a, -1, Olambda0), label='Cosmological constant') plt.plot(a, get_rho(a, 1 / 3, Orad0), label='Radiation') plt.plot(a, get_rho(a, 0, Om0), label='Matter') plt.xlabel('Scale factor: $a / a_0$') plt.ylabel('Energy density: $\\rho / \\rho_{0c}$') plt.axvline(x=1, label='Now', c='black') plt.ylim(0, 2) plt.legend() plt.savefig('global_energy_contributions.pdf', format='pdf')
def camb(wavenumber, redshift, cosmology, A_s, n_s): r'''CAMB linear matter power spectrum. Compute the linear matter power spectrum on a two dimensional grid of redshift and wavenumber using CAMB [1]_. Parameters ---------- wavenumber : (nk,) array_like Array of wavenumbers in units of Mpc-1 at which to evaluate the linear matter power spectrum. redshift : (nz,) array_like Array of redshifts at which to evaluate the linear matter power spectrum. cosmology : astropy.cosmology.Cosmology Cosmology object providing omega_matter, omega_baryon, Hubble parameter and CMB temperature in the present day A_s : float Cosmology parameter, amplitude normalisation of curvature perturbation power spectrum n_s : float Cosmology parameter, spectral index of scalar perturbation power spectrum Returns ------- power_spectrum : (nz, nk) array_like Array of values for the linear matter power spectrum in Mpc3 evaluated at the input wavenumbers for the given primordial power spectrum parameters, cosmology. For nz redshifts and nk wavenumbers the returned array will have shape (nz, nk). Examples -------- >>> import numpy as np >>> from astropy.cosmology import default_cosmology >>> cosmology = default_cosmology.get() >>> redshift = np.array([0, 1]) >>> wavenumber = np.array([1.e-2, 1.e-1, 1e0]) >>> A_s = 2.e-9 >>> n_s = 0.965 >>> power_spectrum = camb(wavenumber, redshift, cosmology, A_s, n_s) # doctest: +SKIP References ---------- .. [1] Lewis, A. and Challinor, A. and Lasenby, A. (2000), doi : 10.1086/309179. ''' try: from camb import CAMBparams, get_results, model except ImportError: raise Exception("camb is required to use skypy.power_spectrum.camb") return_shape = (*np.shape(redshift), *np.shape(wavenumber)) redshift = np.atleast_1d(redshift) h2 = cosmology.h * cosmology.h pars = CAMBparams() pars.set_cosmology(H0=cosmology.H0.value, ombh2=cosmology.Ob0 * h2, omch2=cosmology.Odm0 * h2, omk=cosmology.Ok0, TCMB=cosmology.Tcmb0.value, mnu=np.sum(cosmology.m_nu.value), standard_neutrino_neff=cosmology.Neff) # camb requires redshifts to be in decreasing order redshift_order = np.argsort(redshift)[::-1] pars.InitPower.ns = n_s pars.InitPower.As = A_s pars.set_matter_power(redshifts=list(redshift[redshift_order]), kmax=np.max(wavenumber)) pars.NonLinear = model.NonLinear_none results = get_results(pars) k = wavenumber * (1. / u.Mpc) k_h = k.to((u.littleh / u.Mpc), u.with_H0(cosmology.H0)) kh, z, pzk = results.get_matter_power_spectrum(minkh=np.min(k_h.value), maxkh=np.max(k_h.value), npoints=len(k_h.value)) return pzk[redshift_order[::-1]].reshape(return_shape)
def make_photo_spectro_compare(plateifu, pca_system): drpall_row = drpall.loc[plateifu] plate, ifu = plateifu.split('-') Cgr_i_cmlr = lambda color: -0.496 + 1.147 * color try: drp_logcube = m.load_drp_logcube(plate, ifu, mpl_v) dap_maps = m.load_dap_maps(plate, ifu, mpl_v, daptype) preimaging = MaNGA_PreImage.from_designid_mangaid( drpall_row['designid'], drpall_row['mangaid']) res = read_results.PCAOutput.from_plateifu( os.path.join(basedir, 'results/'), plate, ifu) except IOError: return False else: fig, ax1, ax2, ax3 = make_stellarmass_aperture_plot( preimaging=preimaging, dap_maps=dap_maps, drp_logcube=drp_logcube, cmlr=Cgr_i_cmlr, drpall_row=drpall_row) overplot_spectroscopic(res, drp_logcube, drpall.loc[plateifu], ax1, ax2, ax3, pca_system, res_wcs=wcs.WCS(dap_maps['SPX_MFLUX'].header), cmlr=Cgr_i_cmlr) ax1.axhline( (drpall_row['nsa_elpetro_mass'] * u.Msun * u.littleh**-2).to( u.Msun, u.with_H0(cosmo.H0)).value, c='k', linestyle='-', alpha=0.5) overplot_cmlr_ml_Re(preimaging, drpall_row, drp_logcube, dap_maps, ax1, ax2, Cgr_i_cmlr, target_snr=20., Re_bds=[ 0., .1, .2, .3, .4, .5, .675, .75, .875, 1., 1.25, 1.5, 2., 3.5, 6. ]) ax3.legend(loc='best', prop={'size': 'small'}) fig.tight_layout(rect=(0., 0., 1., 0.95)) drp_logcube.close() dap_maps.close() preimaging.close() res.close() if ax1.get_xlim()[-1] >= 8.: ax1.set_xlim([-.5, 8.]) fig.savefig(os.path.join(basedir, 'results/', plateifu, '{}_photspec_compare.png'.format(plateifu)), dpi=300) finally: plt.close('all')
def overplot_spectroscopic(res, drp_logcube, drpall_row, mass_ax, ml_ax, f_ax, pca_system, res_wcs, cmlr, mlb='i'): ''' overplot cumulative spectroscopic masses, log M/L, cumulative fluxes ''' # synthetic photometry of IFU data in rest frame ebvgal = drpall_row['ebvgal'] r_v = 3.1 dustcorr = 10.**(0.4 * extinction.fitzpatrick99( drp_logcube['WAVE'].data, a_v=r_v * ebvgal, r_v=r_v))[:, None, None] ifu_s2p = spectrophot.Spec2Phot( lam=drp_logcube['WAVE'].data / (1. + drpall_row['nsa_z']), flam=1.0e-17 * drp_logcube['FLUX'].data * (1. + drpall_row['nsa_z']) * dustcorr) res_flux = (ifu_s2p.ABmags['sdss2010-{}'.format(mlb)] * u.ABmag).to(m.Mgy) # map sky coordinates to number of effective radii from center pos_to_nRe = RotatedParaboloid(ctr=np.array( [drpall_row['objra'], drpall_row['objdec']]), phi=drpall_row['nsa_elpetro_phi'] * u.deg, axis_ratio=drpall_row['nsa_elpetro_ba'], Re=drpall_row['nsa_elpetro_th50_r'] / 3600.) badpdf = res.badPDF() ml_mask = np.logical_or(res.mask, badpdf) # WCS from results file determines where elliptical projection is sampled #res_wcs = wcs.WCS(res['SNRMED'].header) res_II, res_JJ = np.meshgrid( *[np.linspace(0., s - 1., s) for s in res['SNRMED'].shape], indexing='ij') res_AA, res_DD = res_wcs.wcs_pix2world(res_JJ, res_II, 1) # sample Re at spaxel centers res_Re = pos_to_nRe(np.column_stack([res_AA.flatten(), res_DD.flatten() ])).reshape(res_AA.shape) nRe_to_plot = np.linspace(0., res_Re[~ml_mask].max(), 50.) # mass, log M/L badpdf = res.badPDF() ml_mask = np.logical_or.reduce((res.mask, badpdf)) interior_mask = np.logical_or.reduce( (badpdf, (m.mask_from_maskbits(drp_logcube['MASK'].data, [3]).sum(axis=0) > 0), (m.mask_from_maskbits(drp_logcube['MASK'].data, [2]).sum(axis=0) > 0))) logml = infer_masked(res.param_dist_med(extname='ML{}'.format(mlb)), ml_mask, interior_mask) ml = 10.**logml * m.m_to_l_unit res_MAG = res_flux.to(u.ABmag) - cosmo.distmod(drpall_row['nsa_zdist']) mlb_sollum = 10.**(-0.4 * (res_MAG - spectrophot.absmag_sun_band[mlb] * u.ABmag)).value * \ m.bandpass_sol_l_unit spectro_mass = (ml * mlb_sollum).to(u.Msun) # sum mass within some number of Re mass_within_nRe = np.array( [sum_within_nRe(spectro_mass, res_Re, n) for n in nRe_to_plot]) mass_ax.plot(nRe_to_plot, mass_within_nRe, c='C1') # plot mass to light versus Re ml_sc = ml_ax.scatter(res_Re[~ml_mask], logml[~ml_mask], c='C1', edgecolor='None', s=.5) res_Re_m = np.ma.array(res_Re, mask=ml_mask) # find ring method log M/L outer_ring = np.logical_and((res_Re_m <= res_Re_m.max()), (res_Re_m >= res_Re_m.max() - .5)) outer_logml_ring = np.median(logml[~ml_mask * outer_ring]) ml_ax.scatter(x=[np.median(res_Re_m[~ml_mask * outer_ring])], y=[outer_logml_ring], marker='x', c='C1') # find CMLR log M/L nsa_MAG = (np.array(drpall_row['nsa_elpetro_absmag'][2:]) * \ (u.ABmag - u.MagUnit(u.littleh**2))).to(u.ABmag, u.with_H0(cosmo.H0)) nsa_mag = (nsa_MAG + cosmo.distmod(drpall_row['nsa_zdist'])) nsa_flux = nsa_mag.to(m.Mgy) ifu_mag = np.array( [ifu_s2p.ABmags['sdss2010-{}'.format(b_)] for b_ in 'ugriz']) * u.ABmag ifu_mag[~np.isfinite(ifu_mag)] = 40. * u.ABmag ifu_flux = ifu_mag.to(m.Mgy) flux_deficit = nsa_flux - ifu_flux.sum(axis=(1, 2)) logml_missingflux_cmlr = cmlr(2.5 * np.log10(flux_deficit[1] / flux_deficit[2])) ml_ax.scatter(x=[np.median(res_Re_m[~ml_mask * outer_ring])], y=[logml_missingflux_cmlr], marker='s', c='C1', edgecolor='k') # ml_missingflux_cmlr = 10.**logml_missingflux_cmlr * m.m_to_l_unit ml_missingflux_ring = 10.**outer_logml_ring * m.m_to_l_unit missing_mlb_MAG = flux_deficit[3].to(u.ABmag) - cosmo.distmod( drpall_row['nsa_zdist']) missing_mlb_sollum = 10.**(-0.4 * (missing_mlb_MAG - spectrophot.absmag_sun_band[mlb] * u.ABmag)).value * \ m.bandpass_sol_l_unit missing_mass_cmlr = (ml_missingflux_cmlr * missing_mlb_sollum).to(u.Msun) missing_mass_ring = (ml_missingflux_ring * missing_mlb_sollum).to(u.Msun) mass_ax.scatter(x=res_Re.max() - .1, y=mass_within_nRe[-1] * u.Msun + missing_mass_cmlr, marker='s', c='C1', edgecolor='k', zorder=3, label='+AC(CMLR)') mass_ax.scatter(x=res_Re.max(), y=mass_within_nRe[-1] * u.Msun + missing_mass_ring, marker='x', c='C1', edgecolor='k', zorder=3, label='+AC(RING)') mass_ax.legend(loc='best', prop={'size': 'x-small'}) summed_flux = np.array([ sum_within_nRe(arr=res_flux, Re_a=res_Re, nRe=n) for n in nRe_to_plot ]) f_ax.plot(nRe_to_plot, summed_flux, label='IFU', c='C1') f_ax.scatter(x=res_Re.max() + .1, y=summed_flux[-1] * m.Mgy + flux_deficit[3], marker='o', c='C1', edgecolor='k', zorder=3)
def make_stellarmass_aperture_plot(preimaging, dap_maps, drp_logcube, cmlr, drpall_row, mlb='i', cb1='g', cb2='r'): ''' make aperture plot of included mass (from CMLR and preimaging) versus radius (from DAP) preimaging: MaNGA_PreImage object dap_maps: FITS HDUList with DAP MAPS outputs ''' ebvgal = drpall_row['ebvgal'] # WCS from DAP determines sampling for Re grid, and where k-correction map is sampled dap_wcs = wcs.WCS(dap_maps['SPX_SNR'].header) dap_AA, dap_DD = dap_wcs.wcs_pix2world( *np.meshgrid(*[ np.linspace(0., s - 1., s) for s in dap_maps['SPX_SNR'].data.shape ]), 1) # map sky coordinates to number of effective radii from center pos_to_nRe = RotatedParaboloid(ctr=np.array( [drpall_row['objra'], drpall_row['objdec']]), phi=drpall_row['nsa_elpetro_phi'] * u.deg, axis_ratio=drpall_row['nsa_elpetro_ba'], Re=drpall_row['nsa_elpetro_th50_r'] / 3600.) # WCS from preimaging determines where elliptical projection is resampled preimaging_wcs = wcs.WCS(preimaging['{} img'.format(mlb)].header) preimaging_II, preimaging_JJ = np.meshgrid( *[np.linspace(0., s - 1., s) for s in preimaging.img(mlb).shape], indexing='ij') preimaging_AA, preimaging_DD = preimaging_wcs.wcs_pix2world( preimaging_JJ, preimaging_II, 1) # evaluate Re interpolation on imaging RA/Dec grid preimaging_Re = pos_to_nRe( np.column_stack([preimaging_AA.flatten(), preimaging_DD.flatten() ])).reshape(preimaging_AA.shape) kcorr_cb1_interp, kcorr_cb2_interp, kcorr_mlb_interp = kcorr_spec_to_phot( drp_logcube, dap_maps['SPX_MFLUX_IVAR'], drpall_row['nsa_z'], cb1, cb2, mlb) kcorr_cb1_phot = kcorr_cb1_interp(preimaging_AA.flatten(), preimaging_DD.flatten()).reshape( preimaging_AA.shape) * u.mag kcorr_cb2_phot = kcorr_cb2_interp(preimaging_AA.flatten(), preimaging_DD.flatten()).reshape( preimaging_AA.shape) * u.mag kcorr_color = kcorr_cb1_phot - kcorr_cb2_phot kcorr_mlb_phot = kcorr_mlb_interp(preimaging_AA.flatten(), preimaging_DD.flatten()).reshape( preimaging_AA.shape) * u.mag # evaluate CMLR given preimaging ml_from_cmlr = 10.**cmlr( color=preimaging.color(cb1, cb2, dustcorr=True, ebvgal=ebvgal) + kcorr_color.value) * m.m_to_l_unit img_mag = (preimaging.img(mlb) * 1.0e-9 * m.Mgy).to( u.ABmag) + kcorr_mlb_phot distmod = cosmo.distmod(drpall_row['nsa_zdist']) img_MAG = img_mag - distmod mlb_sollum = 10.**(-0.4 * (img_MAG - spectrophot.absmag_sun_band[mlb] * u.ABmag)).value * \ m.bandpass_sol_l_unit mass_from_cmlr = (ml_from_cmlr * mlb_sollum).to(u.Msun) nRe_to_plot = np.linspace(0., 0.9 * preimaging_Re.max(), 1000) photomass_within_nRe = np.array([ sum_within_nRe(mass_from_cmlr, preimaging_Re, n) for n in nRe_to_plot ]) # solve for number of effective radii enclosing all of NSA flux NSA_bands = 'FNugriz' NSA_bands_ixs = dict(zip(NSA_bands, range(len(NSA_bands)))) NSA_MAG = drpall_row['nsa_elpetro_absmag'][NSA_bands_ixs[mlb]] * \ (u.ABmag - u.MagUnit(u.littleh**2)) NSA_kcorr_flux = (NSA_MAG.to(u.ABmag, u.with_H0(cosmo.H0)) + \ cosmo.distmod(drpall_row['nsa_zdist'])).to(m.Mgy) fig, (ax1, ax2, ax3) = plt.subplots(nrows=3, ncols=1, figsize=(9, 7), dpi=150, sharex=True) ax1.plot(nRe_to_plot, photomass_within_nRe, linewidth=1., color='C0') ax1.set_yscale('log') ax1.set_ylabel(r'$\frac{M_{< R}}{M_{\odot}}$', size='small') ax2.scatter(preimaging_Re.flatten(), np.log10(ml_from_cmlr.value.flatten()), edgecolor='None', s=.5, c='C0') ax2.set_ylabel(r'$\log \Upsilon^*_{{{}}}$'.format(mlb), size='small') ax2.set_ylim([-2.5, 2.5]) summed_flux = np.array([ sum_within_nRe(arr=img_mag.to(m.Mgy), Re_a=preimaging_Re, nRe=n) for n in nRe_to_plot ]) img_var = 1. / preimaging.img_ivar(mlb) * (1.0e-9 * m.Mgy)**2 quadsummed_fluxunc = np.sqrt( np.array([ sum_within_nRe(arr=img_var, Re_a=preimaging_Re, nRe=n) for n in nRe_to_plot ])) ax3.plot(nRe_to_plot, summed_flux, label='K-Corr. Phot.', color='C0') ax3.fill_between(nRe_to_plot, summed_flux - quadsummed_fluxunc, summed_flux + quadsummed_fluxunc, alpha=0.5, linewidth=0.25, color='C0') ax3.set_xlabel(r'$\frac{R}{R_e}$', size='small') ax3.set_ylabel(r'$\frac{F_{<R}}{\rm Mgy}$', size='small') ax3.set_yscale('log') fig.suptitle(drpall_row['plateifu']) return fig, ax1, ax2, ax3
def __init__(self, filename_drp=None, filename_dap=None, no_analog=False, drpver=None, dapver=None, latest=True, filename_targets=None, filename_gz=None, sersic=False, **kwargs): # Get or set filenames for DRP all file if filename_drp is None: if drpver is None: self.drpver, _ = config.lookUpVersions() logging.warning("Using DRP Version: {}".format(self.drpver)) else: self.drpver = drpver self.filename_drp = os.path.join( os.environ['SAS_BASE_DIR'], 'mangawork', 'manga', 'spectro', 'redux', self.drpver, 'drpall-{}.fits'.format(self.drpver)) else: self.filename_drp = filename_drp # Get or set filenames for DAP all file if filename_dap is None: if dapver is None: _, self.dapver = config.lookUpVersions() logging.warning("Using DAP Version: {}".format(self.dapver)) else: self.dapver = dapver self.filename_dap = os.path.join( os.environ['SAS_BASE_DIR'], 'mangawork', 'manga', 'spectro', 'analysis', self.drpver, self.dapver, 'dapall-{0}-{1}.fits'.format(self.drpver, self.dapver)) else: self.filename_dap = filename_dap # Get or set filename for Target File List if filename_targets is None: self.filename_targets = os.path.join( os.environ['SAS_BASE_DIR'], 'mangawork', 'manga', 'target', 'v1_2_27', 'MaNGA_targets_extNSA_tiled_ancillary.fits') else: self.filename_targets = filename_targets # Get or set filename for Galaxy Zoo VAC if filename_gz is None: self.filename_gz = os.path.join(os.environ['SAS_BASE_DIR'], 'dr15', 'manga', 'morphology', 'galaxyzoo', 'MaNGA_gz-v1_0_1.fits') else: self.filename_gz = filename_gz # Load Data try: self.drp = Table.read(self.filename_drp) except FileNotFoundError: logging.warning("DRP File not found, trying to download") self.drp = get_drpall_table() try: self.dap = Table.read(self.filename_dap) except FileNotFoundError: logging.warning("DAP File not found, trying to download") self.filename = get_dapall_file(self.drpver, self.dapver) try: self.dap = Table.read(self.filename_dap) except FileNotFoundError: if (self.drpver == "v2_4_e") & (self.dapver == "2.2.1"): self.dap = Table.read( "https://data.sdss.org/sas/dr15/manga/spectro/analysis/v2_4_3/2.2.1/dapall-v2_4_3-2.2.1.fits" ) try: self.targets = Table.read(self.filename_targets) except FileNotFoundError: logging.warning("Target Data File not found") self.targets = Table() try: self.gz = Table.read(self.filename_gz) except FileNotFoundError: logging.warning("Galaxy Zoo Morphology Data File not found") self.gz = Table() if not no_analog: self.sersic = sersic # Set Ind Dictionary of Targets by MangaID self.ind_dict_target = dict( (k.rstrip(), i) for i, k in enumerate(self.targets['MANGAID'])) # Set some Milky Way Stellar Mass Estimates self.mw_stellar_mass = 6.43 * 10**10 * u.solMass self.mw_stellar_mass_err = 0.63 * 10**10 * u.solMass self.mw_stellar_mass_jbh = 5.0 * 10**10 * u.solMass self.mw_stellar_mass_jbh_err = 1.0 * 10**10 * u.solMass self.targets_gz = self.targets_in_gz() if latest: self.barred_targets_mask = self.get_barred_galaxies_mask() self.nonbarred_targets_mask = self.get_nonbarred_galaxies_mask( ) # At least Green Valley Selection # Set Color Keys: color_keys = ["F", "N", "u", "g", "r", "i", "z"] # Cosmology Correction h = 1 * u.mag * u.littleh cor = 5. * np.log10(h.to(u.mag, u.with_H0( WMAP9.H0)).value) * u.mag barred_targets_phot = Table(self.targets_gz[ self.barred_targets_mask]['NSA_ELPETRO_ABSMAG'] * u.mag + cor, names=color_keys) nonbarred_targets_phot = Table( self.targets_gz[self.nonbarred_targets_mask] ['NSA_ELPETRO_ABSMAG'] * u.mag + cor, names=color_keys) # Remove Red Galaxies with NUV - r > 5 self.barred_targets_full = self.targets_gz[ self.barred_targets_mask][(barred_targets_phot["N"] - barred_targets_phot["r"]) <= 5] self.nonbarred_targets_full = self.targets_gz[ self.nonbarred_targets_mask][( nonbarred_targets_phot["N"] - nonbarred_targets_phot["r"]) <= 5] # Stellar Masses self.barred_targets_stellar_mass = (10**(self.barred_targets_full["NSA_ELPETRO_MASS"]) *\ u.solMass* u.littleh**-2).to(u.solMass, u.with_H0(WMAP9.H0)) self.nonbarred_targets_stellar_mass = (10**(self.nonbarred_targets_full["NSA_ELPETRO_MASS"]) *\ u.solMass* u.littleh**-2).to(u.solMass, u.with_H0(WMAP9.H0)) #Get closest nonbarred galaxy by mass for each barred galaxy all_gals_drawn = [] for gal_mass in self.barred_targets_stellar_mass: dif = (np.log10(gal_mass.value) - np.log10(self.nonbarred_targets_stellar_mass.value)) ind = np.argsort(np.abs(dif)) added = False ell = 0 while not added: if ind[ell] not in all_gals_drawn: all_gals_drawn.append(ind[ell]) added = True else: ell += 1 self.nonbarred_targets_selected = self.nonbarred_targets_full[ all_gals_drawn] self.nonbarred_targets_selected_stellar_mass = self.nonbarred_targets_stellar_mass[ all_gals_drawn] barred_IDs = [ mangaid.decode("utf-8").rstrip() for mangaid in self.barred_targets_full["MANGAID"].data ] nonbarred_IDs = [ mangaid.decode("utf-8").rstrip() for mangaid in self.nonbarred_targets_selected["MANGAID"].data ] ind_dict_drp = dict( (k, i) for i, k in enumerate(self.drp['mangaid'])) barred_in_drp = set(ind_dict_drp).intersection(barred_IDs) bar_in_drp_ind = [ind_dict_drp[x] for x in barred_in_drp] nonbarred_in_drp = set(ind_dict_drp).intersection( nonbarred_IDs) nonbar_in_drp_ind = [ind_dict_drp[x] for x in nonbarred_in_drp] barred_plateifus = [ plateifu.decode("utf").rstrip() for plateifu in self.drp[bar_in_drp_ind]["plateifu"].data ] nonbarred_plateifus = [ plateifu.decode("utf").rstrip() for plateifu in self.drp[nonbar_in_drp_ind]["plateifu"].data ] ind_dict_dap = dict( (k, i) for i, k in enumerate(self.dap['PLATEIFU'])) barred_sample_dap_ind = np.array( [ind_dict_dap[plateifu] for plateifu in barred_plateifus]) nonbarred_sample_dap_ind = np.array([ ind_dict_dap[plateifu] for plateifu in nonbarred_plateifus ]) if config.release == "MPL-8": bad_barred_ind = ind_dict_dap["10507-12705"] good_barred_mask = np.array([ ind != bad_barred_ind for ind in barred_sample_dap_ind ]) barred_sample_dap_ind = barred_sample_dap_ind[ good_barred_mask] bad_nonbarred_inds = [ ind_dict_dap[bad] for bad in ["8332-12704", "8616-3704", "10498-12704"] ] good_nonbarred_mask = np.array([ ind not in bad_nonbarred_inds for ind in nonbarred_sample_dap_ind ]) nonbarred_sample_dap_ind = nonbarred_sample_dap_ind[ good_nonbarred_mask] self.barred_sample = self.dap[barred_sample_dap_ind] self.nonbarred_sample = self.dap[nonbarred_sample_dap_ind] argsort = np.argsort(self.barred_sample["NSA_Z"]) self.barred_sample = self.barred_sample[argsort] argsort = np.argsort(self.nonbarred_sample["NSA_Z"]) self.nonbarred_sample = self.nonbarred_sample[argsort] self.barred_stellar_mass = (self.drp[self.barred_sample["DRPALLINDX"]]["nsa_elpetro_mass"] *\ u.solMass* u.littleh**-2).to(u.solMass, u.with_H0(WMAP9.H0)) self.nonbarred_stellar_mass = (self.drp[self.nonbarred_sample["DRPALLINDX"]]["nsa_elpetro_mass"] *\ u.solMass* u.littleh**-2).to(u.solMass, u.with_H0(WMAP9.H0)) self.in_mass_range_barred = self.barred_stellar_mass <= ( self.mw_stellar_mass + self.mw_stellar_mass_err * 2.5) self.in_mass_range_barred &= self.barred_stellar_mass > self.mw_stellar_mass - self.mw_stellar_mass_err * 2.5 self.in_mass_range_nonbarred = self.nonbarred_stellar_mass <= self.mw_stellar_mass + self.mw_stellar_mass_err * 2.5 self.in_mass_range_nonbarred &= self.nonbarred_stellar_mass > self.mw_stellar_mass - self.mw_stellar_mass_err * 2.5 self.dk_sample = self.barred_sample[self.in_mass_range_barred] self.dk_sample_nobar = self.nonbarred_sample[ self.in_mass_range_nonbarred] self.barred_sfr = (self.barred_sample["SFR_TOT"] * u.solMass / u.yr * u.littleh**-2).to( u.solMass / u.yr, u.with_H0(WMAP9.H0)) self.nonbarred_sfr = (self.nonbarred_sample["SFR_TOT"] * u.solMass / u.yr * u.littleh**-2).to( u.solMass / u.yr, u.with_H0(WMAP9.H0)) self.dk_sample_sfr = self.barred_sfr[self.in_mass_range_barred] self.dk_sample_nobar_sfr = self.nonbarred_sfr[ self.in_mass_range_nonbarred] self.barred_sfr_1re = (self.barred_sample["SFR_1RE"] * u.solMass / u.yr * u.littleh**-2).to( u.solMass / u.yr, u.with_H0(WMAP9.H0)) self.nonbarred_sfr_1re = (self.nonbarred_sample["SFR_1RE"] * u.solMass / u.yr * u.littleh**-2).to( u.solMass / u.yr, u.with_H0(WMAP9.H0)) self.dk_sample_sfr_1re = self.barred_sfr_1re[ self.in_mass_range_barred] self.dk_sample_nobar_sfr_1re = self.nonbarred_sfr_1re[ self.in_mass_range_nonbarred] else: # Set Full Barred and Unbarred Sample self.barred_sample = self.get_barred_galaxies_dap() argsort = np.argsort(self.barred_sample["NSA_Z"]) self.barred_sample = self.barred_sample[argsort] self.nonbarred_sample = self.get_barred_galaxies_dap( nonbarred=True) argsort = np.argsort(self.nonbarred_sample["NSA_Z"]) self.nonbarred_sample = self.nonbarred_sample[argsort] # At least Green Valley Selection # Set Color Keys: color_keys = ["F", "N", "u", "g", "r", "i", "z"] # Cosmology Correction h = 1 * u.mag * u.littleh cor = 5. * np.log10(h.to(u.mag, u.with_H0( WMAP9.H0)).value) * u.mag barred_sample_phot = Table( self.drp[self.barred_sample["DRPALLINDX"]] ['nsa_elpetro_absmag'] * u.mag + cor, names=color_keys) nonbarred_sample_phot = Table( self.drp[self.nonbarred_sample["DRPALLINDX"]] ['nsa_elpetro_absmag'] * u.mag + cor, names=color_keys) # Remove Red Galaxies with NUV - r > 5 self.barred_sample = self.barred_sample[( barred_sample_phot["N"] - barred_sample_phot["r"]) <= 5] self.nonbarred_sample = self.nonbarred_sample[( nonbarred_sample_phot["N"] - nonbarred_sample_phot["r"]) <= 5] # Stellar Masses self.barred_stellar_mass = (self.drp[self.barred_sample["DRPALLINDX"]]["nsa_elpetro_mass"] * \ u.solMass* u.littleh**-2).to(u.solMass, u.with_H0(WMAP9.H0)) self.nonbarred_stellar_mass = (self.drp[self.nonbarred_sample["DRPALLINDX"]]["nsa_elpetro_mass"] * \ u.solMass* u.littleh**-2).to(u.solMass, u.with_H0(WMAP9.H0)) # Mass Selections self.in_mass_range_barred = self.barred_stellar_mass <= self.mw_stellar_mass + self.mw_stellar_mass_err self.in_mass_range_barred &= self.barred_stellar_mass > self.mw_stellar_mass - self.mw_stellar_mass_err self.in_mass_range_nonbarred = self.nonbarred_stellar_mass <= self.mw_stellar_mass + self.mw_stellar_mass_err self.in_mass_range_nonbarred &= self.nonbarred_stellar_mass > self.mw_stellar_mass - self.mw_stellar_mass_err #JBH self.in_mass_range_barred_jbh = self.barred_stellar_mass <= self.mw_stellar_mass_jbh + self.mw_stellar_mass_jbh_err self.in_mass_range_barred_jbh &= self.barred_stellar_mass > self.mw_stellar_mass_jbh - self.mw_stellar_mass_jbh_err self.in_mass_range_nonbarred_jbh = self.nonbarred_stellar_mass <= self.mw_stellar_mass_jbh + self.mw_stellar_mass_jbh_err self.in_mass_range_nonbarred_jbh &= self.nonbarred_stellar_mass > self.mw_stellar_mass_jbh - self.mw_stellar_mass_jbh_err self.dk_sample = self.barred_sample[self.in_mass_range_barred] self.dk_sample_nobar = self.nonbarred_sample[ self.in_mass_range_nonbarred] #JBH self.dk_sample_jbh = self.barred_sample[ self.in_mass_range_barred_jbh] self.dk_sample_jbh_nobar = self.nonbarred_sample[ self.in_mass_range_nonbarred_jbh] #SFR self.barred_sfr = (self.barred_sample["SFR_TOT"] * u.solMass / u.yr * u.littleh**-2).to( u.solMass / u.yr, u.with_H0(WMAP9.H0)) self.nonbarred_sfr = (self.nonbarred_sample["SFR_TOT"] * u.solMass / u.yr * u.littleh**-2).to( u.solMass / u.yr, u.with_H0(WMAP9.H0)) self.dk_sample_sfr = self.barred_sfr[self.in_mass_range_barred] self.dk_sample_nobar_sfr = self.nonbarred_sfr[ self.in_mass_range_nonbarred] self.dk_sample_jbh_sfr = self.barred_sfr[ self.in_mass_range_barred_jbh] self.dk_sample_jbh_nobar_sfr = self.nonbarred_sfr[ self.in_mass_range_nonbarred_jbh]