def lnprob_spherical_gNFW(pars, returnType='lnprob', model=None): cosinc, beta0, Ra, a, ml, logrho_s, rs, gamma = pars # remove a if you do not need it # print(pars) parsDic = { 'cosinc': cosinc, 'beta0': beta0, 'Ra': Ra, 'a': a, 'ml': ml, 'logrho_s': logrho_s, 'rs': rs, 'gamma': gamma } rst = {} if np.isinf(check_boundary(parsDic, boundary=model['boundary'])): rst['lnprob'] = -np.inf rst['chi2'] = np.inf rst['flux'] = None rst['rmsModel'] = None rst['dh'] = None return rst[returnType] lnpriorValue = lnprior(parsDic, prior=model['prior']) inc = np.arccos(cosinc) JAM = model['JAM'] dh = util_dm.gnfw1d(10**logrho_s, rs, gamma) dh_mge3d = dh.mge3d() rmsModel = JAM.run(inc, beta0, a, Ra, ml=ml, mge_dh=dh_mge3d, alpha=model['alpha']) chi2 = (((rmsModel[model['goodbins']] - model['rms'][model['goodbins']]) / model['errRms'][model['goodbins']])**2).sum() if np.isnan(chi2): print('Warning - JAM return nan value, beta0={:.2f} may not' ' be correct'.format(beta0)) rst['lnprob'] = -np.inf rst['chi2'] = np.inf rst['flux'] = None rst['rmsModel'] = None rst['dh'] = None return rst[returnType] rst['lnprob'] = -0.5 * chi2 + lnpriorValue rst['chi2'] = chi2 rst['flux'] = JAM.flux rst['rmsModel'] = rmsModel rst['dh'] = dh return rst[returnType]
def lnprob_spherical_gNFW_gradient(pars, returnType='lnprob', model=None): cosinc, beta, ml, logdelta, logrho_s, rs, gamma = pars # print pars parsDic = { 'cosinc': cosinc, 'beta': beta, 'ml': ml, 'logdelta': logdelta, 'logrho_s': logrho_s, 'rs': rs, 'gamma': gamma } rst = {} if np.isinf(check_boundary(parsDic, boundary=model['boundary'])): rst['lnprob'] = -np.inf rst['chi2'] = np.inf rst['flux'] = None rst['rmsModel'] = None rst['dh'] = None return rst[returnType] lnpriorValue = lnprior(parsDic, prior=model['prior']) inc = np.arccos(cosinc) Beta = np.zeros(model['lum2d'].shape[0]) + beta sigma = model['pot2d'][:, 1] / model['Re_arcsec'] ML = util_mge.ml_gradient_gaussian(sigma, 10**logdelta, ml0=ml) JAM = model['JAM'] dh = util_dm.gnfw1d(10**logrho_s, rs, gamma) dh_mge3d = dh.mge3d() rmsModel = JAM.run(inc, Beta, ml=ML, mge_dh=dh_mge3d) chi2 = (((rmsModel[model['goodbins']] - model['rms'][model['goodbins']]) / model['errRms'][model['goodbins']])**2).sum() if np.isnan(chi2): print('Warning - JAM return nan value, beta={:.2f} may not' ' be correct'.format(beta)) rst['lnprob'] = -np.inf rst['chi2'] = np.inf rst['flux'] = None rst['rmsModel'] = None rst['dh'] = None return rst[returnType] rst['lnprob'] = -0.5 * chi2 + lnpriorValue rst['chi2'] = chi2 rst['flux'] = JAM.flux rst['rmsModel'] = rmsModel rst['dh'] = dh return rst[returnType]
def main(): '--------------------------------------------------' # create the true density profiles r = np.logspace(np.log10(0.6), np.log10(10.0), 20) mge2d, dist, xbin, ybin, rms, erms = np.load('data/mock_sgnfw_data.npy') mgeStellar = util_mge.mge(mge2d, inc=np.radians(85.0), dist=dist) profileStellar = np.zeros_like(r) for i in range(len(r)): profileStellar[i] = (3.8 * mgeStellar.meanDensity(r[i]*1e3)) * 1e9 logrho_s = 5.8 + np.log10(3.8) rs = 40.0 gamma = -1.2 dh = util_dm.gnfw1d(10**logrho_s, rs, gamma) profileDark = dh.densityProfile(r) profileTotal = profileDark + profileStellar true = {'stellarDens': np.log10(profileStellar), 'darkDens': np.log10(profileDark), 'totalDens': np.log10(profileTotal), 'r': r} '--------------------------------------------------' profile = util_profile.profile('mock_gNFW_out.dat', path='data', nlines=200) profile.plotProfiles(true=true, outpath='data') profile.save(outpath='data')
def __init__(self, name, path='.', burnin=0, nlines=200, r=None): super(profile, self).__init__(name, path=path, burnin=burnin, best='median') self.profiles = {} # dictionary containing profiles if r is None: r = np.logspace(np.log10(0.5), np.log10(100.0), 100) self.profiles['r'] = r # select a subchain to calculate density profile ntotal = self.flatchain.shape[0] step = ntotal // nlines if step == 0: print('Warning - nlines > total number of samples') step = 1 ii = np.zeros(ntotal, dtype=bool) ii[::step] = True self.profiles['nprofiles'] = ii.sum() if self.data['type'] in [ 'spherical_gNFW', 'spherical_gNFW_logml', 'spherical_gNFW_gas' ]: # Calculate stellar mass profiles stellarProfiles = np.zeros([len(r), ii.sum(), 2]) inc = np.arccos(self.flatchain[ii, 0].ravel()) if self.data['type'] == 'spherical_gNFW_logml': mls = 10**self.flatchain[ii, -4].ravel() else: mls = self.flatchain[ii, -4].ravel() mass, density = _extractProfile(self.LmMge, r) for i in range(ii.sum()): stellarProfiles[:, i, 0] = mls[i] * density stellarProfiles[:, i, 1] = mls[i] * mass self.profiles['stellar'] = stellarProfiles # Calculate dark matter profiles # if self.DmMge is None: # raise ValueError('No dark matter halo is found') darkProfiles = np.zeros_like(stellarProfiles) logrho_s = self.flatchain[ii, -3].ravel() rs = self.flatchain[ii, -2].ravel() gamma = self.flatchain[ii, -1].ravel() for i in range(ii.sum()): tem_dh = util_dm.gnfw1d(10**logrho_s[i], rs[i], gamma[i]) tem_mge = util_mge.mge(tem_dh.mge2d(), inc=inc[i]) mass, density = _extractProfile(tem_mge, r) darkProfiles[:, i, 0] = density darkProfiles[:, i, 1] = mass self.profiles['dark'] = darkProfiles totalProfiles = stellarProfiles + darkProfiles self.profiles['total'] = totalProfiles # elif self.data['type'] == 'spherical_gNFW_gradient': # # Calculate stellar mass profiles # stellarProfiles = np.zeros([len(r), ii.sum(), 2]) # inc = np.arccos(self.flatchain[ii, 0].ravel()) # mls = self.flatchain[ii, 2].ravel() # pot_ng = self.pot2d.copy() # pot_tem = np.zeros([1, 3]) # sigma = pot_ng[:, 1]/self.data['Re_arcsec'] # logdelta = self.flatchain[ii, 3].ravel() # mass = np.zeros([len(r), pot_ng.shape[0]]) # density = np.zeros([len(r), pot_ng.shape[0]]) # for i in range(pot_ng.shape[0]): # pot_tem[:, :] = pot_ng[i, :] # mge_pot = util_mge.mge(pot_tem, inc=self.inc, # shape=self.shape, dist=self.dist) # mass[:, i], density[:, i] = _extractProfile(mge_pot, r) # for i in range(ii.sum()): # ML = util_mge.ml_gradient_gaussian(sigma, 10**logdelta[i], # ml0=mls[i]) # stellarProfiles[:, i, 0] = np.sum(ML * density, axis=1) # stellarProfiles[:, i, 1] = np.sum(ML * mass, axis=1) # self.profiles['stellar'] = stellarProfiles # # Calculate dark matter profiles # darkProfiles = np.zeros_like(stellarProfiles) # logrho_s = self.flatchain[ii, 4].ravel() # rs = self.flatchain[ii, 5].ravel() # gamma = self.flatchain[ii, 6].ravel() # for i in range(ii.sum()): # tem_dh = util_dm.gnfw1d(10**logrho_s[i], rs[i], gamma[i]) # tem_mge = util_mge.mge(tem_dh.mge2d(), inc=inc[i]) # mass, density = _extractProfile(tem_mge, r) # darkProfiles[:, i, 0] = density # darkProfiles[:, i, 1] = mass # self.profiles['dark'] = darkProfiles # totalProfiles = stellarProfiles + darkProfiles # self.profiles['total'] = totalProfiles # elif self.data['type'] == 'spherical_total_dpl': # self.profiles['stellar'] = None # self.profiles['dark'] = None # totalProfiles = np.zeros([len(r), ii.sum(), 2]) # inc = np.arccos(self.flatchain[ii, 0].ravel()) # logrho_s = self.flatchain[ii, 2].ravel() # rs = self.flatchain[ii, 3].ravel() # gamma = self.flatchain[ii, 4].ravel() # for i in range(ii.sum()): # tem_dh = util_dm.gnfw1d(10**logrho_s[i], rs[i], gamma[i]) # tem_mge = util_mge.mge(tem_dh.mge2d(), inc=inc[i]) # mass, density = _extractProfile(tem_mge, r) # totalProfiles[:, i, 0] = density # totalProfiles[:, i, 1] = mass # self.profiles['total'] = totalProfiles # elif self.data['type'] == 'oblate_total_dpl': # self.profiles['stellar'] = None # self.profiles['dark'] = None # totalProfiles = np.zeros([len(r), ii.sum(), 2]) # inc = np.arccos(self.flatchain[ii, 0].ravel()) # logrho_s = self.flatchain[ii, 2].ravel() # rs = self.flatchain[ii, 3].ravel() # gamma = self.flatchain[ii, 4].ravel() # q = self.flatchain[ii, 5].ravel() # for i in range(ii.sum()): # tem_dh = util_dm.gnfw2d(10**logrho_s[i], rs[i], gamma[i], q[i]) # tem_mge = util_mge.mge(tem_dh.mge2d(inc[i]), inc=inc[i]) # mass, density = _extractProfile(tem_mge, r) # totalProfiles[:, i, 0] = density # totalProfiles[:, i, 1] = mass # self.profiles['total'] = totalProfiles else: raise ValueError('model type {} not supported'.format( self.data['type'])) # add black hole mass if self.data['bh'] is not None: self.profiles['total'][:, :, 1] += self.data['bh'] # add gas component self.gas3d = self.data.get('gas3d', None) # calculate mass within Re Re_kpc = self.data['Re_arcsec'] * self.pc / 1e3 stellar_Re, dark_Re, total_Re, fdm_Re = self.enclosed3DMass(Re_kpc) MassRe = {} MassRe['Re_kpc'] = Re_kpc MassRe['stellar'] = np.log10(stellar_Re) MassRe['dark'] = np.log10(dark_Re) MassRe['total'] = np.log10(total_Re) MassRe['fdm'] = fdm_Re self.profiles['MassRe'] = MassRe
# Last Modified By : Hongyu Li <*****@*****.**> import numpy as np from contex import JAM import JAM.utils.util_dm as udm # import dark matter utility class import JAM.utils.util_mge as umge # import mge utility class import matplotlib.pyplot as plt r = np.logspace(np.log10(0.1), np.log10(100), 500) logr = np.log10(r) # 3 parameters for gNFW profile gamma = -1.0 # usually between [-2.0, 0.0] rs = 30.0 # [kpc] rho_s = 1e5 # [M_solar/kpc^2] (1[M_solar/kpc^3] = 1e9[M_solar/pc^3]) gnfw_dh = udm.gnfw1d(rho_s, rs, gamma) # initialize a gNFW class profile = np.log10(gnfw_dh.densityProfile(r)) # get the density profile mge2d = gnfw_dh.mge2d() # fit the density profile using MGE # initialize the MGE class using the MGE from dark halo mge = umge.mge(mge2d, np.pi / 2.0, shape='oblate') print('--------------------') print('Enclosed Mass within 10kpc (gNFW profile): {:.3e}'.format( gnfw_dh.enclosedMass(1.0))) print('Enclosed Mass within 10kpc (MGE approximation): {:.3e}'.format( mge.enclosed3Dluminosity(10.0 * 1e3)[0])) # here are some unit conversion profile_mge = np.log10(mge.luminosityDensity(r * 1e3, 0) * 1e9) # plot the density profile of the dark halo and the mge approximation line_dh, = plt.plot(logr, profile, 'k')
def lnprob_mge_gNFW(pars, model=None, returnType='lnprob'): logalpha, logrho_s, rs, gamma = pars parsDic = {'logalpha': logalpha, 'logrho_s': logrho_s, 'rs': rs, 'gamma': gamma} # check if parameters are in the boundary if not check_boundary(parsDic, boundary=model['boundary']): rst = {} rst['lnprob'] = -np.inf rst['chi2'] = np.inf rst['profiles'] = None return rst[returnType] # fit option fit = model['fit'] # observed total density profile, error and goodbins logrhoT = model['logrhoT'] logrhoTerr = model['logrhoTerr'] logMT = model['logMT'] logMTerr = model['logMTerr'] good = model['good'] # model stellar profile logrhoS = model['logrhoS_sps'] + logalpha logMS = model['logMS_sps'] + logalpha # model dark matter profile dh = util_dm.gnfw1d(10**logrho_s, rs, gamma) logrhoD = np.log10(dh.densityProfile(model['r'])) # logMD = np.zeros(len(logMS)) # for i in range(len(logMD)): # logMD[i] = np.log10(dh.enclosedMass(model['r'][i])) tem_mge = util_mge.mge(dh.mge2d(), inc=np.pi/2.0) logMD = np.log10(tem_mge.enclosed3Dluminosity(model['r']*1e3)) # model total profile logrhoTmodel = np.log10(10**logrhoS + 10**logrhoD) logMTmodel = np.log10(10**logMS + 10**logMD) chi2_dens = np.sum(((logrhoT[good] - logrhoTmodel[good]) / logrhoTerr[good])**2) chi2_mass = np.sum(((logMT[good] - logMTmodel[good]) / logMTerr[good])**2) if fit == 'dens': chi2 = chi2_dens elif fit == 'mass': chi2 = chi2_mass elif fit == 'all': chi2 = chi2_dens + chi2_mass else: raise ValueError('Invalid fit option {}'.format(fit)) if returnType == 'profiles': # tem_mge = util_mge.mge(dh.mge2d(), inc=np.pi/2.0) # logMD = np.log10(tem_mge.enclosed3Dluminosity(model['r']*1e3)) rst = {} rst['r'] = model['r'] rst['rho_star'] = logrhoS rst['rho_dark'] = logrhoD rst['rho_total'] = logrhoTmodel rst['M_star'] = logMS rst['M_dark'] = logMD rst['M_total'] = logMTmodel rst['chi2'] = chi2 rst['rho_total_obs'] = logrhoT rst['M_total_obs'] = logMT rst['good'] = good rst['pars'] = parsDic return rst elif returnType == 'lnprob': return -0.5*chi2 elif returnType == 'chi2': return chi2 else: raise KeyError('Invalid returnType {}'.format(returnType))