def kappa(r0fine, Mrfine, nufine, sigr2nu, intbetasfine, gp): # for the following: enabled calculation of kappa # kappa_r^4 kapr4nu = np.ones(len(r0fine)-gp.nexp) xint = r0fine # [pc] yint = gu.G1__pcMsun_1km2s_2 * Mrfine/r0fine**2 # [1/pc (km/s)^2] yint *= nufine # [Munit/pc^4 (km/s)^2] yint *= sigr2nu # [Munit/pc^4 (km/s)^4 yint *= np.exp(intbetasfine) # [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:], r0fine[-1], gp.rinfty*r0fine[-1])) splpar_nu = splrep(xint, yint, k=3) # interpolation in real space for k in range(len(r0fine)-gp.nexp): # integrate from minimal radius to infinity kapr4nu[k] = 3.*(np.exp(-intbetasfine[k])/nufine[k]) * \ (splint(r0fine[k], r0fine[-1], splpar_nu) + C) # [(km/s)^4] kapr4nu /= yscale gh.checkpositive(kapr4nu, 'kapr4nu in kappa_r^4') splpar_kap = splrep(r0fine[:-gp.nexp], np.log(kapr4nu), k=3) kapr4ext = np.exp(splev(r0ext, splpar_kap)) kapr4nu = np.hstack([kapr4nu, kapr4ext]) gh.checkpositive(kapr4nu, 'kapr4nu in extended kappa_r^4') dbetafinedr = splev(r0fine, splrep(r0fine, betafine), der=1) gh.checknan(dbetafinedr, 'dbetafinedr in kappa_r^4') # kappa^4_los*surfdensity kapl4s = np.zeros(len(r0fine)-gp.nexp) for k in range(len(r0fine)-gp.nexp): xnew = np.sqrt(r0fine[k:]**2-r0fine[k]**2) # [pc] ynew = g(r0fine[k:], r0fine[k], betafine[k:], dbetafinedr[k:]) # [1] ynew *= nufine[k:] * kapr4nu[k:] C = max(0., gh.quadinflog(xnew[-3:], ynew[-3:], xnew[-1], gp.rinfty*xnew[-1])) splpar_nu = splrep(xnew,ynew) # not s=0.1, this sometimes gives negative entries after int kapl4s[k] = 2. * (splint(0., xnew[-1], splpar_nu) + C) #kapl4s[k] /= yscale # LOG('ynew = ',ynew,', kapl4s =', kapl4s[k]) 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 kapl4s_out = np.exp(splev(r0, splrep(r0fine[4:-gp.nexp], kapl4s[4:], k=3))) # s=0. gh.checkpositive(kapl4s_out, 'kapl4s_out in kappa_r^4') return sigl2s_out, kapl4s_out
def rho_param_INT_Sig(r0, rhodmpar, pop, gp): # use splines on variable transformed integral # \Sigma(R) = \int_{r=R}^{R=\infty} \rho(r) d \sqrt(r^2-R^2) xmin = gp.xfine[0]/15. # needed, if not: loose on first 4 bins r0nu = gp.xfine rhonu = phys.rho(r0nu, rhodmpar, pop, gp) Sig = np.zeros(len(r0nu)-gp.nexp) for i in range(len(r0nu)-gp.nexp): xnew = np.sqrt(r0nu[i:]**2-r0nu[i]**2) # [lunit] ynew = 2.*rhonu[i:] # power-law extension to infinity C = gh.quadinflog(xnew[-gp.nexp:], ynew[-gp.nexp:], xnew[-1], gp.rinfty*xnew[-1]) Sig[i] = gh.quadinflog(xnew[1:], ynew[1:], xmin, xnew[-1]) + C # np.inf) gh.checkpositive(Sig, 'Sig in rho_param_INT_Sig') # interpolation onto r0 tck1 = splrep(np.log(gp.xfine[:-gp.nexp]), np.log(Sig)) Sigout = np.exp(splev(np.log(r0), tck1)) return Sigout
def rho_param_INT_Sig(r0, rhodmpar, pop, gp): # use splines on variable transformed integral # \Sigma(R) = \int_{r=R}^{R=\infty} \rho(r) d \sqrt(r^2-R^2) xmin = gp.xfine[0] / 15. # needed, if not: loose on first 4 bins r0nu = gp.xfine rhonu = phys.rho(r0nu, rhodmpar, pop, gp) Sig = np.zeros(len(r0nu) - gp.nexp) for i in range(len(r0nu) - gp.nexp): xnew = np.sqrt(r0nu[i:]**2 - r0nu[i]**2) # [lunit] ynew = 2. * rhonu[i:] # power-law extension to infinity C = gh.quadinflog(xnew[-gp.nexp:], ynew[-gp.nexp:], xnew[-1], gp.rinfty * xnew[-1]) Sig[i] = gh.quadinflog(xnew[1:], ynew[1:], xmin, xnew[-1]) + C # np.inf) gh.checkpositive(Sig, 'Sig in rho_param_INT_Sig') # interpolation onto r0 tck1 = splrep(np.log(gp.xfine[:-gp.nexp]), np.log(Sig)) Sigout = np.exp(splev(np.log(r0), tck1)) return Sigout
def nu_param_INT_Sig_disc(z0, nupar, pop, gp): # use splines on variable transformed integral # \Sigma(R) = \int_{r=0}^{R} \rho(r) dr z0nu = z0 nunu = phys.nu_decrease(z0nu, nupar, gp) Sig = np.zeros(len(z0nu)) for i in range(len(z0nu)): Sig[i] = gh.quadinflog(z0nu, nunu, z0nu[0], z0nu[i]) gh.checkpositive(Sig, 'Sig in nu_param_INT_Sig_disc') return Sig
def rho_param_INT_Sig_disc(z0, rhopar, pop, gp): # use splines on variable transformed integral # \Sigma(R) = \int_{r=0}^{R} \rho(r) dr xmin = z0[0]/30. # tweaked. z0[0]/1e4 gives error in quad() z0left = np.array([xmin, z0[0]*0.25, z0[0]*0.50, z0[0]*0.75]) z0nu = np.hstack([z0left, z0]) rhonu = phys.rho(z0nu, rhopar, pop, gp) # rho takes rho(rhalf) and n(r) parameters Sig = np.zeros(len(z0nu)-gp.nexp) for i in range(len(z0nu)-gp.nexp): Sig[i] = gh.quadinflog(z0nu, rhonu, xmin, z0nu[i]) gh.checkpositive(Sig, 'Sig in rho_param_INT_Sig_disc') return Sig[len(z0left):] # @z0 (z0nu without z0left, and without 3 extension bins)
def rho_param_INT_Sig_disc(z0, rhopar, pop, gp): # use splines on variable transformed integral # \Sigma(R) = \int_{r=0}^{R} \rho(r) dr xmin = z0[0] / 30. # tweaked. z0[0]/1e4 gives error in quad() z0left = np.array([xmin, z0[0] * 0.25, z0[0] * 0.50, z0[0] * 0.75]) z0nu = np.hstack([z0left, z0]) rhonu = phys.rho(z0nu, rhopar, pop, gp) # rho takes rho(rhalf) and n(r) parameters Sig = np.zeros(len(z0nu) - gp.nexp) for i in range(len(z0nu) - gp.nexp): Sig[i] = gh.quadinflog(z0nu, rhonu, xmin, z0nu[i]) gh.checkpositive(Sig, 'Sig in rho_param_INT_Sig_disc') return Sig[len( z0left):] # @z0 (z0nu without z0left, and without 3 extension bins)
def Jpar(R0, Sig, gp): if Sig[0] < 1e-100: return np.ones(len(R0)-gp.nexp) splpar_Sig = splrep(R0, np.log(Sig),k=1,s=0.1) # get spline in log space to circumvent flattening J = np.zeros(len(Sig)-gp.nexp) for i in range(len(Sig)-gp.nexp): xint = np.sqrt(R0[i:]**2-R0[i]**2) yint = np.exp(splev(np.sqrt(xint**2+R0[i]**2), splpar_Sig)) J[i] = gh.quadinflog(xint, yint, 0., gp.rinfty*max(gp.xepol)) #yf = lambda r: np.exp(splev(np.sqrt(r**2+R0[i]**2), splpar_Sig)) #J[i] = quad(yf, 0, np.inf)[0] # OLD: direct integration with integrand as fct of x #xint = R0[i:] #yint = Sig[i:]*R0[i:]/np.sqrt(R0[i:]**2-R0[i]**2) #J[i] = gh.quadinflog(xint[1:], yint[1:], R0[i], np.inf) gh.checkpositive(J) return J
def rho_INT_Sig(r0, rho, gp): # use splines on variable transformed integral # \Sigma(R) = \int_{r=R}^{R=\infty} \rho(r) d \sqrt(r^2-R^2) if rho[0] <= 1e-100: return np.zeros(gp.nepol) gh.checknan(rho, 'rho_INT_Sig') # >= 0.1 against rising in last bin. previous: k=2, s=0.1 # TODO: check use of np.log(r0) here splpar_rho = splrep(r0, np.log(rho), k=3, s=0.01) # 0.01? r0ext = np.array([0., r0[0] * 0.25, r0[0] * 0.50, r0[0] * 0.75]) #dR = r0[1:]-r0[:-1] r0nu = np.hstack([r0ext, r0]) # points in between possible, but not helping much: # ,dR*0.25+r0[:-1],dR*0.50+r0[:-1],dR*0.75+r0[:-1]]) r0nu.sort() rhonu = np.exp(splev(r0nu, splpar_rho)) # extend to higher radii splpar_lrhor = splrep(r0[-3:], np.log(rho[-3:]), k=1, s=1.) # k=2 gives NaN! dr0 = (r0[-1] - r0[-2]) / 8. r0ext = np.hstack( [r0[-1] + dr0, r0[-1] + 2 * dr0, r0[-1] + 3 * dr0, r0[-1] + 4 * dr0]) rhoext = np.exp(splev(r0ext, splpar_lrhor)) r0nu = np.hstack([r0nu, r0ext]) rhonu = np.hstack([rhonu, rhoext]) gh.checkpositive(rhonu, 'rhonu in rho_INT_Sig') Sig = np.zeros(len(r0nu) - 4) for i in range(len(r0nu) - 4): xnew = np.sqrt(r0nu[i:]**2 - r0nu[i]**2) # [lunit] ynew = 2. * rhonu[i:] yscale = 10.**(1. - min(np.log10(ynew))) ynew *= yscale # power-law extension to infinity C = gh.quadinflog(xnew[-4:], ynew[-4:], xnew[-1], gp.rinfty * max(gp.xepol)) splpar_nu = splrep( xnew, ynew, k=3) # interpolation in real space. previous: k=2, s=0.1 Sig[i] = splint(0., xnew[-1], splpar_nu) + C Sig /= yscale gh.checkpositive(Sig, 'Sig in rho_INT_Sig') Sigout = splev(r0, splrep(r0nu[:-4], Sig)) # [Munit/lunit^2] gh.checkpositive(Sigout, 'Sigout in rho_INT_Sig') return Sigout
def Jpar(R0, Sig, gp): if Sig[0] < 1e-100: return np.ones(len(R0) - gp.nexp) splpar_Sig = splrep( R0, np.log(Sig), k=1, s=0.1) # get spline in log space to circumvent flattening J = np.zeros(len(Sig) - gp.nexp) for i in range(len(Sig) - gp.nexp): xint = np.sqrt(R0[i:]**2 - R0[i]**2) yint = np.exp(splev(np.sqrt(xint**2 + R0[i]**2), splpar_Sig)) J[i] = gh.quadinflog(xint, yint, 0., gp.rinfty * max(gp.xepol)) #yf = lambda r: np.exp(splev(np.sqrt(r**2+R0[i]**2), splpar_Sig)) #J[i] = quad(yf, 0, np.inf)[0] # OLD: direct integration with integrand as fct of x #xint = R0[i:] #yint = Sig[i:]*R0[i:]/np.sqrt(R0[i:]**2-R0[i]**2) #J[i] = gh.quadinflog(xint[1:], yint[1:], R0[i], np.inf) gh.checkpositive(J) return J
def zeta(r0fine, nufine, Sigfine, Mrfine, betafine, sigr2nu, gp): # common parameters N = gh.Ntot(r0fine, Sigfine, gp) # vr2 = sigr2nu # dPhidr = gu.G1__pcMsun_1km2s_2*Mrfine/r0fine**2 # zetaa scalar #xint = r0fine #yint = nufine*(5-2*betafine)*vr2*dPhidr*r0fine**3 #nom = gh.quadinflog(xint, yint, 0., gp.rinfty*max(gp.xepol), False) #yint = nufine*dPhidr*r0fine**3 #denom = (gh.quadinflog(xint, yint, 0., gp.rinfty*max(gp.xepol), False))**2 theta = np.arccos(r0min/r0fine) cth = np.cos(theta) sth = np.sin(theta) # TODO calculate nuinterp, sigr2interp, Minterp, betainterp yint = gu.G1__pcMsun_1km2s_2*(5-2*betainterp)*sigr2 yint *= Minterp*rmin**2/cth**3*sth nom = quad(theta, yint, 0, np.pi/2) yint = gu.G1__pcMsun_1km2s_2**2*nuinterp*Mrinterp yint *= rmin**2/cth**3*sth denom = quad(theta, yint, 0, np.pi/2) zetaa = 9*N/10. * nom/denom # zetab scalar #------------------------------------------------------------ #yint = nufine*(7-6*betafine)*vr2*dPhidr*r0fine**5 #nom=gh.quadinflog(xint, yint, 0., gp.rinfty*max(gp.xepol), False) yint = gu.G1__pcMsun_1km2s_2*nuinterp*(7-6*betainterp)*sigr2interp*Mrinterp yint *= rmin**2/cth**3*sth nom = quad(theta, yint, 0, np.pi/2) yint = Sigfine*r0fine**3 denom *= gh.quadinflog(xint, yint, 0., gp.rinfty*max(gp.xepol), False) yint = Sigmainterp*Rmin**3/cth**6*sth denom *= quad(theta, yint, 0, np.pi/2) zetab = 9*N**2/35 * nom / denom return zetaa, zetab
def rho_INT_Sig(r0, rho, gp): # use splines on variable transformed integral # \Sigma(R) = \int_{r=R}^{R=\infty} \rho(r) d \sqrt(r^2-R^2) if rho[0] <= 1e-100: return np.zeros(gp.nepol) gh.checknan(rho, 'rho_INT_Sig') # >= 0.1 against rising in last bin. previous: k=2, s=0.1 # TODO: check use of np.log(r0) here splpar_rho = splrep(r0, np.log(rho), k=3, s=0.01) # 0.01? r0ext = np.array([0., r0[0]*0.25, r0[0]*0.50, r0[0]*0.75]) #dR = r0[1:]-r0[:-1] r0nu = np.hstack([r0ext,r0]) # points in between possible, but not helping much: # ,dR*0.25+r0[:-1],dR*0.50+r0[:-1],dR*0.75+r0[:-1]]) r0nu.sort() rhonu = np.exp(splev(r0nu, splpar_rho)) # extend to higher radii splpar_lrhor = splrep(r0[-3:],np.log(rho[-3:]),k=1,s=1.) # k=2 gives NaN! dr0 = (r0[-1]-r0[-2])/8. r0ext = np.hstack([r0[-1]+dr0, r0[-1]+2*dr0, r0[-1]+3*dr0, r0[-1]+4*dr0]) rhoext = np.exp(splev(r0ext, splpar_lrhor)) r0nu = np.hstack([r0nu, r0ext]) rhonu = np.hstack([rhonu, rhoext]) gh.checkpositive(rhonu, 'rhonu in rho_INT_Sig') Sig = np.zeros(len(r0nu)-4) for i in range(len(r0nu)-4): xnew = np.sqrt(r0nu[i:]**2-r0nu[i]**2) # [lunit] ynew = 2.*rhonu[i:] yscale = 10.**(1.-min(np.log10(ynew))) ynew *= yscale # power-law extension to infinity C = gh.quadinflog(xnew[-4:],ynew[-4:],xnew[-1], gp.rinfty*max(gp.xepol)) splpar_nu = splrep(xnew,ynew,k=3) # interpolation in real space. previous: k=2, s=0.1 Sig[i] = splint(0., xnew[-1], splpar_nu) + C Sig /= yscale gh.checkpositive(Sig, 'Sig in rho_INT_Sig') Sigout = splev(r0, splrep(r0nu[:-4], Sig)) # [Munit/lunit^2] gh.checkpositive(Sigout, 'Sigout in rho_INT_Sig') return Sigout
gh.checkpositive(Mrnu, 'Mrnu') Mr_hern = ga.M_hern(rfine, 1, 1) # (sigr2, 3D) * nu/exp(-idnu) xint = rfine # [pc] yint = G1 * Mrnu / rfine**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(rfine)) for i in range(len(rfine)): sigr2nu[i] = np.exp(-idnu[i])/nunu[i]*\ gh.quadinflog(xint, yint, rfine[i], gp.rinfty*rfine[-1], True) #if sigr2nu[i] == np.inf: # sigr2nu[i] = 1e-100 # last arg: warn if no convergence found gh.checkpositive(sigr2nu, 'sigr2nu in sigl2s') sigr2anf = ga.sigr2_hern(rfine, 1, 1, G1) # project back to LOS values # sigl2sold = np.zeros(len(rfine)-gp.nexp sigl2s = np.zeros(len(rfine)-gp.nexp) for i in range(len(rfine)-gp.nexp): # get sig_los^2 xnew = np.sqrt(rfine[i:]**2-rfine[i]**2) # [pc] ynew = 2.*(1-betanu[i]*(rfine[i]**2)/(rfine[i:]**2))