from pNbody import *
from numpy import *

###############################
# Pseudo-isothermal profile
###############################

def pisothm_profile(r,rho0,rc):
  '''
  Pseudo-isothermal profile
  rho = 1/(1+(r/rc)**2)
  '''    
  return rho0/(1+(r/rc)**2)

def pisothm_mr(r,rho0,rc):
  '''
  Mass in the radius r for the distribution
  rho = 1/(1+(r/rc)**2)
  '''  
  return 4*pi*rho0 * rc**3 *(  r/rc - arctan( r/rc) )
    

###############################
# Plummer profile
###############################

def plummer_profile(r,rho0,rc):
  '''
  Plummer profile
  rho = 1/(1+(r/rc)**2)**(5/2)
  '''    
  return rho0/(1+(r/rc)**2)**(5./2.)

def plummer_mr(r,rho0,rc):
  '''
  Mass in the radius r for the distribution
  rho = 1/(1+(r/rc)**2)**(5/2)
  '''  
  return (4./3.)*pi*rho0*rc**3 * r**3/(r**2+rc**2)**(3./2.)  

###############################
# NFW profile
###############################

def nfw_profile(r,rhos,rs):
  '''
  NFW profile
  rho = rhos/((r/rs)*(1+r/rs)**2)
  '''    
  return rhos/((r/rs)*(1+r/rs)**2) 
  
def nfw_mr(r,rhos,rs):
  '''
  Mass in the radius r for the distribution
  rho = rhos/((r/rs)*(1+r/rs)**2)
  '''    
  return 4*pi*rhos*rs**3*( log(1.+r/rs) - r/(rs+r) ) 
  
  
  
###############################
# NFWg profile
###############################

def nfwg_profile(r,rhos,rs,gamma):
  '''
  NFW modified profile
  rho = rhos/((r/rs)**(gamma)*(1+(r/rs)**2)**(0.5*(3.-gamma)))
  '''    
  return rhos/ (  (r/rs)**(gamma) *  (1+ (r/rs)**2)**(0.5*(3.-gamma))   )
  
def nfw_mr(r,rhos,rs,gamma):
  '''
  Mass in the radius r for the distribution
  rho = rhos/((r/rs)*(1+r/rs)**2)
  '''    
  raise "nfw_mr : not implemented"
  
  
  
  
  
###############################
# NFW softened profile
###############################

def nfws_profile(r,rhos,rs,r0):
  '''
  NFW softened profile
  rho = rhos/(((r+r0)/rs)*(1+r/rs)**2)
  '''    
  return rhos/(((r+r0)/rs)*(1+r/rs)**2) 
  
def nfws_mr(r,rhos,rs,r0):
  '''
  Mass in the radius r for the distribution
  rho = rhos/((r/rs)*(1+r/rs)**2)
  '''    
  
  if r0==0:
    return nfw_mr(r,rhos,rs)

  # r=R
  rsr = rs+r
  rs0 = rs-r0
  rr0 = r+r0
    
  lnrr0 = log(rr0)
  lnrsr = log(rsr)
  
  I1 = 4*pi*rhos*rs**3*( r0**2*lnrr0*rsr + rs**2*lnrsr*rsr -2*r0*rs*lnrsr*rsr + rs**2*rs0  )/(rsr*rs0**2)
  
  # r=0
  rsr = rs
  rs0 = rs-r0
  rr0 = r0
    
  lnrr0 = log(rr0)
  lnrsr = log(rsr)
  
  I2 = 4*pi*rhos*rs**3*( r0**2*lnrr0*rsr + rs**2*lnrsr*rsr -2*r0*rs*lnrsr*rsr + rs**2*rs0  )/(rsr*rs0**2)
  
  return I1-I2
  
  
###############################
# Burkert profile
###############################


def burkert_profile(r,rho0,rs):
  '''
  Burkert profile
  rhob = rho0 / ( ( 1 + r/rs  ) * ( 1 + (r/rs)**2  ) )
  
  A. Burkert, Astrophys. J. 447 (1995) L25.
  '''    

  return rho0 / ( ( 1 + r/rs  ) * ( 1 + (r/rs)**2  ) )





###############################
# Pseudo isothermal profile
###############################


def pisotherm_profile(r,rho0,rs):
  '''
  Pseudo isothermal profile
  rhob = rho0/(1+(r/rs)**2)
  '''    

  return rho0 / (  ( 1 + (r/rs)**2  ) )

def pisotherm_mr(r,rho0,rs):
  '''
  Mass in the radius r for the distribution
  rhob = rho0/(1+(r/rs)**2)
  '''    
  
  return  4*pi*rho0*rs**3*(r/rs - atan(r/rs))
   



