def test_age(): """Test integrated age against analytical age.""" z = numpy.arange(0, 10.0, 0.05) cosmo = {} cosmo['omega_M_0'] = numpy.array([[0.99],[0.01],[0.3]]) cosmo['omega_lambda_0'] = 1. - cosmo['omega_M_0'] cosmo['h'] = 0.7 cd.set_omega_k_0(cosmo) linestyle = ['-', ':', '--'] gyr = 1e9 * cc.yr_s tl = cd.lookback_time(z, **cosmo) age = cd.age(z, **cosmo) age_ana = cd.age_flat(z, **cosmo) pylab.figure(figsize=(6,6)) for i in range(len(linestyle)): pylab.plot(z, (tl/gyr)[i], ls=linestyle[i], color='0.5') pylab.plot(z, (age/gyr)[i], ls=linestyle[i], color='r') pylab.plot(z, (age_ana/gyr)[i], ls=linestyle[i], color='k') pylab.xlabel("redshift z") pylab.ylabel(r"age $t_L/$Gyr") pylab.figure(figsize=(6,6)) for i in range(len(linestyle)): pylab.plot(z, ((age - age_ana)/age_ana)[i], ls=linestyle[i], color='k') # Make sure errors are small: ntest.assert_array_less((numpy.abs((age - age_ana)/age_ana)[i]), 3e-13) pylab.xlabel("redshift z") pylab.ylabel(r"age: (integral - analytical)/analytical")
def params_z(self, z): """Return interp/extrapolated Schechter function parameters.""" if self.extrap_var == 'z': return {'MStar':self._MStarfunc(z), 'phiStar':self._phiStarfunc(z), 'alpha':self._alphafunc(z)} elif self.extrap_var == 't': z = numpy.atleast_1d(z) t = cd.age(z, **self.cosmo)[0] return self.params_t(t)
def params_z(self, z): """Return interp/extrapolated Schechter function parameters.""" if self.extrap_var == 'z': return { 'MStar': self._MStarfunc(z), 'phiStar': self._phiStarfunc(z), 'alpha': self._alphafunc(z) } elif self.extrap_var == 't': z = numpy.atleast_1d(z) t = cd.age(z, **self.cosmo)[0] return self.params_t(t)
def age_t(z, **cosmo): z = np.atleast_1d(z) if cosmo == {}: cosmo_in = { 'omega_M_0': 0.3, 'omega_lambda_0': 0.7, 'omega_k_0': 0.0, 'h': 0.70 } else: cosmo_in = cosmo results = cd.age(z, **cosmo_in) / cc.Gyr_s return results
def get_lookback_time(self, z): """Calculates the lookback time to redshift z. Uses :func:`cosmolopy.distance.age` and :func:`cosmolopy.distance.lookback_time`, which are based on equation 30 of David Hogg's `Distance measures in cosmology. <https://arxiv.org/abs/astro-ph/9905116>`_ Args: z (float): Redshift for which to calculate the lookback time Returns: (float): Lookback time in years """ sec = cd.age(z, **self.cosmo) return sec / cc.yr_s
def calculate_age_stars(ro_in=None, dset_in=None, converted=False, time_proper=True): """ Parameters ---------- converted: bool if the epoch field is in code unit or converted to some physical unit Return ------ starsFormedatUniverseAge: age of the universe when the star particle was created in Myr """ if converted: raise ValueError( "Epoch field should be in code unit for this function to work properly.." ) if (time_proper): # switch depends on ramses run setup import cosmolopy.distance as cd import cosmolopy.constants as cc cosmo = { 'omega_M_0': ro_in.info["omega_m"], 'omega_lambda_0': ro_in.info["omega_l"], 'h': ro_in.info["H0"] / 100. } cosmo = cd.set_omega_k_0(cosmo) t_z0 = cd.age(0., **cosmo) / (cc.Gyr_s / 1.e+3) # Myr ram2myr = ro_in.info["unit_time"].express( C.Myr) / ro_in.info["aexp"]**2 starsFormedatUniverseAge = t_z0 + dset_in["epoch"][:] * ram2myr else: Myr_unit_time = ro_in.info["unit_time"].express(C.Myr) starsFormedatUniverseAge = (ro_in.info["time"] - dset_in["epoch"][:]) * Myr_unit_time return starsFormedatUniverseAge
def test_t_0(): """Check the age of the universe we get using WMAP cosmologies. We only find agreement to 3 sig figs, not the 4 specified in the WMAP paper. The results of test_age.py show that we're doing the integral correctly, so I think the problem is that we're not taking into account some of the higher-order effects included in the WMAP numbers. """ dz = 0.1 z = numpy.arange(80., 0. - 1.5 * dz, -1. * dz) flat = True cosmos = [ cparam.WMAP7_BAO_H0_mean(flat=True), cparam.WMAP7_ML(flat=True), cparam.WMAP5_BAO_SN_mean(flat=True), cparam.WMAP5_ML(flat=True), cparam.WMAP5_mean(flat=True) ] for cosmo in cosmos: age = cd.age(0.0, **cosmo) age_flat = cd.age_flat(0.0, **cosmo) gyr = 1e9 * cc.yr_s age /= gyr age_flat /= gyr print "integrated age: ", print tu.fractional_diff_string(age, cosmo['t_0'], 4) ntest.assert_approx_equal(age, cosmo['t_0'], significant=3, err_msg="Integrated age doesn't match WMAP") print "analytical age: ", print tu.fractional_diff_string(age_flat, cosmo['t_0'], 4) ntest.assert_approx_equal(age_flat, cosmo['t_0'], significant=3, err_msg="Analytical age doesn't match WMAP")
def test_figure6(): """Plot Hogg fig. 6: The dimensionless lookback time t_L/t_H and age t/t_H. The three curves are for the three world models, - Einstein-de Sitter (omega_M, omega_lambda) = (1, 0) [solid] : Low-density (0.05, 0) [dotted] -- High lambda, (0.2, 0.8) [dashed] Hubble distance DH = c / H0 z from 0--5 t/th from 0--1.2 """ z = numpy.arange(0, 5.05, 0.05) cosmo = {} cosmo['omega_M_0'] = numpy.array([[1.0], [0.05], [0.2]]) cosmo['omega_lambda_0'] = numpy.array([[0.0], [0.0], [0.8]]) cosmo['h'] = 0.5 cd.set_omega_k_0(cosmo) linestyle = ['-', ':', '--'] th = 1 / cd.hubble_z(0, **cosmo) tl = cd.lookback_time(z, **cosmo) age = cd.age(z, **cosmo) pylab.figure(figsize=(6, 6)) for i in range(len(linestyle)): pylab.plot(z, (tl / th)[i], ls=linestyle[i]) pylab.plot(z, (age / th)[i], ls=linestyle[i]) pylab.xlim(0, 5) pylab.ylim(0, 1.2) pylab.xlabel("redshift z") pylab.ylabel(r"lookback timne $t_L/t_H$") pylab.title("compare to " + inspect.stack()[0][3].replace('test_', '') + " (astro-ph/9905116v4)")
def test_figure6(): """Plot Hogg fig. 6: The dimensionless lookback time t_L/t_H and age t/t_H. The three curves are for the three world models, - Einstein-de Sitter (omega_M, omega_lambda) = (1, 0) [solid] : Low-density (0.05, 0) [dotted] -- High lambda, (0.2, 0.8) [dashed] Hubble distance DH = c / H0 z from 0--5 t/th from 0--1.2 """ z = numpy.arange(0, 5.05, 0.05) cosmo = {} cosmo['omega_M_0'] = numpy.array([[1.0],[0.05],[0.2]]) cosmo['omega_lambda_0'] = numpy.array([[0.0],[0.0],[0.8]]) cosmo['h'] = 0.5 cd.set_omega_k_0(cosmo) linestyle = ['-', ':', '--'] th = 1/ cd.hubble_z(0, **cosmo) tl = cd.lookback_time(z, **cosmo) age = cd.age(z, **cosmo) pylab.figure(figsize=(6,6)) for i in range(len(linestyle)): pylab.plot(z, (tl/th)[i], ls=linestyle[i]) pylab.plot(z, (age/th)[i], ls=linestyle[i]) pylab.xlim(0,5) pylab.ylim(0,1.2) pylab.xlabel("redshift z") pylab.ylabel(r"lookback timne $t_L/t_H$") pylab.title("compare to " + inspect.stack()[0][3].replace('test_', '') + " (astro-ph/9905116v4)")
def test_t_0(): """Check the age of the universe we get using WMAP cosmologies. We only find agreement to 3 sig figs, not the 4 specified in the WMAP paper. The results of test_age.py show that we're doing the integral correctly, so I think the problem is that we're not taking into account some of the higher-order effects included in the WMAP numbers. """ dz = 0.1 z = numpy.arange(80., 0. - 1.5 * dz, -1. * dz) flat = True cosmos = [cparam.WMAP7_BAO_H0_mean(flat=True), cparam.WMAP7_ML(flat=True), cparam.WMAP5_BAO_SN_mean(flat=True), cparam.WMAP5_ML(flat=True), cparam.WMAP5_mean(flat=True)] for cosmo in cosmos: age = cd.age(0.0, **cosmo) age_flat = cd.age_flat(0.0, **cosmo) gyr = 1e9 * cc.yr_s age /= gyr age_flat /= gyr print "integrated age: ", print tu.fractional_diff_string(age, cosmo['t_0'], 4) ntest.assert_approx_equal(age, cosmo['t_0'], significant=3, err_msg="Integrated age doesn't match WMAP") print "analytical age: ", print tu.fractional_diff_string(age_flat, cosmo['t_0'], 4) ntest.assert_approx_equal(age_flat, cosmo['t_0'], significant=3, err_msg="Analytical age doesn't match WMAP")
def test_age(): """Test integrated age against analytical age.""" z = numpy.arange(0, 10.0, 0.05) cosmo = {} cosmo['omega_M_0'] = numpy.array([[0.99], [0.01], [0.3]]) cosmo['omega_lambda_0'] = 1. - cosmo['omega_M_0'] cosmo['h'] = 0.7 cd.set_omega_k_0(cosmo) linestyle = ['-', ':', '--'] gyr = 1e9 * cc.yr_s tl = cd.lookback_time(z, **cosmo) age = cd.age(z, **cosmo) age_ana = cd.age_flat(z, **cosmo) pylab.figure(figsize=(6, 6)) for i in range(len(linestyle)): pylab.plot(z, (tl / gyr)[i], ls=linestyle[i], color='0.5') pylab.plot(z, (age / gyr)[i], ls=linestyle[i], color='r') pylab.plot(z, (age_ana / gyr)[i], ls=linestyle[i], color='k') pylab.xlabel("redshift z") pylab.ylabel(r"age $t_L/$Gyr") pylab.figure(figsize=(6, 6)) for i in range(len(linestyle)): pylab.plot(z, ((age - age_ana) / age_ana)[i], ls=linestyle[i], color='k') # Make sure errors are small: ntest.assert_array_less((numpy.abs((age - age_ana) / age_ana)[i]), 3e-13) pylab.xlabel("redshift z") pylab.ylabel(r"age: (integral - analytical)/analytical")
def get_evolv(ID0, PA, Z=np.arange(-1.2,0.4249,0.05), age=[0.01, 0.1, 0.3, 0.7, 1.0, 3.0], f_comp = 0, fil_path = './FILT/', inputs=None, dust_model=0, DIR_TMP='./templates/', delt_sfh = 0.01): # # delt_sfh (float): delta t of input SFH in Gyr. # # Returns: SED as function of age, based on SF and Z histories; # print('This function may take a while.') flim = 0.01 lsfrl = -1 # log SFR low limit mmax = 1000 Txmax = 4 # Max x value lmmin = 10.3 nage = np.arange(0,len(age),1) fnc = Func(Z, nage, dust_model=dust_model) # Set up the number of Age/ZZ bfnc = Basic(Z) age = np.asarray(age) ################ # RF colors. import os.path home = os.path.expanduser('~') c = 3.e18 # A/s chimax = 1. mag0 = 25.0 d = 10**(73.6/2.5) * 1e-18 # From [ergs/s/cm2/A] to [ergs/s/cm2/Hz] ########################### # Open result file ########################### file = 'summary_' + ID0 + '_PA' + PA + '.fits' hdul = fits.open(file) # open a FITS file zbes = hdul[0].header['z'] chinu= hdul[1].data['chi'] uv= hdul[1].data['uv'] vj= hdul[1].data['vj'] RA = 0 DEC = 0 rek = 0 erekl= 0 ereku= 0 mu = 1.0 nn = 0 qq = 0 enn = 0 eqq = 0 try: RA = hdul[0].header['RA'] DEC = hdul[0].header['DEC'] except: RA = 0 DEC = 0 try: SN = hdul[0].header['SN'] except: ########################### # Get SN of Spectra ########################### file = 'templates/spec_obs_' + ID0 + '_PA' + PA + '.cat' fds = np.loadtxt(file, comments='#') nrs = fds[:,0] lams = fds[:,1] fsp = fds[:,2] esp = fds[:,3] consp = (nrs<10000) & (lams/(1.+zbes)>3600) & (lams/(1.+zbes)<4200) if len((fsp/esp)[consp]>10): SN = np.median((fsp/esp)[consp]) else: SN = 1 Asum = 0 A50 = np.arange(len(age), dtype='float32') for aa in range(len(A50)): A50[aa] = hdul[1].data['A'+str(aa)][1] Asum += A50[aa] #################### # For cosmology #################### DL = cd.luminosity_distance(zbes, **cosmo) * Mpc_cm # Luminositydistance in cm Cons = (4.*np.pi*DL**2/(1.+zbes)) Tuni = cd.age(zbes, use_flat=True, **cosmo) Tuni0 = (Tuni/cc.Gyr_s - age[:]) delT = np.zeros(len(age),dtype='float32') delTl = np.zeros(len(age),dtype='float32') delTu = np.zeros(len(age),dtype='float32') for aa in range(len(age)): if aa == 0: delTl[aa] = age[aa] delTu[aa] = (age[aa+1]-age[aa])/2. delT[aa] = delTu[aa] + delTl[aa] elif Tuni/cc.Gyr_s < age[aa]: delTl[aa] = (age[aa]-age[aa-1])/2. delTu[aa] = delTl[aa] #10. delT[aa] = delTu[aa] + delTl[aa] elif aa == len(age)-1: delTl[aa] = (age[aa]-age[aa-1])/2. delTu[aa] = Tuni/cc.Gyr_s - age[aa] delT[aa] = delTu[aa] + delTl[aa] else: delTl[aa] = (age[aa]-age[aa-1])/2. delTu[aa] = (age[aa+1]-age[aa])/2. delT[aa] = delTu[aa] + delTl[aa] delT[:] *= 1e9 # Gyr to yr delTl[:] *= 1e9 # Gyr to yr delTu[:] *= 1e9 # Gyr to yr ############################## # Load Pickle ############################## samplepath = './' pfile = 'chain_' + ID0 + '_PA' + PA + '_corner.cpkl' niter = 0 data = loadcpkl(os.path.join(samplepath+'/'+pfile)) try: ndim = data['ndim'] # By default, use ndim and burnin values contained in the cpkl file, if present. burnin = data['burnin'] nmc = data['niter'] nwalk = data['nwalkers'] Nburn = burnin #* nwalk/10/2 # I think this takes 3/4 of samples #if nmc>1000: # Nburn = 500 samples = data['chain'][:] except: print(' = > NO keys of ndim and burnin found in cpkl, use input keyword values') return -1 ###################### # Mass-to-Light ratio. ###################### AM = np.zeros((len(age), mmax), dtype='float32') # Mass in each bin. AC = np.zeros((len(age), mmax), dtype='float32') # Cumulative mass in each bin. AL = np.zeros((len(age), mmax), dtype='float32') # Cumulative light in each bin. ZM = np.zeros((len(age), mmax), dtype='float32') # Z. ZC = np.zeros((len(age), mmax), dtype='float32') # Cumulative Z. ZL = np.zeros((len(age), mmax), dtype='float32') # Light weighted cumulative Z. TC = np.zeros((len(age), mmax), dtype='float32') # Mass weighted T. TL = np.zeros((len(age), mmax), dtype='float32') # Light weighted T. ZMM= np.zeros((len(age), mmax), dtype='float32') # Mass weighted Z. ZML= np.zeros((len(age), mmax), dtype='float32') # Light weighted Z. SF = np.zeros((len(age), mmax), dtype='float32') # SFR Av = np.zeros(mmax, dtype='float32') # SFR # ############################## # Add simulated scatter in quad # if files are available. # ############################## if inputs: f_zev = int(inputs['ZEVOL']) else: f_zev = 1 eZ_mean = 0 try: meanfile = './sim_SFH_mean.cat' dfile = np.loadtxt(meanfile, comments='#') eA = dfile[:,2] eZ = dfile[:,4] eAv= np.mean(dfile[:,6]) if f_zev == 0: eZ_mean = np.mean(eZ[:]) eZ[:] = age * 0 #+ eZ_mean else: try: f_zev = int(prihdr['ZEVOL']) if f_zev == 0: eZ_mean = np.mean(eZ[:]) eZ = age * 0 except: pass except: print('No simulation file (%s).\nError may be underestimated.' % meanfile) eA = age * 0 eZ = age * 0 eAv= 0 mm = 0 #mmax = 10 #print('mmax is set to 10') for mm in range(mmax): mtmp = np.random.randint(len(samples))# + Nburn AAtmp = np.zeros(len(age), dtype='float32') ZZtmp = np.zeros(len(age), dtype='float32') mslist= np.zeros(len(age), dtype='float32') Av_tmp = samples['Av'][mtmp] f0 = fits.open(DIR_TMP + 'ms_' + ID0 + '_PA' + PA + '.fits') sedpar = f0[1] f1 = fits.open(DIR_TMP + 'ms.fits') mloss = f1[1].data Avrand = np.random.uniform(-eAv, eAv) if Av_tmp + Avrand<0: Av[mm] = 0 else: Av[mm] = Av_tmp + Avrand for aa in range(len(age)): AAtmp[aa] = samples['A'+str(aa)][mtmp]/mu try: ZZtmp[aa] = samples['Z'+str(aa)][mtmp] except: ZZtmp[aa] = samples['Z0'][mtmp] nZtmp = bfnc.Z2NZ(ZZtmp[aa]) mslist[aa] = sedpar.data['ML_'+str(nZtmp)][aa] ml = mloss['ms_'+str(nZtmp)][aa] Arand = np.random.uniform(-eA[aa],eA[aa]) Zrand = np.random.uniform(-eZ[aa],eZ[aa]) AM[aa, mm] = AAtmp[aa] * mslist[aa] * 10**Arand AL[aa, mm] = AM[aa, mm] / mslist[aa] SF[aa, mm] = AAtmp[aa] * mslist[aa] / delT[aa] / ml * 10**Arand ZM[aa, mm] = ZZtmp[aa] + Zrand ZMM[aa, mm]= (10 ** ZZtmp[aa]) * AAtmp[aa] * mslist[aa] * 10**Zrand ZML[aa, mm]= ZMM[aa, mm] / mslist[aa] for aa in range(len(age)): AC[aa, mm] = np.sum(AM[aa:, mm]) ZC[aa, mm] = np.log10(np.sum(ZMM[aa:, mm])/AC[aa, mm]) ZL[aa, mm] = np.log10(np.sum(ZML[aa:, mm])/np.sum(AL[aa:, mm])) if f_zev == 0: # To avoid random fluctuation in A. ZC[aa, mm] = ZM[aa, mm] ACs = 0 ALs = 0 for bb in range(aa, len(age), 1): tmpAA = 10**np.random.uniform(-eA[bb],eA[bb]) tmpTT = np.random.uniform(-delT[bb]/1e9,delT[bb]/1e9) TC[aa, mm] += (age[bb]+tmpTT) * AAtmp[bb] * mslist[bb] * tmpAA TL[aa, mm] += (age[bb]+tmpTT) * AAtmp[bb] * tmpAA ACs += AAtmp[bb] * mslist[bb] * tmpAA ALs += AAtmp[bb] * tmpAA TC[aa, mm] /= ACs TL[aa, mm] /= ALs Avtmp = np.percentile(Av[:],[16,50,84]) ############# # Plot ############# AMp = np.zeros((len(age),3), dtype='float32') ACp = np.zeros((len(age),3), dtype='float32') ZMp = np.zeros((len(age),3), dtype='float32') ZCp = np.zeros((len(age),3), dtype='float32') SFp = np.zeros((len(age),3), dtype='float32') for aa in range(len(age)): AMp[aa,:] = np.percentile(AM[aa,:], [16,50,84]) ACp[aa,:] = np.percentile(AC[aa,:], [16,50,84]) ZMp[aa,:] = np.percentile(ZM[aa,:], [16,50,84]) ZCp[aa,:] = np.percentile(ZC[aa,:], [16,50,84]) SFp[aa,:] = np.percentile(SF[aa,:], [16,50,84]) ################### msize = np.zeros(len(age), dtype='float32') for aa in range(len(age)): if A50[aa]/Asum>flim: # if >1% msize[aa] = 150 * A50[aa]/Asum conA = (msize>=0) # Make template; tbegin = np.min(Tuni/cc.Gyr_s-age) tuniv_hr = np.arange(tbegin,Tuni/cc.Gyr_s,delt_sfh) # in Gyr sfh_hr_in= np.interp(tuniv_hr,(Tuni/cc.Gyr_s-age)[::-1],SFp[:,1][::-1]) zh_hr_in = np.interp(tuniv_hr,(Tuni/cc.Gyr_s-age)[::-1],ZCp[:,1][::-1]) # FSPS con_sfh = (tuniv_hr>0) import fsps nimf = int(inputs['NIMF']) try: fneb = int(inputs['ADD_NEBULAE']) except: fneb = 0 if fneb == 1: print('Metallicity is set to logZ/Zsun=%.2f'%(np.max(zh_hr_in))) sp = fsps.StellarPopulation(compute_vega_mags=False, zcontinuous=1, imf_type=nimf, logzsol=np.max(zh_hr_in), sfh=3, dust_type=2, dust2=0.0, add_neb_emission=True) sp.set_tabular_sfh(tuniv_hr[con_sfh], sfh_hr_in[con_sfh]) else: sp = fsps.StellarPopulation(compute_vega_mags=False, zcontinuous=3, imf_type=nimf, sfh=3, dust_type=2, dust2=0.0, add_neb_emission=False) sp.set_tabular_sfh(tuniv_hr[con_sfh], sfh_hr_in[con_sfh], Z=10**zh_hr_in[con_sfh]) col01 = [] t_get = tuniv_hr[con_sfh] #con_tget = ((Tuni/cc.Gyr_s-age)>0) #t_get = (Tuni/cc.Gyr_s-age)[con_tget][::-1] for ss in range(len(t_get)): wave0, flux0 = sp.get_spectrum(tage=t_get[ss], peraa=True) # if peraa=True, in unit of L/AA if ss == 0: spec_mul_nu_conv = np.zeros((len(t_get),len(wave0)),dtype='float32') #ax2.plot(wave0, flux0, linestyle='-', color='b') #plt.show() print('Template %d is done.'%(ss)) wavetmp = wave0*(1.+zbes) spec_mul_nu = flamtonu(wavetmp, flux0) # Conversion from Flambda to Fnu. Lsun = 3.839 * 1e33 #erg s-1 stmp_common = 1e10 # 1 tmp is in 1e10Lsun spec_mul_nu_conv[ss,:] = spec_mul_nu[:] spec_mul_nu_conv[ss,:] *= Lsun/(4.*np.pi*DL**2/(1.+zbes)) Ls = 10**sp.log_lbol spec_mul_nu_conv[ss,:] *= (1./Ls)*stmp_common # in unit of erg/s/Hz/cm2/ms[ss]. consave = (wavetmp/(1.+zbes)<20000) # AA if ss == 0: nd_ap = np.arange(0,len(wave0),1) col1 = fits.Column(name='wavelength', format='E', unit='AA', disp='obs', array=wavetmp[consave]) col2 = fits.Column(name='colnum', format='K', unit='', array=nd_ap[consave]) col00 = [col1, col2] col3 = fits.Column(name='age', format='E', unit='Gyr', array=t_get) col4 = fits.Column(name='sfh', format='E', unit='Msun/yr', array=sfh_hr_in[con_sfh]) col5 = fits.Column(name='zh', format='E', unit='Zsun', array=zh_hr_in[con_sfh]) col01 = [col3,col4,col5] colspec_all = fits.Column(name='fspec_'+str(ss), format='E', unit='Fnu', disp='%s'%(t_get[ss]), array=spec_mul_nu_conv[ss,:][consave]) col00.append(colspec_all) coldefs_spec = fits.ColDefs(col00) hdu = fits.BinTableHDU.from_columns(coldefs_spec) hdu.writeto(DIR_TMP + 'obsspec_' + ID0 + '_PA' + PA + '.fits', overwrite=True) coldefs_spec = fits.ColDefs(col01) hdu = fits.BinTableHDU.from_columns(coldefs_spec) hdu.writeto(DIR_TMP + 'obshist_' + ID0 + '_PA' + PA + '.fits', overwrite=True)
def plot_sfh(ID0, PA, Z=np.arange(-1.2,0.4249,0.05), age=[0.01, 0.1, 0.3, 0.7, 1.0, 3.0], f_comp = 0, fil_path = './FILT/', inputs=None, dust_model=0, DIR_TMP='./templates/',f_SFMS=False): # # # flim = 0.01 lsfrl = -1 # log SFR low limit mmax = 1000 Txmax = 4 # Max x value lmmin = 9.5 #10.3 nage = np.arange(0,len(age),1) fnc = Func(Z, nage, dust_model=dust_model) # Set up the number of Age/ZZ bfnc = Basic(Z) age = np.asarray(age) ################ # RF colors. import os.path home = os.path.expanduser('~') c = 3.e18 # A/s chimax = 1. mag0 = 25.0 d = 10**(73.6/2.5) * 1e-18 # From [ergs/s/cm2/A] to [ergs/s/cm2/Hz] #d = 10**(-73.6/2.5) # From [ergs/s/cm2/Hz] to [ergs/s/cm2/A] ############# # Plot. ############# fig = plt.figure(figsize=(8,2.8)) fig.subplots_adjust(top=0.88, bottom=0.18, left=0.07, right=0.99, hspace=0.15, wspace=0.3) ax1 = fig.add_subplot(131) ax2 = fig.add_subplot(132) #ax3 = fig.add_subplot(223) ax4 = fig.add_subplot(133) ax1t = ax1.twiny() ax2t = ax2.twiny() #ax3t = ax3.twiny() ax4t = ax4.twiny() ################## # Fitting Results ################## #DIR_TMP = './templates/' SNlim = 3 # avobe which SN line is shown. ########################### # Open result file ########################### file = 'summary_' + ID0 + '_PA' + PA + '.fits' hdul = fits.open(file) # open a FITS file zbes = hdul[0].header['z'] chinu= hdul[1].data['chi'] uv= hdul[1].data['uv'] vj= hdul[1].data['vj'] RA = 0 DEC = 0 rek = 0 erekl= 0 ereku= 0 mu = 1.0 nn = 0 qq = 0 enn = 0 eqq = 0 try: RA = hdul[0].header['RA'] DEC = hdul[0].header['DEC'] except: RA = 0 DEC = 0 try: SN = hdul[0].header['SN'] except: ########################### # Get SN of Spectra ########################### file = 'templates/spec_obs_' + ID0 + '_PA' + PA + '.cat' fds = np.loadtxt(file, comments='#') nrs = fds[:,0] lams = fds[:,1] fsp = fds[:,2] esp = fds[:,3] consp = (nrs<10000) & (lams/(1.+zbes)>3600) & (lams/(1.+zbes)<4200) if len((fsp/esp)[consp]>10): SN = np.median((fsp/esp)[consp]) else: SN = 1 Asum = 0 A50 = np.arange(len(age), dtype='float32') for aa in range(len(A50)): A50[aa] = hdul[1].data['A'+str(aa)][1] Asum += A50[aa] #################### # For cosmology #################### DL = cd.luminosity_distance(zbes, **cosmo) * Mpc_cm # Luminositydistance in cm Cons = (4.*np.pi*DL**2/(1.+zbes)) Tuni = cd.age(zbes, use_flat=True, **cosmo) Tuni0 = (Tuni/cc.Gyr_s - age[:]) delT = np.zeros(len(age),dtype='float32') delTl = np.zeros(len(age),dtype='float32') delTu = np.zeros(len(age),dtype='float32') for aa in range(len(age)): if aa == 0: delTl[aa] = age[aa] delTu[aa] = (age[aa+1]-age[aa])/2. delT[aa] = delTu[aa] + delTl[aa] elif Tuni/cc.Gyr_s < age[aa]: delTl[aa] = (age[aa]-age[aa-1])/2. delTu[aa] = delTl[aa] #10. delT[aa] = delTu[aa] + delTl[aa] elif aa == len(age)-1: delTl[aa] = (age[aa]-age[aa-1])/2. delTu[aa] = Tuni/cc.Gyr_s - age[aa] delT[aa] = delTu[aa] + delTl[aa] else: delTl[aa] = (age[aa]-age[aa-1])/2. delTu[aa] = (age[aa+1]-age[aa])/2. delT[aa] = delTu[aa] + delTl[aa] delT[:] *= 1e9 # Gyr to yr delTl[:] *= 1e9 # Gyr to yr delTu[:] *= 1e9 # Gyr to yr #print(age, delT, delTu, delTl) ############################## # Load Pickle ############################## samplepath = './' pfile = 'chain_' + ID0 + '_PA' + PA + '_corner.cpkl' niter = 0 data = loadcpkl(os.path.join(samplepath+'/'+pfile)) try: #if 1>0: ndim = data['ndim'] # By default, use ndim and burnin values contained in the cpkl file, if present. burnin = data['burnin'] nmc = data['niter'] nwalk = data['nwalkers'] Nburn = burnin #* nwalk/10/2 # I think this takes 3/4 of samples #if nmc>1000: # Nburn = 500 samples = data['chain'][:] except: print(' = > NO keys of ndim and burnin found in cpkl, use input keyword values') return -1 ###################### # Mass-to-Light ratio. ###################### #ms = np.zeros(len(age), dtype='float32') # Wht do you want from MCMC sampler? AM = np.zeros((len(age), mmax), dtype='float32') # Mass in each bin. AC = np.zeros((len(age), mmax), dtype='float32') # Cumulative mass in each bin. AL = np.zeros((len(age), mmax), dtype='float32') # Cumulative light in each bin. ZM = np.zeros((len(age), mmax), dtype='float32') # Z. ZC = np.zeros((len(age), mmax), dtype='float32') # Cumulative Z. ZL = np.zeros((len(age), mmax), dtype='float32') # Light weighted cumulative Z. TC = np.zeros((len(age), mmax), dtype='float32') # Mass weighted T. TL = np.zeros((len(age), mmax), dtype='float32') # Light weighted T. ZMM= np.zeros((len(age), mmax), dtype='float32') # Mass weighted Z. ZML= np.zeros((len(age), mmax), dtype='float32') # Light weighted Z. SF = np.zeros((len(age), mmax), dtype='float32') # SFR Av = np.zeros(mmax, dtype='float32') # SFR # ############################## # Add simulated scatter in quad # if files are available. # ############################## if inputs: f_zev = int(inputs['ZEVOL']) else: f_zev = 1 eZ_mean = 0 try: #meanfile = '/Users/tmorishita/Documents/Astronomy/sim_tran/sim_SFH_mean.cat' meanfile = './sim_SFH_mean.cat' dfile = np.loadtxt(meanfile, comments='#') eA = dfile[:,2] eZ = dfile[:,4] eAv= np.mean(dfile[:,6]) if f_zev == 0: eZ_mean = np.mean(eZ[:]) eZ[:] = age * 0 #+ eZ_mean else: try: f_zev = int(prihdr['ZEVOL']) if f_zev == 0: eZ_mean = np.mean(eZ[:]) eZ = age * 0 except: pass except: print('No simulation file (%s).\nError may be underestimated.' % meanfile) eA = age * 0 eZ = age * 0 eAv= 0 mm = 0 #while mm<mmax: for mm in range(mmax): mtmp = np.random.randint(len(samples))# + Nburn AAtmp = np.zeros(len(age), dtype='float32') ZZtmp = np.zeros(len(age), dtype='float32') mslist= np.zeros(len(age), dtype='float32') Av_tmp = samples['Av'][mtmp] f0 = fits.open(DIR_TMP + 'ms_' + ID0 + '_PA' + PA + '.fits') sedpar = f0[1] f1 = fits.open(DIR_TMP + 'ms.fits') mloss = f1[1].data Avrand = np.random.uniform(-eAv, eAv) if Av_tmp + Avrand<0: Av[mm] = 0 else: Av[mm] = Av_tmp + Avrand for aa in range(len(age)): AAtmp[aa] = samples['A'+str(aa)][mtmp]/mu try: ZZtmp[aa] = samples['Z'+str(aa)][mtmp] except: ZZtmp[aa] = samples['Z0'][mtmp] nZtmp = bfnc.Z2NZ(ZZtmp[aa]) mslist[aa] = sedpar.data['ML_'+str(nZtmp)][aa] ml = mloss['ms_'+str(nZtmp)][aa] Arand = np.random.uniform(-eA[aa],eA[aa]) Zrand = np.random.uniform(-eZ[aa],eZ[aa]) AM[aa, mm] = AAtmp[aa] * mslist[aa] * 10**Arand AL[aa, mm] = AM[aa, mm] / mslist[aa] SF[aa, mm] = AAtmp[aa] * mslist[aa] / delT[aa] / ml * 10**Arand ZM[aa, mm] = ZZtmp[aa] + Zrand ZMM[aa, mm]= (10 ** ZZtmp[aa]) * AAtmp[aa] * mslist[aa] * 10**Zrand ZML[aa, mm]= ZMM[aa, mm] / mslist[aa] for aa in range(len(age)): AC[aa, mm] = np.sum(AM[aa:, mm]) ZC[aa, mm] = np.log10(np.sum(ZMM[aa:, mm])/AC[aa, mm]) ZL[aa, mm] = np.log10(np.sum(ZML[aa:, mm])/np.sum(AL[aa:, mm])) if f_zev == 0: # To avoid random fluctuation in A. ZC[aa, mm] = ZM[aa, mm] ACs = 0 ALs = 0 for bb in range(aa, len(age), 1): tmpAA = 10**np.random.uniform(-eA[bb],eA[bb]) tmpTT = np.random.uniform(-delT[bb]/1e9,delT[bb]/1e9) TC[aa, mm] += (age[bb]+tmpTT) * AAtmp[bb] * mslist[bb] * tmpAA TL[aa, mm] += (age[bb]+tmpTT) * AAtmp[bb] * tmpAA ACs += AAtmp[bb] * mslist[bb] * tmpAA ALs += AAtmp[bb] * tmpAA TC[aa, mm] /= ACs TL[aa, mm] /= ALs #Avtmp = np.percentile(samples['Av'][:],[16,50,84]) Avtmp = np.percentile(Av[:],[16,50,84]) ############# # Plot ############# AMp = np.zeros((len(age),3), dtype='float32') ACp = np.zeros((len(age),3), dtype='float32') ZMp = np.zeros((len(age),3), dtype='float32') ZCp = np.zeros((len(age),3), dtype='float32') SFp = np.zeros((len(age),3), dtype='float32') for aa in range(len(age)): AMp[aa,:] = np.percentile(AM[aa,:], [16,50,84]) ACp[aa,:] = np.percentile(AC[aa,:], [16,50,84]) ZMp[aa,:] = np.percentile(ZM[aa,:], [16,50,84]) ZCp[aa,:] = np.percentile(ZC[aa,:], [16,50,84]) SFp[aa,:] = np.percentile(SF[aa,:], [16,50,84]) ################### msize = np.zeros(len(age), dtype='float32') for aa in range(len(age)): if A50[aa]/Asum>flim: # if >1% msize[aa] = 150 * A50[aa]/Asum conA = (msize>=0) ax1.fill_between(age[conA], np.log10(SFp[:,0])[conA], np.log10(SFp[:,2])[conA], linestyle='-', color='k', alpha=0.3) #ax1.fill_between(age, np.log10(SFp[:,0]), np.log10(SFp[:,2]), linestyle='-', color='k', alpha=0.3) ax1.scatter(age[conA], np.log10(SFp[:,1])[conA], marker='.', c='k', s=msize[conA]) ax1.errorbar(age[conA], np.log10(SFp[:,1])[conA], xerr=[delTl[:][conA]/1e9,delTu[:][conA]/1e9], yerr=[np.log10(SFp[:,1])[conA]-np.log10(SFp[:,0])[conA], np.log10(SFp[:,2])[conA]-np.log10(SFp[:,1])[conA]], linestyle='-', color='k', lw=0.5, marker='') # Get SFMS; IMF = int(inputs['NIMF']) SFMS_16 = get_SFMS(zbes,age,ACp[:,0],IMF=IMF) SFMS_50 = get_SFMS(zbes,age,ACp[:,1],IMF=IMF) SFMS_84 = get_SFMS(zbes,age,ACp[:,2],IMF=IMF) f_rejuv,t_quench,t_rejuv = check_rejuv(age,np.log10(SFp[:,:]),np.log10(ACp[:,:]),np.log10(SFMS_50)) #print(f_rejuv,t_quench,t_rejuv) # Plot MS? if f_SFMS: #ax1.fill_between(age[conA], np.log10(SFMS_16)[conA], np.log10(SFMS_84)[conA], linestyle='-', color='b', alpha=0.3) ax1.fill_between(age[conA], np.log10(SFMS_50)[conA]-0.2, np.log10(SFMS_50)[conA]+0.2, linestyle='-', color='b', alpha=0.3) ax1.plot(age[conA], np.log10(SFMS_50)[conA], linestyle='--', color='b', alpha=0.5) # # Fit with delayed exponential?? # minsfr = 1e-10 if f_comp == 1: # # Plot exp model? # DIR_exp = '/Users/tmorishita/Documents/Astronomy/sedfitter_exp/' file = DIR_exp + 'summary_' + ID0 + '_PA' + PA + '.fits' hdul = fits.open(file) # open a FITS file t0 = 10**float(hdul[1].data['age'][1]) tau = 10**float(hdul[1].data['tau'][1]) A = float(hdul[1].data['A'][1]) Zexp= hdul[1].data['Z'] Mexp= float(hdul[1].data['ms'][1]) deltt0 = 0.01 # in Gyr tt0 = np.arange(0.01,10,deltt0) sfr = SFH_dec(np.max(age)-t0, tau, A, tt=tt0) mtmp = np.sum(sfr * deltt0 * 1e9) C_exp = Mexp/mtmp ax1.plot(np.max(age) - tt0, np.log10(sfr*C_exp), marker='', linestyle='--', color='r', lw=1.5, alpha=0.7, zorder=-4, label='') mctmp = tt0 * 0 for ii in range(len(tt0)): mctmp[ii] = np.sum(sfr[:ii] * deltt0 * 1e9) ax2.plot(np.max(age) - tt0, np.log10(mctmp*C_exp), marker='', linestyle='--', color='r', lw=1.5, alpha=0.7, zorder=-4) ax4.errorbar(t0, Zexp[1], yerr=[[Zexp[1]-Zexp[0]], [Zexp[2]-Zexp[1]]], marker='s', color='r', alpha=0.7, zorder=-4, capsize=0) sfr_exp = sfr mc_exp = mctmp*C_exp ''' # # Plot delay model? # DIR_exp = '/Users/tmorishita//Documents/Astronomy/sedfitter_del/' file = DIR_exp + 'summary_' + ID0 + '_PA' + PA + '.fits' hdul = fits.open(file) # open a FITS file t0 = 10**float(hdul[1].data['age'][0]) tau = 10**float(hdul[1].data['tau'][0]) A = float(hdul[1].data['A'][0]) Mdel= float(hdul[1].data['ms'][1]) tt0 = np.arange(0.01,10,0.01) sfr = SFH_del(np.max(age)-t0, tau, A, tt=tt0) mtmp = np.sum(sfr * deltt0 * 1e9) C_del = Mdel/mtmp ''' # # Mass in each bin # ax2label = '' ax2.fill_between(age[conA], np.log10(ACp[:,0])[conA], np.log10(ACp[:,2])[conA], linestyle='-', color='k', alpha=0.3) ax2.errorbar(age[conA], np.log10(ACp[:,1])[conA], xerr=[delTl[:][conA]/1e9,delTu[:][conA]/1e9], yerr=[np.log10(ACp[:,1])[conA]-np.log10(ACp[:,0])[conA],np.log10(ACp[:,2])[conA]-np.log10(ACp[:,1])[conA]], linestyle='-', color='k', lw=0.5, label=ax2label) ax2.scatter(age[conA], np.log10(ACp[:,1])[conA], marker='.', c='k', s=msize) y2min = np.max([lmmin,np.min(np.log10(ACp[:,0])[conA])]) y2max = np.max(np.log10(ACp[:,2])[conA])+0.05 if f_comp == 1: y2max = np.max([y2max, np.log10(np.max(mc_exp))+0.05]) y2min = np.min([y2min, np.log10(np.max(mc_exp))-0.05]) if (y2max-y2min)<0.2: y2min -= 0.2 # # Total Metal # ax4.fill_between(age[conA], ZCp[:,0][conA], ZCp[:,2][conA], linestyle='-', color='k', alpha=0.3) ax4.scatter(age[conA], ZCp[:,1][conA], marker='.', c='k', s=msize[conA]) ax4.errorbar(age[conA], ZCp[:,1][conA], yerr=[ZCp[:,1][conA]-ZCp[:,0][conA],ZCp[:,2][conA]-ZCp[:,1][conA]], linestyle='-', color='k', lw=0.5) fw_sfr = open('SFH_' + ID0 + '_PA' + PA + '.txt', 'w') fw_sfr.write('# time_l time_u SFR SFR16 SFR84\n') fw_sfr.write('# (Gyr) (Gyr) (M/yr) (M/yr) (M/yr)\n') fw_met = open('ZH_' + ID0 + '_PA' + PA + '.txt', 'w') fw_met.write('# time_l time_u logZ logZ16 logZ84\n') fw_met.write('# (Gyr) (Gyr) (logZsun) (logZsun) (logZsun)\n') for ii in range(len(age)-1,0-1,-1): t0 = Tuni/cc.Gyr_s - age[ii] fw_sfr.write('%.2f %.2f %.2f %.2f %.2f\n'%(t0-delTl[ii]/1e9, t0+delTl[ii]/1e9, SFp[ii,1], SFp[ii,0], SFp[ii,2])) fw_met.write('%.2f %.2f %.2f %.2f %.2f\n'%(t0-delTl[ii]/1e9, t0+delTl[ii]/1e9, ZCp[ii,1], ZCp[ii,0], ZCp[ii,2])) fw_sfr.close() fw_met.close() ######################### # Title ######################### #ax1.set_title('Each $t$-bin', fontsize=12) #ax2.set_title('Net system', fontsize=12) #ax3.set_title('Each $t$-bin', fontsize=12) #ax4.set_title('Net system', fontsize=12) ############# # Axis ############# #ax1.set_xlabel('$t$ (Gyr)', fontsize=12) ax1.set_ylabel('$\log \dot{M}_*/M_\odot$yr$^{-1}$', fontsize=12) #ax1.set_ylabel('$\log M_*/M_\odot$', fontsize=12) lsfru = 2.8 if np.max(np.log10(SFp[:,2]))>2.8: lsfru = np.max(np.log10(SFp[:,2]))+0.1 if f_comp == 1: lsfru = np.max([lsfru, np.log10(np.max(sfr_exp*C_exp))]) ax1.set_xlim(0.008, Txmax) ax1.set_ylim(lsfrl, lsfru) ax1.set_xscale('log') #ax2.set_xlabel('$t$ (Gyr)', fontsize=12) ax2.set_ylabel('$\log M_*/M_\odot$', fontsize=12) ax2.set_xlim(0.008, Txmax) ax2.set_ylim(y2min, y2max) ax2.set_xscale('log') ax2.text(0.01, y2min + 0.07*(y2max-y2min), 'ID: %s\n$z_\mathrm{obs.}:%.2f$\n$\log M_\mathrm{*}/M_\odot:%.2f$\n$\log Z_\mathrm{*}/Z_\odot:%.2f$\n$\log T_\mathrm{*}$/Gyr$:%.2f$\n$A_V$/mag$:%.2f$'%(ID0, zbes, np.log10(ACp[0,1]), ZCp[0,1], np.log10(np.percentile(TC[0,:],50)), Avtmp[1]), fontsize=9) # # Brief Summary # # Writing SED param in a fits file; # Header prihdr = fits.Header() prihdr['ID'] = ID0 prihdr['PA'] = PA prihdr['z'] = zbes prihdr['RA'] = RA prihdr['DEC'] = DEC prihdr['Re_kpc'] = rek prihdr['Ser_n'] = nn prihdr['Axis_q'] = qq prihdr['e_Re'] = (erekl+ereku)/2. prihdr['e_n'] = enn prihdr['e_q'] = eqq # Add rejuv properties; prihdr['f_rejuv']= f_rejuv prihdr['t_quen'] = t_quench prihdr['t_rejuv']= t_rejuv prihdu = fits.PrimaryHDU(header=prihdr) col01 = [] # Redshift zmc = hdul[1].data['zmc'] col50 = fits.Column(name='zmc', format='E', unit='', array=zmc[:]) col01.append(col50) # Stellar mass ACP = [np.log10(ACp[0,0]), np.log10(ACp[0,1]), np.log10(ACp[0,2])] col50 = fits.Column(name='Mstel', format='E', unit='logMsun', array=ACP[:]) col01.append(col50) # Metallicity_MW ZCP = [ZCp[0,0], ZCp[0,1], ZCp[0,2]] col50 = fits.Column(name='Z_MW', format='E', unit='logZsun', array=ZCP[:]) col01.append(col50) # Age_mw para = [np.log10(np.percentile(TC[0,:],16)), np.log10(np.percentile(TC[0,:],50)), np.log10(np.percentile(TC[0,:],84))] col50 = fits.Column(name='T_MW', format='E', unit='logGyr', array=para[:]) col01.append(col50) # Metallicity_LW ZCP = [ZL[0,0], ZL[0,1], ZL[0,2]] col50 = fits.Column(name='Z_LW', format='E', unit='logZsun', array=ZCP[:]) col01.append(col50) # Age_lw para = [np.log10(np.percentile(TL[0,:],16)), np.log10(np.percentile(TL[0,:],50)), np.log10(np.percentile(TL[0,:],84))] col50 = fits.Column(name='T_LW', format='E', unit='logGyr', array=para[:]) col01.append(col50) # Dust para = [Avtmp[0], Avtmp[1], Avtmp[2]] col50 = fits.Column(name='AV', format='E', unit='mag', array=para[:]) col01.append(col50) # U-V para = [uv[0], uv[1], uv[2]] col50 = fits.Column(name='U-V', format='E', unit='mag', array=para[:]) col01.append(col50) # V-J para = [vj[0], vj[1], vj[2]] col50 = fits.Column(name='V-J', format='E', unit='mag', array=para[:]) col01.append(col50) colms = fits.ColDefs(col01) dathdu = fits.BinTableHDU.from_columns(colms) hdu = fits.HDUList([prihdu, dathdu]) hdu.writeto('SFH_' + ID0 + '_PA' + PA + '_param.fits', overwrite=True) # # SFH # zzall = np.arange(1.,12,0.01) Tall = cd.age(zzall, use_flat=True, **cosmo)/cc.Gyr_s fw = open('SFH_' + ID0 + '_PA' + PA + '_sfh.cat', 'w') fw.write('%s'%(ID0)) for mm in range(len(age)): mmtmp = np.argmin(np.abs(Tall - Tuni0[mm])) zztmp = zzall[mmtmp] fw.write(' %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f'%(zztmp, Tuni0[mm], np.log10(ACp[mm,1]), (np.log10(ACp[mm,1])-np.log10(ACp[mm,0])), (np.log10(ACp[mm,2])-np.log10(ACp[mm,1])), ZCp[mm,1], ZCp[mm,1]-ZCp[mm,0], ZCp[mm,2]-ZCp[mm,1], SFp[mm,1], SFp[mm,1]-SFp[mm,0], SFp[mm,2]-SFp[mm,1])) fw.write('\n') fw.close() #print('%s & $%.5e$ & $%.5e$ & $%.3f$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.1f$ & $%.1f$ & $%.2f$\\\\'%(ID0, RA, DEC, zbes, np.log10(ACp[0,1]), (np.log10(ACp[0,1])-np.log10(ACp[0,0])), (np.log10(ACp[0,2])-np.log10(ACp[0,1])), ACp[7,1]/ACp[0,1], ACp[7,1]/ACp[0,1]-ACp[7,0]/ACp[0,1], ACp[7,2]/ACp[0,1]-ACp[7,1]/ACp[0,1], ZCp[0,1], ZCp[0,1]-ZCp[0,0], ZCp[0,2]-ZCp[0,1], np.percentile(TC[0,:],50), np.percentile(TC[0,:],50)-np.percentile(TC[0,:],16), np.percentile(TC[0,:],84)-np.percentile(TC[0,:],50), Avtmp[1], Avtmp[1]-Avtmp[0], Avtmp[2]-Avtmp[1], uv[1], uv[1]-uv[0], uv[2]-uv[1], vj[1], vj[1]-vj[0], vj[2]-vj[1], chinu[1], SN, rek)) dely2 = 0.1 while (y2max-y2min)/dely2>7: dely2 *= 2. y2ticks = np.arange(y2min, y2max, dely2) ax2.set_yticks(y2ticks) ax2.set_yticklabels(np.arange(y2min, y2max, 0.1), minor=False) ax2.yaxis.set_major_formatter(FormatStrFormatter('%.1f')) #ax2.yaxis.set_major_locator(plt.MaxNLocator(4)) #ax3.set_xlabel('$t$ (Gyr)', fontsize=12) #ax3.set_ylabel('$\log Z_*/Z_\odot$', fontsize=12) y3min, y3max = np.min(Z), np.max(Z) #ax3.set_xlim(0.008, Txmax) #ax3.set_ylim(y3min, y3max) #ax3.set_xscale('log') #ax3.yaxis.set_major_formatter(FormatStrFormatter('%.2f')) fwt = open('T_' + ID0 + '_PA' + PA + '_sfh.cat', 'w') fwt.write('%s %.3f %.3f %.3f'%(ID0, np.percentile(TC[0,:],50), np.percentile(TC[0,:],16), np.percentile(TC[0,:],84))) fwt.close() # For redshift if zbes<4: if zbes<2: zred = [zbes, 2, 3, 6] #zredl = ['$z_\mathrm{obs.}$', 2, 3, 6] zredl = ['$z_\mathrm{obs.}$', 2, 3, 6] elif zbes<2.5: zred = [zbes, 2.5, 3, 6] zredl = ['$z_\mathrm{obs.}$', 2.5, 3, 6] elif zbes<3.: zred = [zbes, 3, 6] zredl = ['$z_\mathrm{obs.}$', 3, 6] else: zred = [zbes, 6] zredl = ['$z_\mathrm{obs.}$', 6] else: zred = [zbes, 6, 7, 9] zredl = ['$z_\mathrm{obs.}$', 6, 7, 9] Tzz = np.zeros(len(zred), dtype='float32') for zz in range(len(zred)): Tzz[zz] = (Tuni - cd.age(zred[zz], use_flat=True, **cosmo))/cc.Gyr_s if Tzz[zz] < 0.01: Tzz[zz] = 0.01 #print(zred, Tzz) #ax3t.set_xscale('log') #ax3t.set_xlim(0.008, Txmax) ax1.set_xlabel('$t_\mathrm{lookback}$/Gyr', fontsize=12) ax2.set_xlabel('$t_\mathrm{lookback}$/Gyr', fontsize=12) ax4.set_xlabel('$t_\mathrm{lookback}$/Gyr', fontsize=12) ax4.set_ylabel('$\log Z_*/Z_\odot$', fontsize=12) ax1t.set_xscale('log') ax1t.set_xlim(0.008, Txmax) ax2t.set_xscale('log') ax2t.set_xlim(0.008, Txmax) ax4t.set_xscale('log') ax4t.set_xlim(0.008, Txmax) ax4.set_xlim(0.008, Txmax) ax4.set_ylim(y3min-0.05, y3max) ax4.set_xscale('log') ax4.set_yticks([-0.8, -0.4, 0., 0.4]) ax4.set_yticklabels(['-0.8', '-0.4', '0', '0.4']) #ax4.yaxis.set_major_formatter(FormatStrFormatter('%.2f')) #ax3.yaxis.labelpad = -2 ax4.yaxis.labelpad = -2 ax1t.set_xticklabels(zredl[:]) ax1t.set_xticks(Tzz[:]) ax1t.tick_params(axis='x', labelcolor='k') ax1t.xaxis.set_ticks_position('none') #ax1t.plot(Tzz, Tzz*0+y3max+(y3max-y3min)*.00, marker='|', color='k', ms=3, linestyle='None') ax2t.set_xticklabels(zredl[:]) ax2t.set_xticks(Tzz[:]) ax2t.tick_params(axis='x', labelcolor='k') ax2t.xaxis.set_ticks_position('none') #ax2t.plot(Tzz, Tzz*0+y3max+(y3max-y3min)*.00, marker='|', color='k', ms=3, linestyle='None') ax4t.set_xticklabels(zredl[:]) ax4t.set_xticks(Tzz[:]) ax4t.tick_params(axis='x', labelcolor='k') ax4t.xaxis.set_ticks_position('none') ax4t.plot(Tzz, Tzz*0+y3max+(y3max-y3min)*.00, marker='|', color='k', ms=3, linestyle='None') ax1.plot(Tzz, Tzz*0+lsfru+(lsfru-lsfrl)*.00, marker='|', color='k', ms=3, linestyle='None') ax2.plot(Tzz, Tzz*0+y2max+(y2max-y2min)*.00, marker='|', color='k', ms=3, linestyle='None') #################### ## Save #################### #plt.show() #ax1.legend(loc=2, fontsize=8) #ax2.legend(loc=3, fontsize=8) plt.savefig('SFH_' + ID0 + '_PA' + PA + '_pcl.png')
def plot_evolv(ID0, PA, Z=np.arange(-1.2,0.4249,0.05), age=[0.01, 0.1, 0.3, 0.7, 1.0, 3.0], f_comp = 0, fil_path = './FILT/', inputs=None, dust_model=0, DIR_TMP='./templates/', delt_sfh = 0.01, nmc=300): # # delt_sfh (float): delta t of input SFH in Gyr. # # Returns: SED as function of age, based on SF and Z histories; # ################ flim = 0.01 lsfrl = -1 # log SFR low limit mmax = 1000 Txmax = 4 # Max x value lmmin = 10.3 nage = np.arange(0,len(age),1) fnc = Func(Z, nage, dust_model=dust_model) # Set up the number of Age/ZZ bfnc = Basic(Z) age = np.asarray(age) ################ # RF colors. import os.path home = os.path.expanduser('~') c = 3.e18 # A/s chimax = 1. mag0 = 25.0 d = 10**(73.6/2.5) * 1e-18 # From [ergs/s/cm2/A] to [ergs/s/cm2/Hz] ############# # Plot. ############# fig = plt.figure(figsize=(5,2.6)) fig.subplots_adjust(top=0.96, bottom=0.16, left=0.12, right=0.99, hspace=0.15, wspace=0.15) #ax1 = fig.add_subplot(131) #ax2 = fig.add_subplot(132) #ax3 = fig.add_subplot(133) ax2 = fig.add_subplot(121) ax3 = fig.add_subplot(122) ########################### # Open result file ########################### file = 'summary_' + ID0 + '_PA' + PA + '.fits' hdul = fits.open(file) # open a FITS file zbes = hdul[0].header['z'] chinu= hdul[1].data['chi'] uv= hdul[1].data['uv'] vj= hdul[1].data['vj'] try: RA = hdul[0].header['RA'] DEC = hdul[0].header['DEC'] except: RA = 0 DEC = 0 try: SN = hdul[0].header['SN'] except: ########################### # Get SN of Spectra ########################### file = 'templates/spec_obs_' + ID0 + '_PA' + PA + '.cat' fds = np.loadtxt(file, comments='#') nrs = fds[:,0] lams = fds[:,1] fsp = fds[:,2] esp = fds[:,3] consp = (nrs<10000) & (lams/(1.+zbes)>3600) & (lams/(1.+zbes)<4200) if len((fsp/esp)[consp]>10): SN = np.median((fsp/esp)[consp]) else: SN = 1 Asum = 0 A50 = np.arange(len(age), dtype='float32') for aa in range(len(A50)): A50[aa] = hdul[1].data['A'+str(aa)][1] Asum += A50[aa] # Cosmo; DL = cd.luminosity_distance(zbes, **cosmo) * Mpc_cm # Luminositydistance in cm Cons = (4.*np.pi*DL**2/(1.+zbes)) Tuni = cd.age(zbes, use_flat=True, **cosmo) Tuni0 = (Tuni/cc.Gyr_s - age[:]) # Open summary; file = 'summary_' + ID0 + '_PA' + PA + '.fits' fd = fits.open(file)[1].data #print(fits.open(file)[1].header) Avtmp = fd['Av0'] uvtmp = fd['uv'] vjtmp = fd['vj'] #ax2.plot(vj[1],uv[1],color='gray',marker='s',ms=3) # SFH file = DIR_TMP + 'obshist_' + ID0 + '_PA' + PA + '.fits' fd = fits.open(file)[1].data age = fd['age'] sfh = fd['sfh'] zh = fd['zh'] # Open FSPS temp; file = DIR_TMP + 'obsspec_' + ID0 + '_PA' + PA + '.fits' fd = fits.open(file)[1].data wave = fd['wavelength'] nr = fd['colnum'] uvall= age * 0 - 99 vjall= age * 0 - 99 delp = -10 flag = False flag2= False #for ii in range(1,len(age),10): for ii in range(len(age)-1,-1,delp): flux = fd['fspec_%d'%(ii)] flux_att = madau_igm_abs(wave/(1.+zbes), flux, zbes) flux_d, xxd, nrd = dust_calz(wave/(1.+zbes), flux_att, 0.0, nr) #ax1.plot(xxd,flux_d,linestyle='-',lw=0.3+0.1*ii/len(age)) band0 = ['u','v','j'] lmconv,fconv = filconv(band0, xxd, flux_d, fil_path) # flux in fnu uv = -2.5*np.log10(fconv[0]/fconv[1]) vj = -2.5*np.log10(fconv[1]/fconv[2]) uvall[ii] = uv vjall[ii] = vj #ax2.plot(vjall[ii],uvall[ii],marker='s',ms=5,linestyle='-',zorder=5) if flag and not flag2: flux_d, xxd, nrd = dust_calz(wave/(1.+zbes), flux_att, Avtmp[1], nr) lmconv,fconv = filconv(band0, xxd, flux_d, fil_path) # flux in fnu uv_av = -2.5*np.log10(fconv[0]/fconv[1]) vj_av = -2.5*np.log10(fconv[1]/fconv[2]) delvj, deluv = vj_av-vj, uv_av-uv flag2 = True flag = True #import matplotlib.colormaps as cm conuvj = (vjall>-90)&(uvall>-90) ax2.plot(vjall[conuvj],uvall[conuvj],marker='s',markeredgecolor='k',color='none',ms=5,zorder=4) ax2.scatter(vjall[conuvj],uvall[conuvj],marker='s',c=age[conuvj],cmap='jet',s=8,zorder=5) ax2.plot(vjall[conuvj],uvall[conuvj],marker='',color='k',ms=3,linestyle='-',zorder=3) ax3.plot(age,np.log10(sfh),color='b', linewidth=1, linestyle='-',label=r'$\log$SFR$/M_\odot$yr$^{-1}$') ax3.plot(age,zh,color='r', linewidth=1, linestyle='-',label=r'$\log Z_*/Z_\odot$') ''' ax1.set_xlim(1000,40000) ax1.set_xscale('log') ax1.set_ylim(1e-2,1e2) ax1.set_yscale('log') ax1.set_xlabel('Wavelength') ''' ax2.set_xlim(-0.3,2.3) ax2.set_ylim(-0.3,2.3) ax2.set_xlabel('$V-J\,$/ mag') ax2.set_ylabel('$U-V\,$/ mag') ax3.set_xlabel('age / Gyr') #ax3.set_ylabel('$\log$SFR$/M_\odot$yr$^{-1}$ or $\log Z_*/Z_\odot$') ## prog_path = '/Users/tmorishita/GitHub/gsf/gsf/example/misc/' data_uvj = np.loadtxt(prog_path+'f2.cat',comments='#') x=data_uvj[:,0] y=data_uvj[:,1] ax2.plot(x,y,color="gray",lw=1,ls="-") data_uvj = np.loadtxt(prog_path+'g2.cat',comments='#') x=data_uvj[:,0] y=data_uvj[:,1] ax2.plot(x,y,color="gray",lw=1,ls="-") data_uvj = np.loadtxt(prog_path+'h2.cat',comments='#') x=data_uvj[:,0] y=data_uvj[:,1] ax2.plot(x,y,color="gray",lw=1,ls="-") try: av=np.array([1.2,0.,delvj,deluv]) X,Y,U,V=zip(av) ax2.quiver(X,Y,U,V,angles='xy',scale_units='xy',scale=1,linewidth=1,color="k") except: pass ax2.text(-0.1,2.1,'Quiescent',fontsize=11,color='orangered') ax2.text(1.3,-0.2,'Starforming',fontsize=11,color='royalblue') ax3.legend(loc=3) #plt.show() plt.savefig('hist_' + ID0 + '_PA' + PA + '.pdf')
def plotLFevo( hist=None, params=B2008, extrap_var='t', #maglim = -21.07 - 2.5 * numpy.log10(0.2)): maglim=-21. - 2.5 * numpy.log10(0.2), z_max=20.0, skipIon=True): """Plot evolution of luminosity function params and total luminsity. Schechter function at each redshift is integrated up to maglim to find total luminsity. """ for (k, v) in params.iteritems(): params[k] = numpy.asarray(v) if hist is None: cosmo = cp.WMAP7_BAO_H0_mean(flat=True) hist = LFHistory(params, extrap_var=extrap_var, **cosmo) else: params = hist.params extrap_var = hist.extrap_var cosmo = hist.cosmo z = params['z'] t = cd.age(z, **cosmo)[0] / cc.yr_s MStar = params['MStar'] phiStar = params['phiStar'] alpha = params['alpha'] if maglim is None: ltot = schechterTotLM(MStar=MStar, phiStar=phiStar, alpha=alpha) else: ltot = schechterCumuLM(magnitudeAB=maglim, MStar=MStar, phiStar=phiStar, alpha=alpha) print(hist._MStarfunc.extrap_string()) zPlot = numpy.arange(z.min() - 0.1, z_max, 0.1) tPlot = cd.age(zPlot, **cosmo)[0] / cc.yr_s newparams = hist.params_z(zPlot) MPlot = newparams['MStar'] phiPlot = newparams['phiStar'] alphaPlot = newparams['alpha'] if maglim is None: ltotPlot = hist.schechterTotLM(zPlot) else: ltotPlot = hist.schechterCumuLM(zPlot, magnitudeAB=maglim) # From Table 6 of 2008ApJ...686..230B lB2008 = 10.**numpy.array([26.18, 25.85, 25.72, 25.32, 25.14]) iPhot = hist.iPhotonRateDensity_z(zPlot, maglim=maglim) # iPhotFunc = lambda t1: cc.yr_s * hist.iPhotonRateDensity_t(t1, # maglim=maglim) if not skipIon: xH = hist.ionization(zPlot, maglim) import pylab pylab.figure(1) pylab.gcf().set_label('LFion_vs_z') if skipIon: pylab.subplot(111) else: pylab.subplot(211) pylab.plot(zPlot, iPhot) if not skipIon: pylab.subplot(212) pylab.plot(zPlot, xH) pylab.ylim(0.0, 1.5) pylab.figure(2) pylab.gcf().set_label('LFparams_vs_z') pylab.subplot(311) pylab.plot(z, MStar, '-') pylab.plot(z, MStar, 'o') pylab.plot(zPlot, MPlot, ':') pylab.subplot(312) pylab.plot(z, phiStar, '-') pylab.plot(z, phiStar, 'o') pylab.plot(zPlot, phiPlot, ':') pylab.subplot(313) pylab.plot(z, alpha, '-') pylab.plot(z, alpha, 'o') pylab.plot(zPlot, alphaPlot, ':') pylab.figure(3) pylab.gcf().set_label('LFparams_vs_t') pylab.subplot(311) pylab.plot(t, MStar, '-') pylab.plot(t, MStar, 'o') pylab.plot(tPlot, MPlot, ':') pylab.subplot(312) pylab.plot(t, phiStar, '-') pylab.plot(t, phiStar, '.') pylab.plot(tPlot, phiPlot, ':') pylab.subplot(313) pylab.plot(t, alpha, '-') pylab.plot(t, alpha, 'o') pylab.plot(tPlot, alphaPlot, ':') pylab.figure(4) pylab.gcf().set_label('LFlum_vs_z') pylab.subplot(121) pylab.plot(z, ltot, 'o') pylab.plot(z, lB2008, 'x') pylab.plot(zPlot, ltotPlot) pylab.subplot(122) pylab.plot(t, ltot, 'o') pylab.plot(t, lB2008, 'x') pylab.plot(tPlot, ltotPlot)
def main(self, ID0, PA0, zgal, flag_m, zprev, Cz0, Cz1, mcmcplot=True, fzvis=1, specplot=1, fneld=0, ntemp=5, sigz=1.0, ezmin=0.01, f_move=False, f_disp=False ): # flag_m related to redshift error in redshift check func. # # sigz (float): confidence interval for redshift fit. # ezmin (float): minimum error in redshift. # print('########################') print('### Fitting Function ###') print('########################') start = timeit.default_timer() inputs = self.inputs DIR_TMP = inputs['DIR_TEMP'] if os.path.exists(DIR_TMP) == False: os.mkdir(DIR_TMP) # For error parameter ferr = 0 # # Age # age = inputs['AGE'] age = [float(x.strip()) for x in age.split(',')] nage = np.arange(0, len(age), 1) # # Metallicity # Zmax, Zmin = float(inputs['ZMAX']), float(inputs['ZMIN']) delZ = float(inputs['DELZ']) Zall = np.arange(Zmin, Zmax, delZ) # in logZsun # For minimizer. delZtmp = delZ #delZtmp = 0.4 # to increase speed. # For z prior. delzz = 0.001 zlimu = 6. snlim = 1 zliml = zgal - 0.5 agemax = cd.age(zgal, use_flat=True, **cosmo) / cc.Gyr_s # N of param: try: ndim = int(inputs['NDIM']) print('No of params are : %d' % (ndim)) except: if int(inputs['ZEVOL']) == 1: ndim = int(len(nage) * 2 + 1) print('Metallicity evolution is on.') if int(inputs['ZMC']) == 1: ndim += 1 print('No of params are : %d' % (ndim)) else: ndim = int(len(nage) + 1 + 1) print('Metallicity evolution is off.') if int(inputs['ZMC']) == 1: ndim += 1 print('No of params are : %d' % (ndim)) pass # # Line # LW0 = inputs['LINE'] LW0 = [float(x.strip()) for x in LW0.split(',')] # # Params for MCMC # nmc = int(inputs['NMC']) nwalk = int(inputs['NWALK']) nmc_cz = int(inputs['NMCZ']) nwalk_cz = int(inputs['NWALKZ']) f_Zevol = int(inputs['ZEVOL']) #f_zvis = int(inputs['ZVIS']) try: fzmc = int(inputs['ZMC']) except: fzmc = 0 # # If FIR data; # try: DT0 = float(inputs['TDUST_LOW']) DT1 = float(inputs['TDUST_HIG']) dDT = float(inputs['TDUST_DEL']) Temp = np.arange(DT0, DT1, dDT) f_dust = True print('FIR fit is on.') except: f_dust = False pass # # Tau for MCMC parameter; not as fitting parameters. # tau0 = inputs['TAU0'] tau0 = [float(x.strip()) for x in tau0.split(',')] # # Dust model specification; # try: dust_model = int(inputs['DUST_MODEL']) except: dust_model = 0 from .function_class import Func from .basic_func import Basic fnc = Func(Zall, nage, dust_model=dust_model, DIR_TMP=DIR_TMP) # Set up the number of Age/ZZ bfnc = Basic(Zall) # Open ascii file and stock to array. #lib = open_spec(ID0, PA0) lib = fnc.open_spec_fits(ID0, PA0, fall=0, tau0=tau0) lib_all = fnc.open_spec_fits(ID0, PA0, fall=1, tau0=tau0) if f_dust: lib_dust = fnc.open_spec_dust_fits(ID0, PA0, Temp, fall=0, tau0=tau0) lib_dust_all = fnc.open_spec_dust_fits(ID0, PA0, Temp, fall=1, tau0=tau0) ################# # Observed Data ################# ############## # Spectrum ############## dat = np.loadtxt(DIR_TMP + 'spec_obs_' + ID0 + '_PA' + PA0 + '.cat', comments='#') NR = dat[:, 0] x = dat[:, 1] fy00 = dat[:, 2] ey00 = dat[:, 3] con0 = (NR < 1000) fy0 = fy00[con0] * Cz0 ey0 = ey00[con0] * Cz0 con1 = (NR >= 1000) & (NR < 10000) fy1 = fy00[con1] * Cz1 ey1 = ey00[con1] * Cz1 # BB data in spec_obs are not in use. #con2 = (NR>=10000) # BB #fy2 = fy00[con2] #ey2 = ey00[con2] ############## # Broadband ############## dat = np.loadtxt(DIR_TMP + 'bb_obs_' + ID0 + '_PA' + PA0 + '.cat', comments='#') NRbb = dat[:, 0] xbb = dat[:, 1] fybb = dat[:, 2] eybb = dat[:, 3] exbb = dat[:, 4] fy2 = fybb ey2 = eybb fy01 = np.append(fy0, fy1) fy = np.append(fy01, fy2) ey01 = np.append(ey0, ey1) ey = np.append(ey01, ey2) wht = 1. / np.square(ey) wht2 = check_line_man(fy, x, wht, fy, zprev, LW0) sn = fy / ey ##################### # Function fo MCMC ##################### def residual( pars, fy, wht2, f_fir, out=False): # x, y, wht are taken from out of the definition. # # Returns: residual of model and data. # out: model as second output. For lnprob func. # f_fir: syntax. If dust component is on or off. vals = pars.valuesdict() model, x1 = fnc.tmp04(ID0, PA0, vals, zprev, lib, tau0=tau0) if f_fir: model_dust, x1_dust = fnc.tmp04_dust(ID0, PA0, vals, zprev, lib_dust, tau0=tau0) n_optir = len(model) # Add dust flux to opt/IR grid. model[:] += model_dust[:n_optir] #print(model_dust) # then append only FIR flux grid. model = np.append(model, model_dust[n_optir:]) x1 = np.append(x1, x1_dust[n_optir:]) #plt.plot(x1,model,'r.') #plt.show() if ferr == 1: f = vals['f'] else: f = 0 # temporary... (if f is param, then take from vals dictionary.) con_res = (model > 0) & (wht2 > 0) #& (fy>0) sig = np.sqrt(1. / wht2 + f**2 * model**2) ''' contmp = x1>1e6 & (wht2>0) try: print(x1[contmp],model[contmp],fy[contmp],np.log10(vals['MDUST'])) except: pass ''' if not out: if fy is None: print('Data is none') return model[con_res] else: return (model - fy)[con_res] / sig[ con_res] # i.e. residual/sigma. Because is_weighted = True. if out: if fy is None: print('Data is none') return model[con_res], model else: return (model - fy)[con_res] / sig[ con_res], model # i.e. residual/sigma. Because is_weighted = True. def lnprob(pars, fy, wht2, f_fir): # # Returns: posterior. # vals = pars.valuesdict() if ferr == 1: f = vals['f'] else: f = 0 # temporary... (if f is param, then take from vals dictionary.) resid, model = residual(pars, fy, wht2, f_fir, out=True) con_res = (model > 0) & (wht2 > 0) sig = np.sqrt(1. / wht2 + f**2 * model**2) lnlike = -0.5 * np.sum(resid**2 + np.log(2 * 3.14 * sig[con_res]**2)) #print(np.log(2 * 3.14 * 1) * len(sig[con_res]), np.sum(np.log(2 * 3.14 * sig[con_res]**2))) #Av = vals['Av'] #if Av<0: # return -np.inf #else: # respr = 0 #np.log(1) respr = 0 # Flat prior... return lnlike + respr ############################### # Add parameters ############################### fit_params = Parameters() for aa in range(len(age)): if age[aa] == 99 or age[aa] > agemax: fit_params.add('A' + str(aa), value=0, min=0, max=1e-10) else: fit_params.add('A' + str(aa), value=1, min=0, max=1e3) ##################### # Dust attenuation ##################### try: Avmin = float(inputs['AVMIN']) Avmax = float(inputs['AVMAX']) fit_params.add('Av', value=Avmin, min=Avmin, max=Avmax) except: fit_params.add('Av', value=0.2, min=0, max=4.0) ##################### # Metallicity ##################### if int(inputs['ZEVOL']) == 1: for aa in range(len(age)): if age[aa] == 99 or age[aa] > agemax: fit_params.add('Z' + str(aa), value=0, min=0, max=1e-10) else: fit_params.add('Z' + str(aa), value=0, min=np.min(Zall), max=np.max(Zall)) elif inputs['ZFIX']: #print('Z is fixed') ZFIX = float(inputs['ZFIX']) aa = 0 fit_params.add('Z' + str(aa), value=0, min=ZFIX, max=ZFIX + 0.01) else: aa = 0 fit_params.add('Z' + str(aa), value=0, min=np.min(Zall), max=np.max(Zall)) #################################### # Initial Metallicity Determination #################################### chidef = 1e5 Zbest = 0 fwz = open('Z_' + ID0 + '_PA' + PA0 + '.cat', 'w') fwz.write('# ID Zini chi/nu AA Av Zbest\n') fwz.write('# FNELD = %d\n' % fneld) nZtmp = int((Zmax - Zmin) / delZtmp) ZZtmp = np.arange(Zmin, Zmax, delZtmp) # How to get initial parameters? # Nelder; if fneld == 1: fit_name = 'nelder' for zz in range(len(ZZtmp)): ZZ = ZZtmp[zz] if int(inputs['ZEVOL']) == 1: for aa in range(len(age)): fit_params['Z' + str(aa)].value = ZZ else: aa = 0 fit_params['Z' + str(aa)].value = ZZ out_tmp = minimize( residual, fit_params, args=(fy, wht2, False), method=fit_name) # nelder is the most efficient. keys = fit_report(out_tmp).split('\n') csq = 99999 rcsq = 99999 for key in keys: if key[4:7] == 'chi': skey = key.split(' ') csq = float(skey[14]) if key[4:7] == 'red': skey = key.split(' ') rcsq = float(skey[7]) fitc = [csq, rcsq] # Chi2, Reduced-chi2 fwz.write('%s %.2f %.5f' % (ID0, ZZ, fitc[1])) AA_tmp = np.zeros(len(age), dtype='float32') ZZ_tmp = np.zeros(len(age), dtype='float32') for aa in range(len(age)): AA_tmp[aa] = out_tmp.params['A' + str(aa)].value fwz.write(' %.5f' % (AA_tmp[aa])) Av_tmp = out_tmp.params['Av'].value fwz.write(' %.5f' % (Av_tmp)) if int(inputs['ZEVOL']) == 1: for aa in range(len(age)): ZZ_tmp[aa] = out_tmp.params['Z' + str(aa)].value fwz.write(' %.5f' % (ZZ_tmp[aa])) else: aa = 0 ZZ_tmp[aa] = out_tmp.params['Z' + str(aa)].value fwz.write(' %.5f' % (ZZ_tmp[aa])) fwz.write('\n') if fitc[1] < chidef: chidef = fitc[1] out = out_tmp # Or # Powell; else: fit_name = 'powell' for zz in range(0, nZtmp, 2): ZZ = zz * delZtmp + np.min(Zall) if int(inputs['ZEVOL']) == 1: for aa in range(len(age)): fit_params['Z' + str(aa)].value = ZZ else: aa = 0 fit_params['Z' + str(aa)].value = ZZ out_tmp = minimize( residual, fit_params, args=(fy, wht2, False), method=fit_name) # powel is the more accurate. keys = fit_report(out_tmp).split('\n') csq = 99999 rcsq = 99999 for key in keys: if key[4:7] == 'chi': skey = key.split(' ') csq = float(skey[14]) if key[4:7] == 'red': skey = key.split(' ') rcsq = float(skey[7]) fitc = [csq, rcsq] # Chi2, Reduced-chi2 fwz.write('%s %.2f %.5f' % (ID0, ZZ, fitc[1])) AA_tmp = np.zeros(len(age), dtype='float32') ZZ_tmp = np.zeros(len(age), dtype='float32') for aa in range(len(age)): AA_tmp[aa] = out_tmp.params['A' + str(aa)].value fwz.write(' %.5f' % (AA_tmp[aa])) Av_tmp = out_tmp.params['Av'].value fwz.write(' %.5f' % (Av_tmp)) if int(inputs['ZEVOL']) == 1: for aa in range(len(age)): ZZ_tmp[aa] = out_tmp.params['Z' + str(aa)].value fwz.write(' %.5f' % (ZZ_tmp[aa])) else: aa = 0 fwz.write(' %.5f' % (ZZ_tmp[aa])) fwz.write('\n') if fitc[1] < chidef: chidef = fitc[1] out = out_tmp # # Best fit # keys = fit_report(out).split('\n') for key in keys: if key[4:7] == 'chi': skey = key.split(' ') csq = float(skey[14]) if key[4:7] == 'red': skey = key.split(' ') rcsq = float(skey[7]) fitc = [csq, rcsq] # Chi2, Reduced-chi2 #fitc = fit_report_chi(out) # Chi2, Reduced-chi2 ZZ = Zbest # This is really important/does affect lnprob/residual. print('\n\n') print('#####################################') print('Zbest, chi are;', Zbest, chidef) print('Params are;', fit_report(out)) print('#####################################') print('\n\n') fwz.close() Av_tmp = out.params['Av'].value AA_tmp = np.zeros(len(age), dtype='float32') ZZ_tmp = np.zeros(len(age), dtype='float32') fm_tmp, xm_tmp = fnc.tmp04_val(ID0, PA0, out, zprev, lib, tau0=tau0) ######################## # Check redshift ######################## zrecom = zprev # Observed data. con_cz = (NR < 10000) #& (sn>snlim) fy_cz = fy[con_cz] ey_cz = ey[con_cz] x_cz = x[con_cz] # Observed range NR_cz = NR[con_cz] xm_s = xm_tmp / (1 + zprev) * (1 + zrecom) fm_s = np.interp(x_cz, xm_s, fm_tmp) if fzvis == 1: plt.plot(x_cz / (1 + zprev) * (1. + zrecom), fm_s, 'gray', linestyle='--', linewidth=0.5, label='Default ($z=%.5f$)' % (zprev)) # Model based on input z. plt.plot(x_cz, fy_cz, 'b', linestyle='-', linewidth=0.5, label='Obs.') # Observation plt.errorbar(x_cz, fy_cz, yerr=ey_cz, color='b', capsize=0, linewidth=0.5) # Observation if flag_m == 0: dez = 0.5 else: dez = 0.2 # # For Eazy # ''' dprob = np.loadtxt(eaz_path + 'photz_' + str(int(ID0)) + '.pz', comments='#') zprob = dprob[:,0] cprob = dprob[:,1] zz_prob = np.arange(0,13,delzz) cprob_s = np.interp(zz_prob, zprob, cprob) prior_s = 1/cprob_s prior_s /= np.sum(prior_s) ''' zz_prob = np.arange(0, 13, delzz) prior_s = zz_prob * 0 + 1. prior_s /= np.sum(prior_s) try: print('############################') print('Start MCMC for redshift fit') print('############################') res_cz, fitc_cz = check_redshift(fy_cz, ey_cz, x_cz, fm_tmp, xm_tmp / (1 + zprev), zprev, dez, prior_s, NR_cz, zliml, zlimu, delzz, nmc_cz, nwalk_cz) z_cz = np.percentile(res_cz.flatchain['z'], [16, 50, 84]) scl_cz0 = np.percentile(res_cz.flatchain['Cz0'], [16, 50, 84]) scl_cz1 = np.percentile(res_cz.flatchain['Cz1'], [16, 50, 84]) zrecom = z_cz[1] Czrec0 = scl_cz0[1] Czrec1 = scl_cz1[1] # Switch to peak redshift: from scipy import stats from scipy.stats import norm # find minimum and maximum of xticks, so we know # where we should compute theoretical distribution ser = res_cz.flatchain['z'] xmin, xmax = zprev - 0.2, zprev + 0.2 lnspc = np.linspace(xmin, xmax, len(ser)) print('\n\n') print( 'Recommended redshift, Cz0 and Cz1, %.5f %.5f %.5f, with chi2/nu=%.3f' % (zrecom, Cz0 * Czrec0, Cz1 * Czrec1, fitc_cz[1])) print('\n\n') except: print('z fit failed. No spectral data set?') try: ezl = float(inputs['EZL']) ezu = float(inputs['EZU']) print('Redshift error is taken from input file.') if ezl < ezmin: ezl = ezmin #0.03 if ezu < ezmin: ezu = ezmin #0.03 except: ezl = ezmin ezu = ezmin print('Redshift error is assumed to %.1f.' % (ezl)) z_cz = [zprev - ezl, zprev, zprev + ezu] zrecom = z_cz[1] scl_cz0 = [1., 1., 1.] scl_cz1 = [1., 1., 1.] Czrec0 = scl_cz0[1] Czrec1 = scl_cz1[1] ''' try: # lets try the normal distribution first m, s = stats.norm.fit(ser) # get mean and standard deviation pdf_g = stats.norm.pdf(lnspc, m, s) # now get theoretical values in our interval z_cz[:] = [m-s, m, m+s] zrecom = z_cz[1] f_fitgauss = 1 except: print('Guassian fitting to z distribution failed.') f_fitgauss=0 ''' f_fitgauss = 0 xm_s = xm_tmp / (1 + zprev) * (1 + zrecom) fm_s = np.interp(x_cz, xm_s, fm_tmp) whtl = 1 / np.square(ey_cz) try: wht3, ypoly = check_line_cz_man(fy_cz, x_cz, whtl, fm_s, zrecom, LW0) except: wht3, ypoly = whtl, fy_cz con_line = (wht3 == 0) if fzvis == 1: plt.plot(x_cz, fm_s, 'r', linestyle='-', linewidth=0.5, label='Updated model ($z=%.5f$)' % (zrecom)) # Model based on recomended z. plt.plot(x_cz[con_line], fm_s[con_line], color='orange', marker='o', linestyle='', linewidth=3.) # Plot lines for reference for ll in range(len(LW)): try: conpoly = (x_cz / (1. + zrecom) > 3000) & (x_cz / (1. + zrecom) < 8000) yline = np.max(ypoly[conpoly]) yy = np.arange(yline / 1.02, yline * 1.1) xxpre = yy * 0 + LW[ll] * (1. + zprev) xx = yy * 0 + LW[ll] * (1. + zrecom) plt.plot(xxpre, yy / 1.02, linewidth=0.5, linestyle='--', color='gray') plt.text(LW[ll] * (1. + zprev), yline / 1.05, '%s' % (LN[ll]), fontsize=8, color='gray') plt.plot(xx, yy, linewidth=0.5, linestyle='-', color='orangered') plt.text(LW[ll] * (1. + zrecom), yline, '%s' % (LN[ll]), fontsize=8, color='orangered') except: pass plt.plot(xbb, fybb, '.r', linestyle='', linewidth=0, zorder=4, label='Obs.(BB)') plt.plot(xm_tmp, fm_tmp, color='gray', marker='.', ms=0.5, linestyle='', linewidth=0.5, zorder=4, label='Model') try: xmin, xmax = np.min(x_cz) / 1.1, np.max(x_cz) * 1.1 except: xmin, xmax = 2000, 10000 plt.xlim(xmin, xmax) try: plt.ylim(0, yline * 1.1) except: pass plt.xlabel('Wavelength ($\mathrm{\AA}$)') plt.ylabel('$F_\\nu$ (arb.)') plt.legend(loc=0) zzsigma = ((z_cz[2] - z_cz[0]) / 2.) / zprev zsigma = np.abs(zprev - zrecom) / (zprev) C0sigma = np.abs(Czrec0 - Cz0) / Cz0 eC0sigma = ((scl_cz0[2] - scl_cz0[0]) / 2.) / Cz0 C1sigma = np.abs(Czrec1 - Cz1) / Cz1 eC1sigma = ((scl_cz1[2] - scl_cz1[0]) / 2.) / Cz1 print('Input redshift is %.3f per cent agreement.' % ((1. - zsigma) * 100)) print('Error is %.3f per cent.' % (zzsigma * 100)) print('Input Cz0 is %.3f per cent agreement.' % ((1. - C0sigma) * 100)) print('Error is %.3f per cent.' % (eC0sigma * 100)) print('Input Cz1 is %.3f per cent agreement.' % ((1. - C1sigma) * 100)) print('Error is %.3f per cent.' % (eC1sigma * 100)) plt.show() # # Ask interactively; # flag_z = raw_input( 'Do you want to continue with original redshift, Cz0 and Cz1, %.5f %.5f %.5f? ([y]/n/m) ' % (zprev, Cz0, Cz1)) else: flag_z = 'y' ################################################# # Gor for mcmc phase ################################################# if flag_z == 'y' or flag_z == '': zrecom = zprev Czrec0 = Cz0 Czrec1 = Cz1 ####################### # Added ####################### if fzmc == 1: out_keep = out #sigz = 1.0 #3.0 fit_params.add('zmc', value=zrecom, min=zrecom - (z_cz[1] - z_cz[0]) * sigz, max=zrecom + (z_cz[2] - z_cz[1]) * sigz) #print(zrecom,zrecom-(z_cz[1]-z_cz[0])*sigz,zrecom+(z_cz[2]-z_cz[1])*sigz) ##################### # Error parameter ##################### try: ferr = int(inputs['F_ERR']) if ferr == 1: fit_params.add('f', value=1e-2, min=0, max=1e2) ndim += 1 except: ferr = 0 pass ##################### # Dust; ##################### if f_dust: Tdust = np.arange(DT0, DT1, dDT) fit_params.add('TDUST', value=len(Tdust) / 2., min=0, max=len(Tdust) - 1) #fit_params.add('TDUST', value=1, min=0, max=len(Tdust)-1) fit_params.add('MDUST', value=1e6, min=0, max=1e10) ndim += 2 # Append data; dat_d = np.loadtxt(DIR_TMP + 'spec_dust_obs_' + ID0 + '_PA' + PA0 + '.cat', comments='#') x_d = dat_d[:, 1] fy_d = dat_d[:, 2] ey_d = dat_d[:, 3] fy = np.append(fy, fy_d) x = np.append(x, x_d) wht = np.append(wht, 1. / np.square(ey_d)) wht2 = check_line_man(fy, x, wht, fy, zprev, LW0) # Then, minimize again. out = minimize( residual, fit_params, args=(fy, wht2, f_dust), method=fit_name ) # It needs to define out with redshift constrain. print(fit_report(out)) # Fix params to what we had before. out.params['zmc'].value = zrecom out.params['Av'].value = out_keep.params['Av'].value for aa in range(len(age)): out.params['A' + str(aa)].value = out_keep.params['A' + str(aa)].value try: out.params['Z' + str(aa)].value = out_keep.params[ 'Z' + str(aa)].value except: out.params['Z0'].value = out_keep.params['Z0'].value ############################## # Save fig of z-distribution. ############################## try: # if spectrum; fig = plt.figure(figsize=(6.5, 2.5)) fig.subplots_adjust(top=0.96, bottom=0.16, left=0.09, right=0.99, hspace=0.15, wspace=0.25) ax1 = fig.add_subplot(111) #n, nbins, patches = ax1.hist(res_cz.flatchain['z'], bins=200, normed=False, color='gray',label='') n, nbins, patches = ax1.hist(res_cz.flatchain['z'], bins=200, normed=True, color='gray', label='') if f_fitgauss == 1: ax1.plot(lnspc, pdf_g, label='Gaussian fit', color='g', linestyle='-') # plot it ax1.set_xlim(m - s * 3, m + s * 3) yy = np.arange(0, np.max(n), 1) xx = yy * 0 + z_cz[1] ax1.plot( xx, yy, linestyle='-', linewidth=1, color='orangered', label='$z=%.5f_{-%.5f}^{+%.5f}$\n$C_z0=%.3f$\n$C_z1=%.3f$' % (z_cz[1], z_cz[1] - z_cz[0], z_cz[2] - z_cz[1], Czrec0, Czrec1)) xx = yy * 0 + z_cz[0] ax1.plot(xx, yy, linestyle='--', linewidth=1, color='orangered') xx = yy * 0 + z_cz[2] ax1.plot(xx, yy, linestyle='--', linewidth=1, color='orangered') xx = yy * 0 + zprev ax1.plot(xx, yy, linestyle='-', linewidth=1, color='royalblue') ax1.set_xlabel('Redshift') ax1.set_ylabel('$dn/dz$') ax1.legend(loc=0) plt.savefig('zprob_' + ID0 + '_PA' + PA0 + '.pdf', dpi=300) plt.close() except: print('z-distribution figure is not generated.') pass ############################## print('\n\n') print('###############################') print('Input redshift is adopted.') print('Starting long journey in MCMC.') print('###############################') print('\n\n') ################# # Initialize mm. ################# mm = 0 # add a noise parameter # out.params.add('f', value=1, min=0.001, max=20) wht2 = wht ################################ print('\nMinimizer Defined\n') mini = Minimizer(lnprob, out.params, fcn_args=[fy, wht2, f_dust], f_disp=f_disp, f_move=f_move) print('######################') print('### Starting emcee ###') print('######################') import multiprocess ncpu0 = int(multiprocess.cpu_count() / 2) try: ncpu = int(inputs['NCPU']) if ncpu > ncpu0: print('!!! NCPU is larger than No. of CPU. !!!') #print('Now set to %d'%(ncpu0)) #ncpu = ncpu0 except: ncpu = ncpu0 pass print('No. of CPU is set to %d' % (ncpu)) start_mc = timeit.default_timer() res = mini.emcee(burn=int(nmc / 2), steps=nmc, thin=10, nwalkers=nwalk, params=out.params, is_weighted=True, ntemps=ntemp, workers=ncpu) stop_mc = timeit.default_timer() tcalc_mc = stop_mc - start_mc print('###############################') print('### MCMC part took %.1f sec ###' % (tcalc_mc)) print('###############################') #----------- Save pckl file #-------- store chain into a cpkl file start_mc = timeit.default_timer() import corner burnin = int(nmc / 2) savepath = './' cpklname = 'chain_' + ID0 + '_PA' + PA0 + '_corner.cpkl' savecpkl( { 'chain': res.flatchain, 'burnin': burnin, 'nwalkers': nwalk, 'niter': nmc, 'ndim': ndim }, savepath + cpklname) # Already burn in stop_mc = timeit.default_timer() tcalc_mc = stop_mc - start_mc print('#################################') print('### Saving chain took %.1f sec' % (tcalc_mc)) print('#################################') Avmc = np.percentile(res.flatchain['Av'], [16, 50, 84]) #Zmc = np.percentile(res.flatchain['Z'], [16,50,84]) Avpar = np.zeros((1, 3), dtype='float32') Avpar[0, :] = Avmc out = res #################### # Best parameters #################### Amc = np.zeros((len(age), 3), dtype='float32') Ab = np.zeros(len(age), dtype='float32') Zmc = np.zeros((len(age), 3), dtype='float32') Zb = np.zeros(len(age), dtype='float32') NZbest = np.zeros(len(age), dtype='int') f0 = fits.open(DIR_TMP + 'ms_' + ID0 + '_PA' + PA0 + '.fits') sedpar = f0[1] ms = np.zeros(len(age), dtype='float32') for aa in range(len(age)): Ab[aa] = out.params['A' + str(aa)].value Amc[aa, :] = np.percentile(res.flatchain['A' + str(aa)], [16, 50, 84]) try: Zb[aa] = out.params['Z' + str(aa)].value Zmc[aa, :] = np.percentile(res.flatchain['Z' + str(aa)], [16, 50, 84]) except: Zb[aa] = out.params['Z0'].value Zmc[aa, :] = np.percentile(res.flatchain['Z0'], [16, 50, 84]) NZbest[aa] = bfnc.Z2NZ(Zb[aa]) ms[aa] = sedpar.data['ML_' + str(NZbest[aa])][aa] Avb = out.params['Av'].value if f_dust: Mdust_mc = np.zeros(3, dtype='float32') Tdust_mc = np.zeros(3, dtype='float32') Mdust_mc[:] = np.percentile(res.flatchain['MDUST'], [16, 50, 84]) Tdust_mc[:] = np.percentile(res.flatchain['TDUST'], [16, 50, 84]) print(Mdust_mc) print(Tdust_mc) #################### # MCMC corner plot. #################### if mcmcplot: fig1 = corner.corner(res.flatchain, labels=res.var_names, \ label_kwargs={'fontsize':16}, quantiles=[0.16, 0.84], show_titles=False, \ title_kwargs={"fontsize": 14}, truths=list(res.params.valuesdict().values()), \ plot_datapoints=False, plot_contours=True, no_fill_contours=True, \ plot_density=False, levels=[0.68, 0.95, 0.997], truth_color='gray', color='#4682b4') fig1.savefig('SPEC_' + ID0 + '_PA' + PA0 + '_corner.pdf') plt.close() ######################### msmc0 = 0 for aa in range(len(age)): msmc0 += res.flatchain['A' + str(aa)] * ms[aa] msmc = np.percentile(msmc0, [16, 50, 84]) # Do analysis on MCMC results. # Write to file. stop = timeit.default_timer() tcalc = stop - start # Load writing package; from .writing import Analyze wrt = Analyze(inputs) # Set up for input start_mc = timeit.default_timer() wrt.get_param(res, lib_all, zrecom, Czrec0, Czrec1, z_cz[:], scl_cz0[:], scl_cz1[:], fitc[:], tau0=tau0, tcalc=tcalc) stop_mc = timeit.default_timer() tcalc_mc = stop_mc - start_mc print('##############################################') print('### Writing params tp file took %.1f sec ###' % (tcalc_mc)) print('##############################################') return 0, zrecom, Czrec0, Czrec1 ################################################################### elif flag_z == 'm': zrecom = float( raw_input('What is your manual input for redshift? ')) Czrec0 = float(raw_input('What is your manual input for Cz0? ')) Czrec1 = float(raw_input('What is your manual input for Cz1? ')) print('\n\n') print('Generate model templates with input redshift and Scale.') print('\n\n') return 1, zrecom, Czrec0, Czrec1 else: print('\n\n') print('Terminated because of redshift estimate.') print('Generate model templates with recommended redshift.') print('\n\n') flag_gen = raw_input( 'Do you want to make templates with recommended redshift, Cz0, and Cz1 , %.5f %.5f %.5f? ([y]/n) ' % (zrecom, Czrec0, Czrec1)) if flag_gen == 'y' or flag_gen == '': #return 1, zrecom, Cz0 * Czrec0, Cz1 * Czrec1 return 1, zrecom, Czrec0, Czrec1 else: print('\n\n') print('There is nothing to do.') print('\n\n') return 0, zprev, Czrec0, Czrec1
def __init__(self, params=B2008, MStar_bounds=['extrapolate', float('NaN')], phiStar_bounds=['constant', float('NaN')], alpha_bounds=['constant', float('NaN')], extrap_args={}, extrap_var='z', sedParams={}, wavelength=1500., **cosmo): for (k, v) in params.iteritems(): params[k] = numpy.asarray(v) self.params = params self.MStar_bounds = MStar_bounds self.phiStar_bounds = phiStar_bounds self.alpha_bounds = alpha_bounds self.extrap_args = extrap_args self.extrap_var = extrap_var self.sedParams = sedParams self.wavelength = wavelength self.cosmo = cosmo self.zobs = params['z'] self.tobs = cd.age(self.zobs, **cosmo)[0] self.MStar = params['MStar'] self.phiStar = params['phiStar'] self.alpha = params['alpha'] if extrap_var == 't': self.xobs = self.tobs self._iPhotFunc = \ lambda t1, mag: (self.iPhotonRateDensity_t(t1, maglim=mag)) elif extrap_var == 'z': self.xobs = self.zobs MStar_bounds = MStar_bounds[::-1] phiStar_bounds = phiStar_bounds[::-1] alpha_bounds = alpha_bounds[::-1] self._iPhotFunc = \ lambda z1, mag: (self.iPhotonRateDensity_z(z1, maglim=mag)) self._MStarfunc = utils.Extrapolate1d(self.xobs, self.MStar, bounds_behavior=MStar_bounds, **extrap_args) print("M*:", ) print(self._MStarfunc.extrap_string()) self._phiStarfunc = utils.Extrapolate1d(self.xobs, self.phiStar, bounds_behavior=phiStar_bounds, **extrap_args) print("phi*:", ) print(self._phiStarfunc.extrap_string()) self._alphafunc = utils.Extrapolate1d(self.xobs, self.alpha, bounds_behavior=alpha_bounds, **extrap_args) print("alpha:", ) print(self._alphafunc.extrap_string()) self._SED = BrokenPowerlawSED(**sedParams) self._rQL = self._SED.iPhotonRateRatio(wavelength) for name, func in globals().items(): if not name.startswith('schechter'): continue def newfunc(z, _name=name, _func=func, **kwargs): params = self.params_z(z) M = params['MStar'] phi = params['phiStar'] alpha = params['alpha'] return _func(MStar=M, phiStar=phi, alpha=alpha, **kwargs) newfunc.__name__ = func.__name__ newfunc.__doc__ = func.__doc__ self.__dict__[name] = newfunc
import matplotlib.pyplot as plt from scipy.integrate import quad from scipy.stats import truncnorm import cosmolopy.distance as cd import cosmolopy.constants as cc nObj = 1000000 intercept = -8. slope = 1. scatter = 0.3 cosmo = {'omega_M_0' : 0.3, 'omega_lambda_0' : 0.7, 'h' : 0.7} cosmo = cd.set_omega_k_0(cosmo) zObs=2.0 ageUniv = cd.age(zObs, **cosmo)/cc.yr_s ageUniv5 = cd.age(5.0, **cosmo)/cc.yr_s msa = 10**np.random.uniform(low=6, high=np.log10(ageUniv), size=nObj) # yrs tau = 10**np.random.uniform(low=7, high=10.5, size=nObj) # yrs tau_exp = 10**np.random.uniform(low=7, high=10.5, size=nObj) # yrs mass = 10**np.random.uniform(low=7, high=12, size=nObj) # solar masses A = np.zeros(nObj) for i in range(nObj): integrand = lambda T: T*np.heaviside(tau[i]-T, 0) + tau[i]*np.exp((tau[i]-T)/tau_exp[i])*np.heaviside(T-tau[i], 1) integral = quad(integrand, 0, msa[i])
def ionization_from_luminosity(z, ratedensityfunc, xHe=1.0, rate_is_tfunc=False, ratedensityfunc_args=(), method='romberg', **cosmo): """Integrate the ionization history given an ionizing luminosity function, ignoring recombinations. Parameters ---------- ratedensityfunc: callable function giving comoving ionizing photon emission rate density, or ionizing emissivity (photons s^-1 Mpc^-3) as a function of redshift (or time). rate_is_tfunc: boolean Set to true if ratedensityfunc is a function of time rather than z. Notes ----- Ignores recombinations. The ionization rate is computed as ratedensity / nn, where nn = nH + xHe * nHe. So if xHe is 1.0, we are assuming that helium becomes singly ionized at proportionally the same rate as hydrogen. If xHe is 2.0, we are assuming helium becomes fully ionizing at proportionally the same rate as hydrogen. The returened x is therefore the ionized fraction of hydrogen, and the ionized fraction of helium is xHe * x. """ cosmo = cd.set_omega_k_0(cosmo) rhoc, rho0, nHe, nH = cden.baryon_densities(**cosmo) nn = (nH + xHe * nHe) if rate_is_tfunc: t = cd.age(z, **cosmo)[0] def dx_dt(t1): return numpy.nan_to_num( ratedensityfunc(t1, *ratedensityfunc_args) / nn) sorti = numpy.argsort(t) x = numpy.empty(t.shape) x[sorti] = cu.integrate_piecewise(dx_dt, t[sorti], method=method) return x else: dt_dz = lambda z1: cd.lookback_integrand(z1, **cosmo) def dx_dz(z1): z1 = numpy.abs(z1) return numpy.nan_to_num( dt_dz(z1) * ratedensityfunc(z1, *ratedensityfunc_args) / nn) sorti = numpy.argsort(-z) x = numpy.empty(z.shape) x[sorti] = cu.integrate_piecewise(dx_dz, -z[sorti], method=method) return x
def plot_mz(ID0, PA, Z=np.arange(-1.2, 0.4249, 0.05), age=[0.01, 0.1, 0.3, 0.7, 1.0, 3.0]): #col = ['darkred', 'r', 'coral','orange','g','lightgreen', 'lightblue', 'b','indigo','violet','k'] import matplotlib.cm as cm flim = 0.01 lsfrl = -1 # log SFR low limit mmax = 500 Txmax = 4 # Max x value lmmin = 10.3 nage = np.arange(0, len(age), 1) fnc = Func(Z, nage) # Set up the number of Age/ZZ bfnc = Basic(Z) age = np.asarray(age) ################ # RF colors. import os.path home = os.path.expanduser('~') #fil_path = '/Users/tmorishita/eazy-v1.01/PROG/FILT/' fil_path = home + '/Dropbox/FILT/' fil_u = fil_path + 'u.fil' fil_b = fil_path + 'b.fil' fil_v = fil_path + "v.fil" fil_j = fil_path + "j.fil" fil_k = fil_path + "k.fil" fil_f125w = fil_path + "f125w.fil" fil_f160w = fil_path + "f160w.fil" fil_36 = fil_path + "3.6.fil" fil_45 = fil_path + "4.5.fil" du = np.loadtxt(fil_u, comments="#") lu = du[:, 1] fu = du[:, 2] db = np.loadtxt(fil_b, comments="#") lb = db[:, 1] fb = db[:, 2] dv = np.loadtxt(fil_v, comments="#") lv = dv[:, 1] fv = dv[:, 2] dj = np.loadtxt(fil_j, comments="#") lj = dj[:, 1] fj = dj[:, 2] c = 3.e18 # A/s chimax = 1. mag0 = 25.0 d = 10**(73.6 / 2.5) * 1e-18 # From [ergs/s/cm2/A] to [ergs/s/cm2/Hz] #d = 10**(-73.6/2.5) # From [ergs/s/cm2/Hz] to [ergs/s/cm2/A] ############# # Plot. ############# fig = plt.figure(figsize=(6, 6)) fig.subplots_adjust(top=0.98, bottom=0.08, left=0.1, right=0.99, hspace=0.18, wspace=0.25) ax1 = fig.add_subplot(221) ax2 = fig.add_subplot(222) ax3 = fig.add_subplot(223) ax4 = fig.add_subplot(224) #ax3t = ax3.twiny() #ax4t = ax4.twiny() ################## # Fitting Results ################## DIR_TMP = './templates/' SNlim = 3 # avobe which SN line is shown. ########################### # Open result file ########################### file = 'summary_' + ID0 + '_PA' + PA + '.fits' hdul = fits.open(file) # open a FITS file zbes = hdul[0].header['z'] Asum = 0 A50 = np.arange(len(age), dtype='float32') for aa in range(len(A50)): A50[aa] = hdul[1].data['A' + str(aa)][1] Asum += A50[aa] # Cosmo; DL = cd.luminosity_distance(zbes, ** cosmo) * Mpc_cm # Luminositydistance in cm Cons = (4. * np.pi * DL**2 / (1. + zbes)) Tuni = cd.age(zbes, use_flat=True, **cosmo) # age at zobs. Tuni0 = (Tuni / cc.Gyr_s - age[:]) delT = np.zeros(len(age), dtype='float32') delTl = np.zeros(len(age), dtype='float32') delTu = np.zeros(len(age), dtype='float32') col = np.zeros((len(age), 4), dtype='float32') for aa in range(len(age)): col[aa, :] = cm.nipy_spectral_r((aa + 0.1) / (len(age))) for aa in range(len(age)): if aa == 0: delTl[aa] = age[aa] delTu[aa] = (age[aa + 1] - age[aa]) / 2. delT[aa] = delTu[aa] + delTl[aa] elif Tuni / cc.Gyr_s < age[aa]: delTl[aa] = (age[aa] - age[aa - 1]) / 2. delTu[aa] = 10. delT[aa] = delTu[aa] + delTl[aa] elif aa == len(age) - 1: delTl[aa] = (age[aa] - age[aa - 1]) / 2. delTu[aa] = Tuni / cc.Gyr_s - age[aa] delT[aa] = delTu[aa] + delTl[aa] else: delTl[aa] = (age[aa] - age[aa - 1]) / 2. delTu[aa] = (age[aa + 1] - age[aa]) / 2. delT[aa] = delTu[aa] + delTl[aa] delT[:] *= 1e9 # Gyr to yr delTl[:] *= 1e9 # Gyr to yr delTu[:] *= 1e9 # Gyr to yr #print(age, delT, delTu, delTl) ############################## # Load Pickle ############################## samplepath = './' pfile = 'chain_' + ID0 + '_PA' + PA + '_corner.cpkl' niter = 0 data = loadcpkl(os.path.join(samplepath + '/' + pfile)) try: #if 1>0: ndim = data[ 'ndim'] # By default, use ndim and burnin values contained in the cpkl file, if present. burnin = data['burnin'] nmc = data['niter'] nwalk = data['nwalkers'] Nburn = burnin #* nwalk/10/2 # I think this takes 3/4 of samples #if nmc>1000: # Nburn = 500 samples = data['chain'][:] except: print( ' = > NO keys of ndim and burnin found in cpkl, use input keyword values' ) return -1 ###################### # Mass-to-Light ratio. ###################### # Wht do you want from MCMC sampler? AM = np.zeros((len(age), mmax), dtype='float32') # Mass in each bin. AC = np.zeros((len(age), mmax), dtype='float32') # Cumulative mass in each bin. ZM = np.zeros((len(age), mmax), dtype='float32') # Z. ZC = np.zeros((len(age), mmax), dtype='float32') # Cumulative Z. TC = np.zeros((len(age), mmax), dtype='float32') # Mass weighted T. ZMM = np.zeros((len(age), mmax), dtype='float32') # Mass weighted Z. SF = np.zeros((len(age), mmax), dtype='float32') # SFR mm = 0 while mm < mmax: mtmp = np.random.randint(len(samples)) # + Nburn AAtmp = np.zeros(len(age), dtype='float32') ZZtmp = np.zeros(len(age), dtype='float32') mslist = np.zeros(len(age), dtype='float32') Av_tmp = samples['Av'][mtmp] f0 = fits.open(DIR_TMP + 'ms_' + ID0 + '_PA' + PA + '.fits') sedpar = f0[1] for aa in range(len(age)): AAtmp[aa] = samples['A' + str(aa)][mtmp] ZZtmp[aa] = samples['Z' + str(aa)][mtmp] nZtmp = bfnc.Z2NZ(ZZtmp[aa]) mslist[aa] = sedpar.data['ML_' + str(nZtmp)][aa] AM[aa, mm] = AAtmp[aa] * mslist[aa] SF[aa, mm] = AAtmp[aa] * mslist[aa] / delT[aa] ZM[aa, mm] = ZZtmp[aa] # AAtmp[aa] * mslist[aa] ZMM[aa, mm] = (10**ZZtmp[aa]) * AAtmp[aa] * mslist[aa] for aa in range(len(age)): AC[aa, mm] = np.sum(AM[aa:, mm]) ZC[aa, mm] = np.log10(np.sum((ZMM)[aa:, mm]) / AC[aa, mm]) ACs = 0 for bb in range(aa, len(age), 1): TC[aa, mm] += age[bb] * AAtmp[bb] * mslist[bb] ACs += AAtmp[bb] * mslist[bb] TC[aa, mm] /= ACs mm += 1 ############# # Plot ############# AMp = np.zeros((len(age), 3), dtype='float32') ACp = np.zeros((len(age), 3), dtype='float32') ZMp = np.zeros((len(age), 3), dtype='float32') ZCp = np.zeros((len(age), 3), dtype='float32') SFp = np.zeros((len(age), 3), dtype='float32') for aa in range(len(age)): AMp[aa, :] = np.percentile(AM[aa, :], [16, 50, 84]) ACp[aa, :] = np.percentile(AC[aa, :], [16, 50, 84]) ZMp[aa, :] = np.percentile(ZM[aa, :], [16, 50, 84]) ZCp[aa, :] = np.percentile(ZC[aa, :], [16, 50, 84]) SFp[aa, :] = np.percentile(SF[aa, :], [16, 50, 84]) ################### msize = np.zeros(len(age), dtype='float32') for aa in range(len(age)): if A50[aa] / Asum > flim: # if >1% msize[aa] = 10 + 150 * A50[aa] / Asum conA = (msize >= 0) # # M-SFR # #ax1.fill_between(age[conA], np.log10(SFp[:,0])[conA], np.log10(SFp[:,2])[conA], linestyle='-', color='k', alpha=0.3) ax1.scatter(np.log10(ACp[:, 1])[conA], np.log10(SFp[:, 1])[conA], marker='o', c=col[:], s=msize[conA], edgecolors='k', zorder=2) ax1.errorbar(np.log10(ACp[:, 1])[conA], np.log10(SFp[:, 1])[conA], linestyle='--', color='k', lw=1., marker='', zorder=0, alpha=1.) lM = np.arange(9, 13, 0.1) delSFR = np.zeros(len(age), dtype='float32') delSFRl = np.zeros(len(age), dtype='float32') delSFRu = np.zeros(len(age), dtype='float32') for ii in range(len(Tuni0)): lSFR = (0.84 - 0.026 * Tuni0[ii]) * (lM - 0.19) - (6.51 - 0.11 * Tuni0[ii]) ax1.fill_between(lM, lSFR - 0.1, lSFR + 0.1, linestyle='None', lw=0.5, zorder=-5, alpha=0.5, color=col[ii]) # 0.19 is for Kroupa to Salpeter. lSFRtmp = (0.84 - 0.026 * Tuni0[ii]) * np.log10(ACp[ii, 1]) - ( 6.51 - 0.11 * Tuni0[ii]) delSFR[ii] = np.log10(SFp[ii, 1]) - lSFRtmp delSFRl[ii] = np.log10(SFp[ii, 0]) - lSFRtmp delSFRu[ii] = np.log10(SFp[ii, 2]) - lSFRtmp # # t - delta SRF relation (right top) # #ax2.plot(age[:][conA], delSFR[conA], marker='', c='k',zorder=1, lw=1, linestyle='-') ax2.scatter(age[:][conA], delSFR[conA], marker='o', c=col[:], s=msize[conA], edgecolors='k', zorder=2) ax2.errorbar(age[:][conA], delSFR[:][conA], linestyle='--', fmt='--', color='k', lw=1., marker='', zorder=0, alpha=1.) # # Mass - Z relation (left bottom) # ax2label = '' #ax2.fill_between(age[conA], np.log10(ACp[:,0])[conA], np.log10(ACp[:,2])[conA], linestyle='-', color='k', alpha=0.3) ax3.errorbar( np.log10(ACp[:, 1])[conA], ZCp[:, 1][conA], linestyle='--', zorder=0, color='k', lw=1., label=ax2label, alpha=1. ) #, xerr=[np.log10(ACp[:,1])[conA]-np.log10(ACp[:,0])[conA],np.log10(ACp[:,2])[conA]-np.log10(ACp[:,1])[conA]], yerr=[ZCp[:,1][conA]-ZCp[:,0][conA],ZCp[:,2][conA]-ZCp[:,1][conA]] ax3.scatter(np.log10(ACp[:, 1])[conA], ZCp[:, 1][conA], marker='o', c=col[:], s=msize, edgecolors='k', zorder=2) # # Mass-Z from Gallazzi+05 # lM = [ 8.91, 9.11, 9.31, 9.51, 9.72, 9.91, 10.11, 10.31, 10.51, 10.72, 10.91, 11.11, 11.31, 11.51, 11.72, 11.91 ] lZ50 = [ -0.6, -0.61, -0.65, -0.61, -.52, -.41, -.23, -.11, -.01, .04, .07, .10, .12, .13, .14, .15 ] lZ16 = [ -1.11, -1.07, -1.1, -1.03, -.97, -.90, -.8, -.65, -.41, -.24, -.14, -.09, -.06, -.04, -.03, -.03 ] lZ84 = [ -0., -0., -0.05, -0.01, .05, .09, .14, .17, .20, .22, .24, .25, .26, .28, .29, .30 ] lM = np.asarray(lM) lZ50 = np.asarray(lZ50) lZ16 = np.asarray(lZ16) lZ84 = np.asarray(lZ84) ax3.errorbar(lM, lZ50, marker='', color='gray', ms=15, linestyle='-', lw=1, zorder=-2) #, yerr=[lZ50-lZ16, lZ84-lZ50] ax3.fill_between(lM, lZ16, lZ84, color='gray', linestyle='None', lw=1, alpha=0.4, zorder=-2) # # Fundamental Metal # bsfr = -0.32 # From Mannucci+10 #ax4.fill_between(age[conA], ZCp[:,0][conA], ZCp[:,2][conA], linestyle='-', color='k', alpha=0.3) ax4.scatter((np.log10(ACp[:, 1]) + bsfr * np.log10(SFp[:, 1]))[conA], ZCp[:, 1][conA], marker='o', c=col[:], s=msize[conA], edgecolors='k', zorder=2) ax4.errorbar((np.log10(ACp[:, 1]) + bsfr * np.log10(SFp[:, 1]))[conA], ZCp[:, 1][conA], linestyle='--', color='k', lw=1., zorder=0, alpha=1.) for iic in range(len(A50)): if msize[iic] > 10: lwe = 1.5 ax1.errorbar(np.log10(ACp[iic, 1]), np.log10(SFp[iic, 1]), xerr=[[np.log10(ACp[iic, 1]) - np.log10(ACp[iic, 0])], [np.log10(ACp[iic, 2]) - np.log10(ACp[iic, 1])] ], yerr=[[np.log10(SFp[iic, 1]) - np.log10(SFp[iic, 0])], [np.log10(SFp[iic, 2]) - np.log10(SFp[iic, 1])] ], linestyle='-', color=col[iic], lw=lwe, marker='', zorder=1) ax2.errorbar(age[iic], delSFR[iic], xerr=[[delTl[iic] / 1e9], [delTu[iic] / 1e9]], yerr=[[delSFR[iic] - delSFRl[iic]], [delSFRu[iic] - delSFR[iic]]], linestyle='-', fmt='-', color=col[iic], lw=lwe, marker='', zorder=1) ax3.errorbar(np.log10(ACp[iic, 1]), ZCp[iic, 1], xerr=[[np.log10(ACp[iic, 1]) - np.log10(ACp[iic, 0])], [np.log10(ACp[iic, 2]) - np.log10(ACp[iic, 1])] ], yerr=[[ZCp[iic, 1] - ZCp[iic, 0]], [ZCp[iic, 2] - ZCp[iic, 1]]], linestyle='-', color=col[iic], lw=lwe, label=ax2label, zorder=1) xerl_ax4 = np.sqrt( (np.log10(ACp[iic, 1]) - np.log10(ACp[iic, 0]))**2 + bsfr**2 * (np.log10(SFp[iic, 1]) - np.log10(SFp[iic, 0]))**2) xeru_ax4 = np.sqrt( (np.log10(ACp[iic, 2]) - np.log10(ACp[iic, 1]))**2 + bsfr**2 * (np.log10(SFp[iic, 2]) - np.log10(SFp[iic, 1]))**2) ax4.errorbar( (np.log10(ACp[iic, 1]) + bsfr * np.log10(SFp[iic, 1])), ZCp[iic, 1], xerr=[[xerl_ax4], [xeru_ax4]], yerr=[[ZCp[iic, 1] - ZCp[iic, 0]], [ZCp[iic, 2] - ZCp[iic, 1]]], linestyle='-', color=col[iic], lw=lwe, label=ax2label, zorder=1) ######################### # Title ######################### #ax1.set_title('Each $t$-bin', fontsize=12) #ax2.set_title('Net system', fontsize=12) #ax3.set_title('Each $t$-bin', fontsize=12) #ax4.set_title('Net system', fontsize=12) ############# # Axis ############# #ax1.set_xlabel('$t$ (Gyr)', fontsize=12) ax1.set_ylabel('$\log \dot{M_*}/M_\odot$yr$^{-1}$', fontsize=12) #ax1.set_ylabel('$\log M_*/M_\odot$', fontsize=12) y3min, y3max = np.min(Z), np.max(Z) lsfru = 2.8 if np.max(np.log10(SFp[:, 2])) > 2.8: lsfru = np.max(np.log10(SFp[:, 2])) + 0.1 y2min, y2max = 9.5, 12.5 ax1.set_xlim(y2min, y2max) ax1.set_ylim(lsfrl, lsfru) #ax1.set_xscale('log') ax1.set_xlabel('$\log M_*/M_\odot$', fontsize=12) #ax1.xaxis.labelpad = -3 #ax1.yaxis.labelpad = -2 #ax2t.set_yticklabels(()) #ax2.set_xlabel('$t$ (Gyr)', fontsize=12) #ax2.set_ylabel('$\log M_*/M_\odot$', fontsize=12) ax2.set_xlabel('$t-t_\mathrm{obs.}$/Gyr', fontsize=12) ax2.set_ylabel('$\Delta_\mathrm{SFR}$', fontsize=12) #ax2.set_ylim(lsfrl, lsfru) ax2.set_ylim(-4, 2.5) ax2.set_xlim(0.008, 3.2) ax2.set_xscale('log') dely2 = 0.1 while (y2max - y2min) / dely2 > 7: dely2 *= 2. #y2ticks = np.arange(y2min, y2max, dely2) #ax2.set_yticks(y2ticks) #ax2.set_yticklabels(np.arange(y2min, y2max, 0.1), minor=False) #ax2.yaxis.set_major_formatter(FormatStrFormatter('%.1f')) ax3.set_xlim(y2min, y2max) ax3.set_ylim(y3min, y3max) ax3.set_xlabel('$\log M_*/M_\odot$', fontsize=12) ax3.set_ylabel('$\log Z_*/Z_\odot$', fontsize=12) #ax3.set_xscale('log') #ax2.yaxis.set_major_formatter(FormatStrFormatter('%.2f')) # For redshift if zbes < 2: zred = [zbes, 2, 3, 6] #zredl = ['$z_\mathrm{obs.}$', 2, 3, 6] zredl = ['$z_\mathrm{obs.}$', 2, 3, 6] elif zbes < 2.5: zred = [zbes, 2.5, 3, 6] zredl = ['$z_\mathrm{obs.}$', 2.5, 3, 6] elif zbes < 3.: zred = [zbes, 3, 6] zredl = ['$z_\mathrm{obs.}$', 3, 6] elif zbes < 6: zred = [zbes, 6] zredl = ['$z_\mathrm{obs.}$', 6] Tzz = np.zeros(len(zred), dtype='float32') for zz in range(len(zred)): Tzz[zz] = (Tuni - cd.age(zred[zz], use_flat=True, **cosmo)) / cc.Gyr_s if Tzz[zz] < 0.01: Tzz[zz] = 0.01 #ax3t.set_xscale('log') #ax3t.set_xlim(0.008, Txmax) ax4.set_xlabel('$\log M_*/M_\odot - 0.32 \log \dot{M_*}/M_\odot$yr$^{-1}$', fontsize=12) ax4.set_ylabel('$\log Z_*/Z_\odot$', fontsize=12) #ax4t.set_xscale('log') #ax4t.set_xlim(0.008, Txmax) ax4.set_xlim(9, 12.3) ax4.set_ylim(y3min, y3max) #ax4.set_xscale('log') #ax4.yaxis.set_major_formatter(FormatStrFormatter('%.2f')) ax3.yaxis.labelpad = -2 ax4.yaxis.labelpad = -2 #################### ## Save #################### ax1.legend(loc=1, fontsize=11) ax2.legend(loc=3, fontsize=8) plt.savefig('MZ_' + ID0 + '_PA' + PA + '_pcl.pdf')
def maketemp(inputs, zbest, Z=np.arange(-1.2, 0.45, 0.1), age=[0.01, 0.1, 0.3, 0.7, 1.0, 3.0], fneb=0, DIR_TMP='./templates/'): # # inputs : Configuration file. # zbest(float): Best redshift at this iteration. Templates are generated based on this reshift. # Z (array) : Stellar phase metallicity in logZsun. # age (array) : Age, in Gyr. # fneb (int) : flag for adding nebular emissionself. # nage = np.arange(0, len(age), 1) fnc = Func(Z, nage) # Set up the number of Age/ZZ bfnc = Basic(Z) ID = inputs['ID'] PA = inputs['PA'] try: DIR_EXTR = inputs['DIR_EXTR'] if len(DIR_EXTR) == 0: DIR_EXTR = False except: DIR_EXTR = False DIR_FILT = inputs['DIR_FILT'] try: CAT_BB_IND = inputs['CAT_BB_IND'] except: CAT_BB_IND = False try: CAT_BB = inputs['CAT_BB'] except: CAT_BB = False SFILT = inputs['FILTER'] # filter band string. SFILT = [x.strip() for x in SFILT.split(',')] FWFILT = fil_fwhm(SFILT, DIR_FILT) # If FIR data; try: DFILT = inputs['FIR_FILTER'] # filter band string. DFILT = [x.strip() for x in DFILT.split(',')] DFWFILT = fil_fwhm(DFILT, DIR_FILT) CAT_BB_DUST = inputs['CAT_BB_DUST'] DT0 = float(inputs['TDUST_LOW']) DT1 = float(inputs['TDUST_HIG']) dDT = float(inputs['TDUST_DEL']) f_dust = True print('FIR is implemented.') except: print('No FIR is implemented.') f_dust = False pass # # Tau for MCMC parameter; not as fitting parameters. # tau0 = inputs['TAU0'] tau0 = [float(x.strip()) for x in tau0.split(',')] print('############################') print('Making templates at %.4f' % (zbest)) print('############################') #################################################### # Get extracted spectra. #################################################### # # Get ascii data. # #ninp1 = 0 #ninp2 = 0 f_spec = False try: spec_files = inputs['SPEC_FILE'].replace('$ID', '%s' % (ID)) spec_files = [x.strip() for x in spec_files.split(',')] ninp0 = np.zeros(len(spec_files), dtype='int') for ff, spec_file in enumerate(spec_files): try: fd0 = np.loadtxt(DIR_EXTR + spec_file, comments='#') lm0tmp = fd0[:, 0] fobs0 = fd0[:, 1] eobs0 = fd0[:, 2] ninp0[ff] = len(lm0tmp) #[con_tmp]) except Exception: print('File, %s, cannot be open.' % (spec_file)) pass # Constructing arrays. lm = np.zeros(np.sum(ninp0[:]), dtype='float32') fobs = np.zeros(np.sum(ninp0[:]), dtype='float32') eobs = np.zeros(np.sum(ninp0[:]), dtype='float32') fgrs = np.zeros(np.sum(ninp0[:]), dtype='int') # FLAG for G102/G141. for ff, spec_file in enumerate(spec_files): try: fd0 = np.loadtxt(DIR_EXTR + spec_file, comments='#') lm0tmp = fd0[:, 0] fobs0 = fd0[:, 1] eobs0 = fd0[:, 2] for ii1 in range(ninp0[ff]): if ff == 0: ii = ii1 else: ii = ii1 + np.sum(ninp0[:ff]) fgrs[ii] = ff lm[ii] = lm0tmp[ii1] fobs[ii] = fobs0[ii1] eobs[ii] = eobs0[ii1] f_spec = True except Exception: pass except: print('No spec file is provided.') pass ############################# # Extracting BB photometry: ############################# if CAT_BB: fd0 = np.loadtxt(CAT_BB, comments='#') try: id0 = fd0[:, 0] ii0 = np.argmin(np.abs(id0[:] - int(ID))) if int(id0[ii0]) != int(ID): return -1 fd = fd0[ii0, :] except: id0 = fd0[0] if int(id0) != int(ID): return -1 fd = fd0[:] id = fd[0] fbb = np.zeros(len(SFILT), dtype='float32') ebb = np.zeros(len(SFILT), dtype='float32') for ii in range(len(SFILT)): fbb[ii] = fd[ii * 2 + 1] ebb[ii] = fd[ii * 2 + 2] elif CAT_BB_IND: # if individual photometric catalog; made in get_sdss.py fd0 = fits.open(DIR_EXTR + CAT_BB_IND) hd0 = fd0[1].header bunit_bb = float(hd0['bunit'][:5]) lmbb0 = fd0[1].data['wavelength'] fbb0 = fd0[1].data['flux'] * bunit_bb ebb0 = 1 / np.sqrt(fd0[1].data['inverse_variance']) * bunit_bb unit = 'nu' try: unit = inputs['UNIT_SPEC'] except: print('No param for UNIT_SPEC is found.') print('BB flux unit is assumed to Fnu.') pass if unit == 'lambda': print('#########################') print('Changed BB from Flam to Fnu') snbb0 = fbb0 / ebb0 fbb = flamtonu(lmbb0, fbb0) ebb = fbb / snbb0 else: snbb0 = fbb0 / ebb0 fbb = fbb0 ebb = ebb0 else: fbb = np.zeros(len(SFILT), dtype='float32') ebb = np.zeros(len(SFILT), dtype='float32') for ii in range(len(SFILT)): fbb[ii] = 0 ebb[ii] = -99 #1000 # Dust flux; if f_dust: fdd = np.loadtxt(CAT_BB_DUST, comments='#') try: id0 = fdd[:, 0] ii0 = np.argmin(np.abs(id0[:] - int(ID))) if int(id0[ii0]) != int(ID): return -1 fd = fdd[ii0, :] except: id0 = fdd[0] if int(id0) != int(ID): return -1 fd = fdd[:] id = fd[0] fbb_d = np.zeros(len(DFILT), dtype='float32') ebb_d = np.zeros(len(DFILT), dtype='float32') for ii in range(len(DFILT)): fbb_d[ii] = fd[ii * 2 + 1] ebb_d[ii] = fd[ii * 2 + 2] ############################# # Getting Morphology params. ############################# Amp = 0 f_morp = False if f_spec: try: if inputs['MORP'] == 'moffat' or inputs['MORP'] == 'gauss': f_morp = True try: mor_file = inputs['MORP_FILE'].replace('$ID', '%s' % (ID)) fm = np.loadtxt(DIR_EXTR + mor_file, comments='#') #Amp = fm[0] #gamma = fm[1] Amp = fm[2] gamma = fm[4] if inputs['MORP'] == 'moffat': #alp = fm[2] alp = fm[5] else: alp = 0 except Exception: print('Error in reading morphology params.') print('No morphology convolution.') #return -1 pass else: print('MORP Keywords does not match.') print('No morphology convolution.') except: pass ############################ # Template convolution; ############################ try: sig_temp = float(inputs['SIG_TEMP']) except: sig_temp = 50. print('Template resolution is unknown.') print('Set to %.1f km/s.' % (sig_temp)) dellam = lm[1] - lm[0] # AA/pix R_temp = c / (sig_temp * 1e3 * 1e10) sig_temp_pix = np.median(lm) / R_temp / dellam # delta v in pixel; # sig_inst = 0 #65 #km/s for Manga # If grism; if f_morp: print('Templates convolution (intrinsic morphology).') if gamma > sig_temp_pix: sig_conv = np.sqrt(gamma**2 - sig_temp_pix**2) else: sig_conv = 0 print('Template resolution is broader than Morphology.') print('No convolution is applied to templates.') xMof = np.arange(-5, 5.1, .1) # dimension must be even. if inputs['MORP'] == 'moffat' and Amp > 0 and alp > 0: LSF = moffat(xMof, Amp, 0, np.sqrt(gamma**2 - sig_temp_pix**2), alp) #print(np.sqrt(gamma**2-sig_temp_pix**2)) print('Template convolution with Moffat.') #print('params are;',Amp, 0, gamma, alp) elif inputs['MORP'] == 'gauss': sigma = gamma LSF = gauss(xMof, Amp, np.sqrt(sigma**2 - sig_temp_pix**2)) print('Template convolution with Gaussian.') print('params is sigma;', sigma) else: print('Something is wrong.') return -1 else: # For slit spectroscopy. To be updated... print('Templates convolution (intrinsic velocity).') f_disp = False try: vdisp = float(inputs['VDISP']) dellam = lm[1] - lm[0] # AA/pix #R_disp = c/(vdisp*1e3*1e10) R_disp = c / (np.sqrt(vdisp**2 - sig_inst**2) * 1e3 * 1e10) vdisp_pix = np.median( lm) / R_disp / dellam # delta v in pixel; print('Templates are convolved at %.2f km/s.' % (vdisp)) if vdisp_pix - sig_temp_pix > 0: sig_conv = np.sqrt(vdisp_pix**2 - sig_temp_pix**2) else: sig_conv = 0 except: vdisp = 0. print('Templates are not convolved.') sig_conv = 0 #np.sqrt(sig_temp_pix**2) pass xMof = np.arange(-5, 5.1, .1) # dimension must be even. Amp = 1. LSF = gauss(xMof, Amp, sig_conv) else: lm = [] #################################### # Start generating templates #################################### #DIR_TMP = './templates/' #DIR_TMP = inputs['DIR_TEMP'] f0 = fits.open(DIR_TMP + 'ms.fits') mshdu = f0[1] col00 = [] col01 = [] col02 = [] for zz in range(len(Z)): for pp in range(len(tau0)): f1 = fits.open(DIR_TMP + 'spec_all.fits') spechdu = f1[1] Zbest = Z[zz] Na = len(age) Nz = 1 param = np.zeros((Na, 6), dtype='float32') param[:, 2] = 1e99 Ntmp = 1 chi2 = np.zeros(Ntmp) + 1e99 snorm = np.zeros(Ntmp) agebest = np.zeros(Ntmp) avbest = np.zeros(Ntmp) age_univ = cd.age(zbest, use_flat=True, **cosmo) if zz == 0 and pp == 0: lm0 = spechdu.data['wavelength'] if fneb == 1: spec0 = spechdu.data['efspec_' + str(zz) + '_0_' + str(pp)] #logU = f1[0].header['logU'] else: spec0 = spechdu.data['fspec_' + str(zz) + '_0_' + str(pp)] lmbest = np.zeros((Ntmp, len(lm0)), dtype='float32') fbest = np.zeros((Ntmp, len(lm0)), dtype='float32') lmbestbb = np.zeros((Ntmp, len(SFILT)), dtype='float32') fbestbb = np.zeros((Ntmp, len(SFILT)), dtype='float32') A = np.zeros(Na, dtype='float32') + 1 spec_mul = np.zeros((Na, len(lm0)), dtype='float32') spec_mul_nu = np.zeros((Na, len(lm0)), dtype='float32') spec_mul_nu_conv = np.zeros((Na, len(lm0)), dtype='float64') ftmpbb = np.zeros((Na, len(SFILT)), dtype='float32') ltmpbb = np.zeros((Na, len(SFILT)), dtype='float32') ftmp_nu_int = np.zeros((Na, len(lm)), dtype='float32') spec_av_tmp = np.zeros((Na, len(lm)), dtype='float32') ms = np.zeros(Na, dtype='float32') Ls = np.zeros(Na, dtype='float32') ms[:] = mshdu.data['ms_' + str(zz)][:] # [:] is necessary. Ls[:] = mshdu.data['Ls_' + str(zz)][:] Fuv = np.zeros(Na, dtype='float32') for ss in range(Na): wave = spechdu.data['wavelength'] if fneb == 1: spec_mul[ss] = spechdu.data['efspec_' + str(zz) + '_' + str(ss) + '_' + str(pp)] else: spec_mul[ss] = spechdu.data['fspec_' + str(zz) + '_' + str(ss) + '_' + str(pp)] ################### # IGM attenuation. ################### spec_av_tmp = madau_igm_abs(wave, spec_mul[ss, :], zbest) spec_mul_nu[ss, :] = flamtonu(wave, spec_av_tmp) if len(lm) > 0: try: spec_mul_nu_conv[ss, :] = convolve(spec_mul_nu[ss], LSF, boundary='extend') except: spec_mul_nu_conv[ss, :] = spec_mul_nu[ss] if zz == 0 and ss == 0: print('Kernel is too small. No convolution.') else: spec_mul_nu_conv[ss, :] = spec_mul_nu[ss] spec_sum = 0 * spec_mul[0] # This is dummy file. DL = cd.luminosity_distance( zbest, **cosmo) * Mpc_cm # Luminositydistance in cm wavetmp = wave * (1. + zbest) #spec_av = flamtonu(wavetmp, spec_sum) # Conversion from Flambda to Fnu. #ftmp_int = data_int(lm, wavetmp, spec_av) Lsun = 3.839 * 1e33 #erg s-1 stmp_common = 1e10 # 1 tmp is in 1e10Lsun #ftmpbb[ss,:] *= Lsun/(4.*np.pi*DL**2/(1.+zbest)) #ftmpbb[ss,:] *= (1./Ls[ss])*stmp_common spec_mul_nu_conv[ss, :] *= Lsun / (4. * np.pi * DL**2 / (1. + zbest)) spec_mul_nu_conv[ss, :] *= ( 1. / Ls[ss]) * stmp_common # in unit of erg/s/Hz/cm2/ms[ss]. ms[ss] *= ( 1. / Ls[ss] ) * stmp_common # M/L; 1 unit template has this mass in [Msolar]. if f_spec: ftmp_nu_int[ss, :] = data_int(lm, wavetmp, spec_mul_nu_conv[ss, :]) ltmpbb[ss, :], ftmpbb[ss, :] = filconv(SFILT, wavetmp, spec_mul_nu_conv[ss, :], DIR_FILT) # UV magnitude; #print('%s AA is used as UV reference.'%(xm_tmp[iiuv])) #print(ms[ss], (Lsun/(4.*np.pi*DL**2/(1.+zbest)))) #print('m-M=',5*np.log10(DL/Mpc_cm*1e6/10)) ########################################## # Writing out the templates to fits table. ########################################## if ss == 0 and pp == 0 and zz == 0: # First file nd1 = np.arange(0, len(lm), 1) nd3 = np.arange(10000, 10000 + len(ltmpbb[ss, :]), 1) nd_ap = np.append(nd1, nd3) lm_ap = np.append(lm, ltmpbb[ss, :]) col1 = fits.Column(name='wavelength', format='E', unit='AA', array=lm_ap) col2 = fits.Column(name='colnum', format='K', unit='', array=nd_ap) col00 = [col1, col2] # Second file col3 = fits.Column(name='wavelength', format='E', unit='AA', array=wavetmp) nd = np.arange(0, len(wavetmp), 1) col4 = fits.Column(name='colnum', format='K', unit='', array=nd) col01 = [col3, col4] spec_ap = np.append(ftmp_nu_int[ss, :], ftmpbb[ss, :]) colspec = fits.Column(name='fspec_' + str(zz) + '_' + str(ss) + '_' + str(pp), format='E', unit='Fnu', disp='%s' % (age[ss]), array=spec_ap) col00.append(colspec) colspec_all = fits.Column(name='fspec_' + str(zz) + '_' + str(ss) + '_' + str(pp), format='E', unit='Fnu', disp='%s' % (age[ss]), array=spec_mul_nu_conv[ss, :]) col01.append(colspec_all) ######################### # Summarize the ML ######################### if pp == 0: colms = fits.Column(name='ML_' + str(zz), format='E', unit='Msun/1e10Lsun', array=ms) col02.append(colms) ######################### # Summarize the templates ######################### coldefs_spec = fits.ColDefs(col00) hdu = fits.BinTableHDU.from_columns(coldefs_spec) hdu.writeto(DIR_TMP + 'spec_' + ID + '_PA' + PA + '.fits', overwrite=True) coldefs_spec = fits.ColDefs(col01) hdu2 = fits.BinTableHDU.from_columns(coldefs_spec) hdu2.writeto(DIR_TMP + 'spec_all_' + ID + '_PA' + PA + '.fits', overwrite=True) coldefs_ms = fits.ColDefs(col02) hdu3 = fits.BinTableHDU.from_columns(coldefs_ms) hdu3.writeto(DIR_TMP + 'ms_' + ID + '_PA' + PA + '.fits', overwrite=True) ###################### # Add dust component; ###################### if f_dust: Temp = np.arange(DT0, DT1, dDT) lambda_d = np.arange( 1e4, 1e7, 1e3) # RF wavelength, in AA. #* (1.+zbest) # 1um to 1000um; #lambda_d = np.arange(4000,1e7,1e3) # RF wavelength, in AA. #* (1.+zbest) # 1um to 1000um; # c in AA/s. kb = 1.380649e-23 # Boltzmann constant, in J/K hp = 6.62607015e-34 # Planck constant, in J*s # from Eq.3 of Bianchi 13 kabs0 = 4.0 # in cm2/g beta_d = 2.08 # lam0 = 250. * 1e4 # mu m to AA kappa = kabs0 * (lam0 / lambda_d)**beta_d # cm2/g kappa *= (1e8)**2 # AA2/g for tt in range(len(Temp)): if tt == 0: # For full; nd_d = np.arange(0, len(lambda_d), 1) colspec_dw = fits.Column(name='wavelength', format='E', unit='AA', array=lambda_d * (1. + zbest)) col_dw = fits.Column(name='colnum', format='K', unit='', array=nd_d) col03 = [colspec_dw, col_dw] nu_d = c / lambda_d # 1/s = Hz BT_nu = 2 * hp * nu_d[:]**3 / c**2 / ( np.exp(hp * nu_d[:] / (kb * Temp[tt])) - 1 ) # J*s * (1/s)^3 / (AA/s)^2 / sr = J / AA^2 / sr = J/s/AA^2/Hz/sr. # in side exp: J*s * (1/s) / (J/K * K) = 1; # if optically thin; #kappa = nu_d ** beta_d fnu_d = 1.0 / ( 4. * np.pi * DL**2 / (1. + zbest) ) * kappa * BT_nu # 1/cm2 * AA2/g * J/s/AA^2/Hz = J/s/cm^2/Hz/g #fnu_d = 1.0 / (4.*np.pi*DL**2/(1.+zbest)) * BT_nu # 1/cm2 * AA2/g * J/s/AA^2/Hz = J/s/cm^2/Hz/g fnu_d *= 1.989e+33 # J/s/cm^2/Hz/Msun; i.e. 1 flux is in 1Msun fnu_d *= 1e7 # erg/s/cm^2/Hz/Msun. #fnu_d *= 1e9 # Now 1 flux is in 1e9Msun print('Somehow, crazy scale is required for FIR normalization...') fnu_d *= 1e40 colspec_d = fits.Column(name='fspec_' + str(tt), format='E', unit='Fnu(erg/s/cm^2/Hz/Msun)', disp='%.2f' % (Temp[tt]), array=fnu_d) col03.append(colspec_d) #print('At z=%.2f, luminosity surface is %.2e cm^2'%(zbest,4.*np.pi*DL**2/(1.+zbest))) # Convolution; #ltmpbb_d, ftmpbb_d = filconv(DFILT,lambda_d*(1.+zbest),fnu_d,DIR_FILT) ALLFILT = np.append(SFILT, DFILT) ltmpbb_d, ftmpbb_d = filconv(ALLFILT, lambda_d * (1. + zbest), fnu_d, DIR_FILT) if False: #plt.plot(nu_d/1e9/(1.+zbest),fnu_d) #nubb_d = c / ltmpbb_d #plt.plot(nubb_d/1e9, ftmpbb_d, 'x') plt.plot(lambda_d / 1e4, fnu_d) plt.plot(lambda_d * (1. + zbest) / 1e4, fnu_d) plt.plot(ltmpbb_d / 1e4, ftmpbb_d, 'x') plt.show() if tt == 0: # For conv; col3 = fits.Column(name='wavelength', format='E', unit='AA', array=ltmpbb_d) nd_db = np.arange(0, len(ltmpbb_d), 1) col4 = fits.Column(name='colnum', format='K', unit='', array=nd_db) col04 = [col3, col4] colspec_db = fits.Column(name='fspec_' + str(tt), format='E', unit='Fnu', disp='%.2f' % (Temp[tt]), array=ftmpbb_d) col04.append(colspec_db) coldefs_d = fits.ColDefs(col03) hdu4 = fits.BinTableHDU.from_columns(coldefs_d) hdu4.writeto(DIR_TMP + 'spec_dust_all_' + ID + '_PA' + PA + '.fits', overwrite=True) coldefs_db = fits.ColDefs(col04) hdu5 = fits.BinTableHDU.from_columns(coldefs_db) hdu5.writeto(DIR_TMP + 'spec_dust_' + ID + '_PA' + PA + '.fits', overwrite=True) ########################################## # For observation. # Write out for the Multi-component fitting. ########################################## lamliml = 0. lamlimu = 20000. ebblim = 1e5 ncolbb = 10000 fw = open(DIR_TMP + 'spec_obs_' + ID + '_PA' + PA + '.cat', 'w') fw.write('# BB data (>%d) in this file are not used in fitting.\n' % (ncolbb)) for ii in range(len(lm)): if fgrs[ii] == 0: # G102 if lm[ii] / (1. + zbest) > lamliml and lm[ii] / (1. + zbest) < lamlimu: fw.write('%d %.5f %.5e %.5e\n' % (ii, lm[ii], fobs[ii], eobs[ii])) else: fw.write('%d %.5f 0 1000\n' % (ii, lm[ii])) elif fgrs[ii] == 1: # G141 if lm[ii] / (1. + zbest) > lamliml and lm[ii] / (1. + zbest) < lamlimu: fw.write('%d %.5f %.5e %.5e\n' % (ii + 1000, lm[ii], fobs[ii], eobs[ii])) else: fw.write('%d %.5f 0 1000\n' % (ii + 1000, lm[ii])) for ii in range(len(ltmpbb[0, :])): if ebb[ii] > ebblim: fw.write('%d %.5f 0 1000\n' % (ii + ncolbb, ltmpbb[0, ii])) else: fw.write('%d %.5f %.5e %.5e\n' % (ii + ncolbb, ltmpbb[0, ii], fbb[ii], ebb[ii])) fw.close() fw = open(DIR_TMP + 'spec_dust_obs_' + ID + '_PA' + PA + '.cat', 'w') if f_dust: nbblast = len(ltmpbb[0, :]) for ii in range(len(ebb_d[:])): if ebb_d[ii] > ebblim: fw.write('%d %.5f 0 1000\n' % (ii + ncolbb + nbblast, ltmpbb_d[ii + nbblast])) else: fw.write('%d %.5f %.5e %.5e\n' % (ii + ncolbb + nbblast, ltmpbb_d[ii + nbblast], fbb_d[ii], ebb_d[ii])) fw.close() fw = open(DIR_TMP + 'bb_obs_' + ID + '_PA' + PA + '.cat', 'w') for ii in range(len(ltmpbb[0, :])): if ebb[ii] > ebblim: fw.write('%d %.5f 0 1000 %.1f\n' % (ii + ncolbb, ltmpbb[0, ii], FWFILT[ii] / 2.)) else: fw.write('%d %.5f %.5e %.5e %.1f\n' % (ii + ncolbb, ltmpbb[0, ii], fbb[ii], ebb[ii], FWFILT[ii] / 2.)) fw.close() fw = open(DIR_TMP + 'bb_dust_obs_' + ID + '_PA' + PA + '.cat', 'w') if f_dust: for ii in range(len(ebb_d[:])): if ebb_d[ii] > ebblim: fw.write('%d %.5f 0 1000 %.1f\n' % (ii + ncolbb + nbblast, ltmpbb_d[ii + nbblast], DFWFILT[ii] / 2.)) else: fw.write('%d %.5f %.5e %.5e %.1f\n' % (ii + ncolbb + nbblast, ltmpbb_d[ii + nbblast], fbb_d[ii], ebb_d[ii], DFWFILT[ii] / 2.)) fw.close()
da = cd.angular_diameter_distance(z[i], **Cosmology) #See equations 18-19 of David Hogg's arXiv:astro-ph/9905116v4 dl = cd.luminosity_distance(z[i], **Cosmology) #Units are Mpc dVc = cd.diff_comoving_volume(z[i], **Cosmology) #The differential comoving volume element dV_c/dz/dSolidAngle. #Dimensions are volume per unit redshift per unit solid angle. #Units are Mpc**3 Steradians^-1. #See David Hogg's arXiv:astro-ph/9905116v4, equation 28 tl = cd.lookback_time(z[i], **Cosmology) #See equation 30 of David Hogg's arXiv:astro-ph/9905116v4. Units are s. agetl = cd.age(z[i], **Cosmology) #Age at z is lookback time at z'->Infinity minus lookback time at z. tH = 3.09e17 / Cosmology['h'] ez = cd.e_z(z[i], **Cosmology) #The unitless Hubble expansion rate at redshift z. #In David Hogg's (arXiv:astro-ph/9905116v4) formalism, this is #equivalent to E(z), defined in his eq. 14. if PlotNumber == 1: val[i] = dm / dh xtitle = "redshift z" ytitle = "Proper motion distance Dm/Dh" elif PlotNumber == 2:
4, 5, 8, 10, 11, 12, 13, 14, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 31, 32, 34, 35, 36, 37, 39, 41, 42, 43, 44, 45, 47, 49, 50, 51, 53, 55, 56, 58, 61, 62, 63, 64, 65, 66, 68, 70, 71, 73, 75, 78, 79, 81, 83, 84, 88, 89, 90, 92, 93, 94, 95, 96, 98, 99 ]) ID_ff_DE = np.array([3, 59]) ID_rf_DE = np.array([]) ID_fr_DE = np.array([ 2, 7, 9, 15, 18, 33, 38, 40, 52, 69, 72, 74, 76, 77, 80, 82, 85, 86, 87, 91, 97, 100 ]) test = [(4)] cosmo = {'omega_M_0': 0.3, 'omega_lambda_0': 0.7, 'h': 0.7} cosmo = cd.set_omega_k_0(cosmo) ageUniv2 = cd.age(2.0, **cosmo) / cc.yr_s ageUniv999 = cd.age(999.0, **cosmo) / cc.yr_s xlin = np.linspace(1, 1e10, 100000) for j in test: i = (np.abs(ID - j)).argmin() plt.figure(figsize=(4 * fsize, fsize)) plt.title('{} ID {}'.format(revision.replace('_', ' '), j)) plt.xlim(0, 1e10) # plt.xlim(0.9*msa, 1.1*msa) plt.ylim(0.0, 1.1) sfr_in = 1 * (xlin - (ageUniv2 - msa_in[i])) * np.exp(
def __init__(self, params=B2008, MStar_bounds = ['extrapolate', float('NaN')], phiStar_bounds = ['constant', float('NaN')], alpha_bounds = ['constant', float('NaN')], extrap_args = {}, extrap_var = 'z', sedParams = {}, wavelength = 1500., **cosmo): for (k, v) in params.iteritems(): params[k] = numpy.asarray(v) self.params = params self.MStar_bounds = MStar_bounds self.phiStar_bounds = phiStar_bounds self.alpha_bounds = alpha_bounds self.extrap_args = extrap_args self.extrap_var = extrap_var self.sedParams = sedParams self.wavelength = wavelength self.cosmo = cosmo self.zobs = params['z'] self.tobs = cd.age(self.zobs, **cosmo)[0] self.MStar = params['MStar'] self.phiStar = params['phiStar'] self.alpha = params['alpha'] if extrap_var == 't': self.xobs = self.tobs self._iPhotFunc = \ lambda t1, mag: (self.iPhotonRateDensity_t(t1, maglim=mag)) elif extrap_var == 'z': self.xobs = self.zobs MStar_bounds = MStar_bounds[::-1] phiStar_bounds = phiStar_bounds[::-1] alpha_bounds = alpha_bounds[::-1] self._iPhotFunc = \ lambda z1, mag: (self.iPhotonRateDensity_z(z1, maglim=mag)) self._MStarfunc = utils.Extrapolate1d(self.xobs, self.MStar, bounds_behavior=MStar_bounds, **extrap_args ) print "M*:", print self._MStarfunc.extrap_string() self._phiStarfunc = utils.Extrapolate1d(self.xobs, self.phiStar, bounds_behavior=phiStar_bounds, **extrap_args ) print "phi*:", print self._phiStarfunc.extrap_string() self._alphafunc = utils.Extrapolate1d(self.xobs, self.alpha, bounds_behavior=alpha_bounds, **extrap_args ) print "alpha:", print self._alphafunc.extrap_string() self._SED = BrokenPowerlawSED(**sedParams) self._rQL = self._SED.iPhotonRateRatio(wavelength) for name, func in globals().items(): if not name.startswith('schechter'): continue def newfunc(z, _name=name, _func=func, **kwargs): params = self.params_z(z) M = params['MStar'] phi = params['phiStar'] alpha = params['alpha'] return _func(MStar=M, phiStar=phi, alpha=alpha, **kwargs) newfunc.__name__ = func.__name__ newfunc.__doc__ = func.__doc__ self.__dict__[name] = newfunc
def plotLFevo(hist=None, params=B2008, extrap_var='t', #maglim = -21.07 - 2.5 * numpy.log10(0.2)): maglim = -21. - 2.5 * numpy.log10(0.2), z_max=20.0, skipIon=True ): """Plot evolution of luminosity function params and total luminsity. Schechter function at each redshift is integrated up to maglim to find total luminsity. """ for (k, v) in params.iteritems(): params[k] = numpy.asarray(v) if hist is None: cosmo = cp.WMAP7_BAO_H0_mean(flat=True) hist = LFHistory(params, extrap_var=extrap_var, **cosmo) else: params = hist.params extrap_var = hist.extrap_var cosmo = hist.cosmo z = params['z'] t = cd.age(z, **cosmo)[0] / cc.yr_s MStar = params['MStar'] phiStar = params['phiStar'] alpha = params['alpha'] if maglim is None: ltot = schechterTotLM(MStar=MStar, phiStar=phiStar, alpha=alpha) else: ltot = schechterCumuLM(magnitudeAB=maglim, MStar=MStar, phiStar=phiStar, alpha=alpha) print hist._MStarfunc.extrap_string() zPlot = numpy.arange(z.min()-0.1, z_max, 0.1) tPlot = cd.age(zPlot, **cosmo)[0] / cc.yr_s newparams = hist.params_z(zPlot) MPlot = newparams['MStar'] phiPlot = newparams['phiStar'] alphaPlot = newparams['alpha'] if maglim is None: ltotPlot = hist.schechterTotLM(zPlot) else: ltotPlot = hist.schechterCumuLM(zPlot, magnitudeAB=maglim) # From Table 6 of 2008ApJ...686..230B lB2008 =10.** numpy.array([26.18, 25.85, 25.72, 25.32, 25.14]) iPhot = hist.iPhotonRateDensity_z(zPlot, maglim=maglim) # iPhotFunc = lambda t1: cc.yr_s * hist.iPhotonRateDensity_t(t1, # maglim=maglim) if not skipIon: xH = hist.ionization(zPlot, maglim) import pylab pylab.figure(1) pylab.gcf().set_label('LFion_vs_z') if skipIon: pylab.subplot(111) else: pylab.subplot(211) pylab.plot(zPlot, iPhot) if not skipIon: pylab.subplot(212) pylab.plot(zPlot, xH) pylab.ylim(0.0, 1.5) pylab.figure(2) pylab.gcf().set_label('LFparams_vs_z') pylab.subplot(311) pylab.plot(z, MStar, '-') pylab.plot(z, MStar, 'o') pylab.plot(zPlot, MPlot, ':') pylab.subplot(312) pylab.plot(z, phiStar, '-') pylab.plot(z, phiStar, 'o') pylab.plot(zPlot, phiPlot, ':') pylab.subplot(313) pylab.plot(z, alpha, '-') pylab.plot(z, alpha, 'o') pylab.plot(zPlot, alphaPlot, ':') pylab.figure(3) pylab.gcf().set_label('LFparams_vs_t') pylab.subplot(311) pylab.plot(t, MStar, '-') pylab.plot(t, MStar, 'o') pylab.plot(tPlot, MPlot, ':') pylab.subplot(312) pylab.plot(t, phiStar, '-') pylab.plot(t, phiStar, '.') pylab.plot(tPlot, phiPlot, ':') pylab.subplot(313) pylab.plot(t, alpha, '-') pylab.plot(t, alpha, 'o') pylab.plot(tPlot, alphaPlot, ':') pylab.figure(4) pylab.gcf().set_label('LFlum_vs_z') pylab.subplot(121) pylab.plot(z, ltot, 'o') pylab.plot(z, lB2008, 'x') pylab.plot(zPlot, ltotPlot) pylab.subplot(122) pylab.plot(t, ltot, 'o') pylab.plot(t, lB2008, 'x') pylab.plot(tPlot, ltotPlot)
def integrate_ion_recomb(z, ion_func, clump_fact_func, xHe=1.0, temp_gas=1e4, alpha_B=None, bubble=True, **cosmo): """Integrate IGM ionization and recombination given an ionization function. Parameters: z: array The redshift values at which to calculate the ionized fraction. This array should be in reverse numerical order. The first redshift specified should be early enough that the universe is still completely neutral. ion_func: A function giving the ratio of the total density of emitted ionizing photons to the density hydrogen atoms (or hydrogen plus helium, if you prefer) as a function of redshift. temp_gas: Gas temperature used to calculate the recombination coefficient if alpha_b is not specified. alpha_B: Optional recombination coefficient in units of cm^3 s^-1. In alpha_B=None, it is calculated from temp_gas. clump_fact_func: function Function returning the clumping factor when given a redshift, defined as <n_HII^2>/<n_HII>^2. cosmo: dict Dictionary specifying the cosmological parameters. Notes: We only track recombination of hydrogen, but if xHe > 0, then the density is boosted by the addition of xHe * nHe. This is eqiuvalent to assuming the the ionized fraction of helium is always proportional to the ionized fraction of hydrogen. If xHe=1.0, then helium is singly ionized in the same proportion as hydrogen. If xHe=2.0, then helium is fully ionized in the same proportion as hydrogen. We assume, as is fairly standard, that the ionized fraction is contained in fully ionized bubbles surrounded by a fully neutral IGM. The output is therefore the volume filling factor of ionized regions, not the ionized fraction of a uniformly-ionized IGM. I have also made the standard assumption that all ionized photons are immediately absorbed, which allows the two differential equations (one for ionization-recombination and one for emission-photoionizaion) to be combined into a single ODE. """ # Determine recombination coefficient. if alpha_B is None: alpha_B_cm = recomb_rate_coeff_HG(temp_gas, 'H', 'B') else: alpha_B_cm = alpha_B alpha_B = alpha_B_cm * cc.Gyr_s / (cc.Mpc_cm**3.) print( "Recombination rate alpha_B = %.4g (Mpc^3 Gyr^-1) = %.4g (cm^3 s^-1)" % (alpha_B, alpha_B_cm)) # Normalize power spectrum. if 'deltaSqr' not in cosmo: cosmo['deltaSqr'] = cp.norm_power(**cosmo) # Calculate useful densities. rho_crit, rho_0, n_He_0, n_H_0 = cden.baryon_densities(**cosmo) # Boost density to approximately account for helium. nn = (n_H_0 + xHe * n_He_0) # Function used in the integration. # Units: (Mpc^3 Gyr^-1) * Mpc^-3 = Gyr^-1 coeff_rec_func = lambda z1: (clump_fact_func(z1) * alpha_B * nn * (1. + z1)**3.) # Generate a function that converts age of the universe to z. red_func = cd.quick_redshift_age_function(zmax=1.1 * numpy.max(z), zmin=-0.0, dz=0.01, **cosmo) ref_func_Gyr = lambda t1: red_func(t1 * cc.Gyr_s) # Convert specified redshifts to cosmic time (age of the universe). t = cd.age(z, **cosmo)[0] / cc.Gyr_s # Integrate to find u(z) = x(z) - w(z), where w is the ionization fraction u = si.odeint(_udot, y0=0.0, t=t, args=(coeff_rec_func, ref_func_Gyr, ion_func, bubble)) u = u.flatten() w = ion_func(z) x = u + w #x[x > 1.0] = 1.0 return x, w, t
def integrate_ion_recomb_collapse(z, coeff_ion, temp_min=1e4, passed_min_mass=False, temp_gas=1e4, alpha_B=None, clump_fact_func=clumping_factor_BKP, **cosmo): """IGM ionization state with recombinations from halo collapse fraction. Integrates an ODE describing IGM ionization and recombination rates. z: array The redshift values at which to calculate the ionized fraction. This array should be in reverse numerical order. The first redshift specified should be early enough that the universe is still completely neutral. coeff_ion: The coefficient converting the collapse fraction to ionized fraction, neglecting recombinations. Equivalent to the product (f_star * f_esc_gamma * N_gamma) in the BKP paper. temp_min: See docs for ionization_from_collapse. Either the minimum virial temperature or minimum mass of halos contributing to reionization. passed_temp_min: See documentation for ionization_from_collapse. temp_gas: Gas temperature used to calculate the recombination coefficient if alpha_b is not specified. alpha_B: Optional recombination coefficient in units of cm^3 s^-1. In alpha_B=None, it is calculated from temp_gas. clump_fact_func: function Function returning the clumping factor when given a redshift. cosmo: dict Dictionary specifying the cosmological parameters. We assume, as is fairly standard, that the ionized fraction is contained in fully ionized bubbles surrounded by a fully neutral IGM. The output is therefore the volume filling factor of ionized regions, not the ionized fraction of a uniformly-ionized IGM. I have also made the standard assumption that all ionized photons are immediately absorbed, which allows the two differential equations (one for ionization-recombination and one for emission-photoionizaion) to be combined into a single ODE. """ # Determine recombination coefficient. if alpha_B is None: alpha_B_cm = recomb_rate_coeff_HG(temp_gas, 'H', 'B') else: alpha_B_cm = alpha_B alpha_B = alpha_B_cm / (cc.Mpc_cm**3.) print("Recombination rate alpha_B = %.4g (Mpc^3 s^-1) = %.4g (cm^3 s^-1)" % (alpha_B, alpha_B_cm)) # Normalize power spectrum. if 'deltaSqr' not in cosmo: cosmo['deltaSqr'] = cp.norm_power(**cosmo) # Calculate useful densities. rho_crit, rho_0, n_He_0, n_H_0 = cden.baryon_densities(**cosmo) # Function used in the integration. # Units: (Mpc^3 s^-1) * Mpc^-3 = s^-1 coeff_rec_func = lambda z: (clump_fact_func(z)**2. * alpha_B * n_H_0 * (1. + z)**3.) # Generate a function that converts redshift to age of the universe. redfunc = cd.quick_redshift_age_function(zmax=1.1 * numpy.max(z), zmin=-0.0, **cosmo) # Function used in the integration. ionfunc = quick_ion_col_function(coeff_ion, temp_min, passed_min_mass=passed_min_mass, zmax=1.1 * numpy.max(z), zmin=-0.0, zstep=0.1, **cosmo) # Convert specified redshifts to cosmic time (age of the universe). t = cd.age(z, **cosmo) # Integrate to find u(z) = x(z) - w(z), where w is the ionization fraction u = si.odeint(_udot, y0=0.0, t=t, args=(coeff_rec_func, redfunc, ionfunc)) u = u.flatten() w = ionization_from_collapse(z, coeff_ion, temp_min, passed_min_mass=passed_min_mass, **cosmo) x = u + w x[x > 1.0] = 1.0 return x, w, t
def current_age(snapshot): import cosmolopy.distance as cd import cosmolopy.constants as cc cosmo = snapshot.cosmo return cd.age(**cosmo) / cc.Gyr_s # Gyr
da = cd.angular_diameter_distance(z[i],**Cosmology) #See equations 18-19 of David Hogg's arXiv:astro-ph/9905116v4 dl = cd.luminosity_distance(z[i],**Cosmology) #Units are Mpc dVc = cd.diff_comoving_volume(z[i], **Cosmology) #The differential comoving volume element dV_c/dz/dSolidAngle. #Dimensions are volume per unit redshift per unit solid angle. #Units are Mpc**3 Steradians^-1. #See David Hogg's arXiv:astro-ph/9905116v4, equation 28 tl = cd.lookback_time(z[i],**Cosmology) #See equation 30 of David Hogg's arXiv:astro-ph/9905116v4. Units are s. agetl = cd.age(z[i],**Cosmology) #Age at z is lookback time at z'->Infinity minus lookback time at z. tH = 3.09e17/Cosmology['h'] ez = cd.e_z(z[i],**Cosmology) #The unitless Hubble expansion rate at redshift z. #In David Hogg's (arXiv:astro-ph/9905116v4) formalism, this is #equivalent to E(z), defined in his eq. 14. if PlotNumber == 1: val[i] = dm/dh xtitle = "redshift z" ytitle = "Proper motion distance Dm/Dh" elif PlotNumber == 2: