Ejemplo n.º 1
0
def rho_param_INT_Rho(r0, rhoparam):
    # use splines on variable transformed integral
    # \Sigma(R) = \int_{r=R}^{R=\infty} \rho(r) d \sqrt(r^2-R^2)
    # gh.checknan(rhoparam, 'rho_param_INT_Rho')

    xmin = r0[0]/1e4
    r0left = np.array([xmin, r0[0]*0.25, r0[0]*0.50, r0[0]*0.75])
    r0nu = np.hstack([r0left, r0])

    rhonu = phys.rho(r0nu, rhoparam)
    
    Rho = 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. TODO: include in Rho[i] below
        C = gh.quadinflog(xnew[-gp.nexp:], ynew[-gp.nexp:], xnew[-1], np.inf)
        # tcknu  = splrep(xnew, ynew, k=3)
        # interpolation in real space, not log space
        # problem: splint below could give negative values
        # reason:  for high radii (high i), have a spline that goes negative
        # workaround: multiply by const/add const to keep spline positive @ all times
        #             or set to log (but then integral is not straightforward
        # Rho[i] = splint(0., xnew[-1], tcknu) + C
        Rho[i] = gh.quadinfloglog(xnew[1:], ynew[1:], xmin, xnew[-1]) + C

    gh.checkpositive(Rho, 'Rho in rho_param_INT_Rho')
    return Rho[4:] # @r0 (r0nu without r0left)
Ejemplo n.º 2
0
def rho(r0, arr):
    rhoathalf = arr[0]
    arr = arr[1:]
    spline_n = nr(gp.xepol, arr) # fix on gp.xepol, as this is where definition is on

    rs =  np.log(r0/gp.rstarhalf) # have to integrate in d log(r)

    # check assumption r_min < rstarhalf < r_max
    if min(rs)>0. or max(rs)<0.:
        print('assumption r_min < rstarhalf < r_max violated')
        pdb.set_trace()
    logrright = rs[(rs>=0.)]
    logrleft  = rs[(rs<0.)]
    logrleft  = logrleft[::-1]
    logrhoright = []
    for i in np.arange(0, len(logrright)):
        logrhoright.append(np.log(rhoathalf) + \
                           splint(0., logrright[i], spline_n))
                           # TODO: integration along dlog(r) instead of dr?!

    logrholeft = []
    for i in np.arange(0, len(logrleft)):
        logrholeft.append(np.log(rhoathalf) + \
                          splint(0., logrleft[i], spline_n))

    tmp = np.exp(np.hstack([logrholeft[::-1], logrhoright])) # still defined on log(r)
    gh.checkpositive(tmp, 'rho()')
    return tmp
Ejemplo n.º 3
0
def calculate_surfdens(r, M):
    r0 = np.hstack([0,r])                         # [lunit]
    M0 = np.hstack([0,M])                         # [munit]

    deltaM = M0[1:]-M0[:-1]                       # [munit]
    gh.checkpositive(deltaM, 'unphysical negative mass increment encountered')
    
    deltavol = np.pi*(r0[1:]**2 - r0[:-1]**2)        # [lunit^2]
    Rho = deltaM/deltavol                           # [munit/lunit^2]
    gh.checkpositive(Rho, 'Rho in calculate_surfdens')
    return Rho                                      # [munit/lunit^2]
Ejemplo n.º 4
0
def calculate_rho(r, M):
    r0 = np.hstack([0,r])                         # [lunit]
    M0 = np.hstack([0,M])

    deltaM   = M0[1:]-M0[:-1]                     # [munit]
    gh.checkpositive(deltaM,  'unphysical negative mass increment encountered')

    deltavol = 4./3.*np.pi*(r0[1:]**3-r0[:-1]**3) # [lunit^3]
    rho     = deltaM / deltavol                  # [munit/lunit^3]
    gh.checkpositive(rho, 'rho in calculate_rho')
    return rho                                   # [munit/lunit^3]
Ejemplo n.º 5
0
def rho_INTDIRECT_Rho(r0, rho):
    # use splines, spline derivative to go beyond first radial point
    tck0 = splrep(r0,np.log(rho),k=3,s=0.1) # >= 0.1 against rising in last bin. previous: k=2, s=0.1
    # more points to the left help, but not so much
    r0ext = np.array([0.,r0[0]/6.,r0[0]/5.,r0[0]/4.,\
                      r0[0]/3.,r0[0]/2.,r0[0]/1.5])
    
    # introduce new points in between
    dR = r0[1:]-r0[:-1]
    r0nu = np.hstack([r0ext,r0,dR/4.+r0[:-1],dR/2.+r0[:-1],.75*dR+r0[:-1]])
    r0nu.sort()
    rhonu = np.exp(splev(r0nu,tck0))

    # extend to higher radii
    tckr = splrep(r0[-3:],np.log(rho[-3:]),k=1,s=0.2) # previous: k=2
    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,tckr))
    r0nu = np.hstack([r0nu, r0ext]);    rhonu = np.hstack([rhonu, rhoext])

    Rho = np.zeros(len(r0nu)-4)
    for i in range(len(r0nu)-4):
        xint = r0nu[i:]         # [lunit]
        yint = np.ones(len(xint))
        for j in range(i+1,len(r0nu)):
            yint[j-i] = r0nu[j] * rhonu[j]/np.sqrt(r0nu[j]**2-r0nu[i]**2) 
            # [munit/lunit^3]

        # Cubic-spline extrapolation to first bin
        tck = splrep(xint[1:],np.log(yint[1:]),k=3,s=0.)
        xnew = xint
        ynew = np.hstack([np.exp(splev(xnew[0],tck,der=0)),yint[1:]])
        # gpl.start(); pdb.set_trace()

        # power-law extension to infinity
        tck = splrep(xint[-4:],np.log(yint[-4:]),k=1,s=1.)
        invexp = lambda x: np.exp(splev(x,tck,der=0))
        dropoffint = quad(invexp,r0nu[-1],np.inf)
        tcknu = splrep(xnew,ynew,s=0) # interpolation in real space
        Rho[i] = 2. * (splint(r0nu[i], r0nu[-1], tcknu) + dropoffint[0])

        # gpl.plot(r0nu[:-4], Rho, '.', color='green')
    tcke = splrep(r0nu[:-4],Rho)
    Rhoout = splev(r0,tcke)     # [munit/lunit^2]

    # TODO: debug: raise Rho overall with factor 1.05?!
    gh.checkpositive(Rhoout, 'Rhoout in rho_INTDIRECT_Rho')
    # [munit/lunit^2]
    return Rhoout
Ejemplo n.º 6
0
def Rho_INT_rho(R0, Rho):
    # TODO: deproject with variable transformed, x = sqrt(r^2-R^2)
    # TODO: any good? have 1/x in transformation, for x=0 to infty
    pnts = len(Rho)                    # [1]

    # use splines, spline derivative to go beyond first radial point
    tck0 = splrep(R0,np.log(Rho),s=0.01)
    R0ext = np.array([R0[0]/6.,R0[0]/5.,R0[0]/4.,R0[0]/3.,R0[0]/2.,R0[0]/1.5])
    
    # introduce new points in between
    R0nu = np.hstack([R0ext,R0,(R0[1:]-R0[:-1])/2.+R0[:-1]])
    R0nu.sort()
    Rhonu = np.exp(splev(R0nu,tck0))
    
    # extend to higher radii
    tckr = splrep(R0[-3:],np.log(Rho[-3:]),k=1,s=0.3) # previous: k=2, s=0.1
    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,tckr))

    R0nu = np.hstack([R0nu, R0ext])
    Rhonu = np.hstack([Rhonu, Rhoext])
    gh.checkpositive(Rhonu, 'Rhonu in Rho_INT_rho')
    # gpl.start(); pdb.set_trace()
    tck1 = splrep(R0nu,Rhonu,k=3,        s=0.)
    # TODO: adapt s for problem at hand ==^
    dnubydR = splev(R0nu,tck1,der=1)
    # Rhofit = np.exp(splev(R0nu,tck1))   # debug for outer part

    rho = np.zeros(len(R0nu)-4)
    for i in range(len(R0nu)-4):
        xint = R0nu[i:]         # [lunit]
        yint = np.ones(len(xint))
        for j in range(i+1,len(R0nu)):
            yint[j-i] = dnubydR[j]/np.sqrt(R0nu[j]**2-R0nu[i]**2)
            # [munit/lunit^3/lunit]

        # Cubic-spline extrapolation to first bin
        tck = splrep(xint[1:],yint[1:],k=3,s=0.01)
        xnew = xint
        ynew = splev(xnew,tck,der=0)
        tcknu = splrep(xnew,ynew,s=0) # interpolation in real space
        rho[i] = -1./np.pi * splint(0.,max(R0)*2.,tcknu)
    tcke = splrep(R0nu[:-4],rho)
    rhoout = splev(R0,tcke)     # [munit/lunit^3]
    return rhoout               # [munit/lunit^3]
Ejemplo n.º 7
0
def rho_INT_Rho(r0, rho):
    # use splines on variable transformed integral
    # \Sigma(R) = \int_{r=R}^{R=\infty} \rho(r) d \sqrt(r^2-R^2)
    gh.checknan(rho, 'rho_INT_Rho')

    # >= 0.1 against rising in last bin. previous: k=2, s=0.1
    tck0 = splrep(r0,np.log(rho),k=3,s=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,tck0))

    # extend to higher radii
    tckr   = 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,tckr))
    r0nu   = np.hstack([r0nu, r0ext])
    rhonu  = np.hstack([rhonu, rhoext])
    gh.checkpositive(rhonu, 'rhonu in rho_INT_Rho')
    
    Rho = 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],np.inf)
        #print('C[',i,'] = ',C)
        tcknu  = splrep(xnew,ynew,k=3) # interpolation in real space. previous: k=2, s=0.1
        Rho[i] = splint(0., xnew[-1], tcknu) + C

    Rho /= yscale
    gh.checkpositive(Rho, 'Rho in rho_INT_Rho')
    # gpl.plot(r0nu[:-4],Rho,'.')
    tcke = splrep(r0nu[:-4], Rho)
    Rhoout = splev(r0, tcke)     # [munit/lunit^2]

    gh.checkpositive(Rhoout, 'Rhoout in rho_INT_Rho')
    return Rhoout
Ejemplo n.º 8
0
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