def myloglike(cube, ndim, nparams): tmp_profs = Profiles(gp.pops, gp.nipol) off = 0 rho_param = np.array(cube[off:off+gp.nepol]) if gprio.check_nr(rho_param[2:-1]): print('dn/dr too big!') return gh.err(0.7) tmp_rho = phys.rho(gp.xepol, rho_param) if(gprio.check_rho(tmp_rho)): print('rho slope error') return gh.err(1.) tmp_profs.set_rho(tmp_rho[:gp.nipol]) tmp_profs.set_M(rho_SUM_Mr(gp.xepol, tmp_rho)[:gp.nipol]) # [munit,3D] # TODO: mass is set at binmax, not rbin! # implement integration routine working with density function # based on density parametrization # to give mass below rbin # TODO: implement above function as gl_project.rho_INT_Mr() off += gp.nepol nuparstore = [] for pop in np.arange(gp.pops)+1: nu_param = cube[off:off+gp.nepol] nuparstore.append(nu_param) tmp_nu = phys.rho(gp.xepol, nu_param) # [1], [pc] # if gprio.check_nu(tmp_nu): # print('nu error') # return err/2. if gp.bprior and gprio.check_bprior(tmp_rho, tmp_nu): print('bprior error') return gh.err(1.5) tmp_profs.set_nu(pop, tmp_nu[:gp.nipol]) # [munit/pc^3] off += gp.nepol beta_param = np.array(cube[off:off+gp.nbeta]) tmp_beta = phys.beta(gp.xipol, beta_param) if gprio.check_beta(tmp_beta): print('beta error') return gh.err(2.) tmp_profs.set_beta(pop, tmp_beta) off += gp.nbeta try: # beta_param = np.array([0.,0.]) sig, kap = phys.sig_kap_los(gp.xepol, pop, rho_param, nu_param, beta_param) # sig and kap already are on data radii only, so no extension by 3 bins here except Exception as detail: return gh.err(3.) tmp_profs.set_sig_kap(pop, sig, kap) # determine log likelihood (*not* reduced chi2) chi2 = gc.calc_chi2(tmp_profs, nuparstore) # print('found log likelihood = ', -chi2/2.) return -chi2/2. # from likelihood L = exp(-\chi^2/2), want log of that
def physical(r0, prof, pop, tmp_rho, tmp_nu, tmp_beta): if prof == "rho": tmp_prof = phys.rho(r0, tmp_rho) elif prof == 'nr': tmp_prof = tmp_rho[1:] elif prof == "nu": tmp_prof = rho_INT_Rho(r0, phys.rho(r0, tmp_nu)) elif prof == "betastar": tmp_prof = phys.mapping_beta_star_poly(r0, tmp_beta) elif prof == "beta": tmp_prof = phys.beta(r0, tmp_beta) elif prof == "sig": tmp_sig, tmp_kap = phys.sig_kap_los(r0, pop, tmp_rho, tmp_nu, tmp_beta) tmp_prof = tmp_sig elif prof == "kap": tmp_sig, tmp_kap = phys.sig_kap_los(r0, pop, tmp_rho, tmp_nu, tmp_beta) tmp_prof = tmp_kap return tmp_prof
def ant_intbeta(r0, betaparam): # extend beta by interpolating r0ext = [r0[0]/5.,r0[0]/4., r0[0]/3., r0[0]/2.] r0nu = np.hstack([r0ext, r0, r0[:-1]+(r0[1:]-r0[:-1])/2.]) r0nu.sort() betanu = phys.beta(r0nu, betaparam) # TODO: include beta parameter directly in integral! # TODO: or use more Stuetzpunkte tmp = np.zeros(len(betanu)) for i in range(5,len(betanu)): xint = r0nu[:i] # [lunit] yint = betanu[:i]/r0nu[:i] # [1/lunit] yint[0] = correct_first_bin(xint, yint, k=3, s=0, log=False) tmp[i] = 2.*simps(yint, xint, even=gp.even) # [1] tckout = splrep(r0nu[5:], tmp[5:], k=2) # TODO: safe? intbet = splev(r0, tckout) gh.checknan(intbet, 'intbet in ant_intbeta') return intbet # [1]
def ant_sigkaplos2surf(r0, beta_param, rho_param, nu_param): # TODO: check all values in ()^2 and ()^4 are >=0 minval = 1.e-30 r0nu = introduce_points_in_between(r0) rhonu = phys.rho(r0nu, rho_param) nunu = phys.rho(r0nu, nu_param) betanu = phys.beta(r0nu, beta_param) # calculate intbeta from beta approx directly idnu = ant_intbeta(r0nu, beta_param) # integrate enclosed 3D mass from 3D density r0tmp = np.hstack([0.,r0nu]) rhoint = 4.*np.pi*r0nu**2*rhonu # add point to avoid 0.0 in Mrnu(r0nu[0]) rhotmp = np.hstack([0.,rhoint]) tck1 = splrep(r0tmp, rhotmp, k=3, s=0.) # not necessarily monotonic Mrnu = np.zeros(len(r0nu)) # work in refined model for i in range(len(r0nu)): # get Mrnu Mrnu[i] = splint(0., r0nu[i], tck1) gh.checkpositive(Mrnu, 'Mrnu') # (sigr2, 3D) * nu/exp(-idnu) xint = r0nu # [pc] yint = gp.G1 * Mrnu / r0nu**2 # [1/pc (km/s)^2] yint *= nunu # [munit/pc^4 (km/s)^2] yint *= np.exp(idnu) # [munit/pc^4 (km/s)^2] gh.checkpositive(yint, 'yint sigr2') # use quadinflog or quadinfloglog here sigr2nu = np.zeros(len(r0nu)) for i in range(len(r0nu)): sigr2nu[i] = np.exp(-idnu[i])/nunu[i]*gh.quadinflog(xint, yint, r0nu[i], np.inf) # project back to LOS values # sigl2sold = np.zeros(len(r0nu)-gp.nexp) sigl2s = np.zeros(len(r0nu)-gp.nexp) dropoffintold = 1.e30 for i in range(len(r0nu)-gp.nexp): # get sig_los^2 xnew = np.sqrt(r0nu[i:]**2-r0nu[i]**2) # [pc] ynew = 2.*(1-betanu[i]*(r0nu[i]**2)/(r0nu[i:]**2)) ynew *= nunu[i:] * sigr2nu[i:] gh.checkpositive(ynew, 'ynew in sigl2s') # is hit several times.. # yscale = 10.**(1.-min(np.log10(ynew[1:]))) # ynew *= yscale # gh.checkpositive(ynew, 'ynew sigl2s') tcknu = splrep(xnew, ynew, k=1) # interpolation in real space for int # power-law approximation from last three bins to infinity # tckex = splrep(xnew[-3:], np.log(ynew[-3:]),k=1,s=1.0) # fine # invexp = lambda x: np.exp(splev(x,tckex,der=0)) # C = quad(invexp,xnew[-1],np.inf)[0] # C = max(0.,gh.quadinflog(xnew[-2:],ynew[-2:],xnew[-1],np.inf)) # sigl2sold[i] = splint(xnew[0], xnew[-1], tcknu) + C sigl2s[i] = gh.quadinflog(xnew[1:], ynew[1:], xnew[0], np.inf) # sigl2s[i] /= yscale # TODO: for last 3 bins, up to factor 2 off # if min(sigl2s)<0.: # pdb.set_trace() gh.checkpositive(sigl2s, 'sigl2s') # derefine on radii of the input vector tck = splrep(r0nu[:-gp.nexp], np.log(sigl2s), k=3, s=0.) sigl2s_out = np.exp(splev(r0, tck)) gh.checkpositive(sigl2s_out, 'sigl2s_out') if not gp.usekappa: # print('not using kappa') return sigl2s_out, np.ones(len(sigl2s_out)) # for the following: enabled calculation of kappa # TODO: include another set of anisotropy parameters beta_' # kappa_r^4 kapr4nu = np.ones(len(r0nu)-gp.nexp) xint = r0nu # [pc] yint = gp.G1 * Mrnu/r0nu**2 # [1/pc (km/s)^2] yint *= nunu # [munit/pc^4 (km/s)^2] yint *= sigr2nu # [munit/pc^4 (km/s)^4 yint *= np.exp(idnu) # [munit/pc^4 (km/s)^4] gh.checkpositive(yint, 'yint in kappa_r^4') yscale = 10.**(1.-min(np.log10(yint[1:]))) yint *= yscale # power-law extrapolation to infinity C = max(0., gh.quadinflog(xint[-3:], yint[-3:], r0nu[-1], np.inf)) # tckexp = splrep(xint[-3:],np.log(yint[-3:]),k=1,s=0.) # fine, exact interpolation # invexp = lambda x: np.exp(splev(x,tckexp,der=0)) # C = quad(invexp,r0nu[-1],np.inf)[0] tcknu = splrep(xint, yint, k=3) # interpolation in real space # TODO: for i in range(len(r0nu)-gp.nexp): # integrate from minimal radius to infinity kapr4nu[i] = 3.*(np.exp(-idnu[i])/nunu[i]) * \ (splint(r0nu[i], r0nu[-1], tcknu) + C) # [(km/s)^4] kapr4nu /= yscale gh.checkpositive(kapr4nu, 'kapr4nu in kappa_r^4') tcke = splrep(r0nu[:-gp.nexp], np.log(kapr4nu), k=3) kapr4ext = np.exp(splev(r0ext, tcke)) kapr4nu = np.hstack([kapr4nu, kapr4ext]) gh.checkpositive(kapr4nu, 'kapr4nu in extended kappa_r^4') tckbet = splrep(r0nu, betanu) dbetanudr = splev(r0nu, tckbet, der=1) gh.checknan(dbetanudr, 'dbetanudr in kappa_r^4') # kappa^4_los*surfdensity kapl4s = np.zeros(len(r0nu)-gp.nexp) # gpl.start(); gpl.yscale('linear') for i in range(len(r0nu)-gp.nexp): xnew = np.sqrt(r0nu[i:]**2-r0nu[i]**2) # [pc] ynew = g(r0nu[i:], r0nu[i], betanu[i:], dbetanudr[i:]) # [1] ynew *= nunu[i:] * kapr4nu[i:] # [TODO] # TODO: ynew could go negative here.. fine? #gpl.plot(xnew, ynew) #gh.checkpositive(ynew, 'ynew in kapl4s') #yscale = 10.**(1.-min(np.log10(ynew[1:]))) #ynew *= yscale # gpl.plot(xnew,ynew) C = max(0., gh.quadinflog(xnew[-3:], ynew[-3:], xnew[-1], np.inf)) tcknu = splrep(xnew,ynew) # not s=0.1, this sometimes gives negative entries after int kapl4s[i] = 2. * (splint(0., xnew[-1], tcknu) + C) #kapl4s[i] /= yscale # print('ynew = ',ynew,', kapl4s =', kapl4s[i]) # TODO: sometimes the last value of kapl4s is nan: why? gh.checkpositive(kapl4s, 'kapl4s in kappa_r^4') # project kappa4_los as well # only use middle values to approximate, without errors in center and far tck = splrep(r0nu[4:-gp.nexp], kapl4s[4:], k=3) # s=0. kapl4s_out = np.exp(splev(r0, tck)) gh.checkpositive(kapl4s_out, 'kapl4s_out in kappa_r^4') return sigl2s_out, kapl4s_out
def get_beta(self, pop): off = beta_offset(pop) return phys.beta(gp.xipol, self.cube[off:off+gp.nbeta])