Package ivs :: Package sed :: Module limbdark
[hide private]
[frames] | no frames]

Module limbdark

source code

Interface to the limb-darkening library.

Section 1. Basic interface

Retrieve limb darkening coeffcients and goodness of fit parameters:

>>> coefs,fac,ssr,idiff = get_coeffs(teff=10000,logg=4.0,'JOHNSON.V',law='claret')

When you need this for a large grid of parameters, consider using get_itable. The available laws are claret, linear, logarithmic, quadratic and power.

Retrieve a normalised passband-integrated limb darkening profile via:

>>> mu,intensities = get_limbdarkening(teff=10000,logg=4.0,photbands=['JOHNSON.V'],normalised=True)

and fit a particular law via:

>>> coeffs,ssr,idiff = fit_law(mu,intensities[:,0],law='claret',fitmethod='equidist_mu_leastsq')
>>> print(coeffs)
[ 2.00943266 -3.71261279  4.25469623 -1.70466934]

You can evaluate this law on a particular angle-sampling grid:

>>> mus = np.linspace(0,1,1000)
>>> mu_law = ld_claret(mus,coeffs)

Or on a disk-sampling grid:

>>> rs = np.linspace(0,1,1000)
>>> r_law = ld_claret(_mu(rs),coeffs)

Make a simple plot:

>>> p = pl.figure()
>>> p,q = pl.subplot(121),pl.title('Angle-sampled')
>>> p = pl.plot(mu,intensities,'ko-')
>>> p = pl.plot(mus,mu_law,'r-',lw=2)
>>> p,q = pl.subplot(122),pl.title('Disk-sampled')
>>> p = pl.plot(_r(mu),intensities,'ko-')
>>> p = pl.plot(rs,r_law,'r-',lw=2)

]include figure]]ivs_limbdark_basic.png]

Section 2. Fit comparison

You can fit a limb darkening law in various ways: using different laws, different optimizers and different x-coordinates (limb angle mu or radius). In the figure below, you can see the influence of some of these choices:

>>> p = pl.figure()
>>> laws = ['claret','linear','logarithmic','quadratic','power']
>>> fitmethods = ['equidist_mu_leastsq','equidist_r_leastsq','leastsq']
>>> r,rs = _r(mu),_r(mus)
>>> integ_mu = np.trapz(intensities[:,0],x=mu)
>>> integ_r = np.trapz(intensities[:,0],x=r)
>>> for i,fitmethod in enumerate(fitmethods):
...     p = pl.subplot(3,2,2*i+1)
...     p = pl.title(fitmethod)
...     p = pl.plot(mu,intensities[:,0],'ko-')
...     p = pl.xlabel('$\mu$ = cos(limb angle)')
...     p = pl.ylabel('Normalised intensity')
...     p = pl.subplot(3,2,2*i+2)
...     p = pl.title(fitmethod)
...     p = pl.plot(r,intensities[:,0],'ko-')
...     p = pl.xlabel('r')
...     p = pl.ylabel('Normalised intensity')
...     for law in laws:
...         cl,ssr,idiff = fit_law(mu,intensities[:,0],law=law,fitmethod=fitmethod)
...         print("{:12s} ({:19s}): {}".format(law,fitmethod,cl))
...         Imus = globals()['ld_{}'.format(law)](mus,cl)
...         p = pl.subplot(3,2,2*i+1)
...         idiff = (np.trapz(Imus,x=mus)-integ_mu)/integ_mu
...         p = pl.plot(mus,Imus,'-',lw=2,label="{} ({:.3f},{:.3f}%)".format(law,ssr,idiff*100))
...         p = pl.subplot(3,2,2*i+2)
...         idiff = (np.trapz(Imus,x=rs)-integ_r)/integ_r
...         p = pl.plot(rs,Imus,'-',lw=2,label="{} ({:.3f},{:.3}%)".format(law,ssr,idiff*100))
...     p = pl.subplot(3,2,2*i+1)
...     leg = pl.legend(loc='best',fancybox=True,prop=dict(size='small'))
...     leg.get_frame().set_alpha(0.5)
...     p = pl.subplot(3,2,2*i+2)
...     leg = pl.legend(loc='best',fancybox=True,prop=dict(size='small'))
...     leg.get_frame().set_alpha(0.5)
claret       (equidist_mu_leastsq): [ 2.00943266 -3.71261279  4.25469623 -1.70466934]
linear       (equidist_mu_leastsq): [ 0.48655636]
divide by zero encountered in log
invalid value encountered in multiply
logarithmic  (equidist_mu_leastsq): [ 0.6  0. ]
quadratic    (equidist_mu_leastsq): [ 0.21209044  0.36591797]
power        (equidist_mu_leastsq): [ 0.29025864]
claret       (equidist_r_leastsq ): [ 1.99805089 -3.04504952  3.02780048 -1.09105603]
linear       (equidist_r_leastsq ): [ 0.42641628]
logarithmic  (equidist_r_leastsq ): [ 0.6  0. ]
quadratic    (equidist_r_leastsq ): [ 0.28650391  0.24476527]
power        (equidist_r_leastsq ): [ 0.31195553]
claret       (leastsq            ): [  3.49169665  -8.96767096  11.16873314  -4.72869922]
linear       (leastsq            ): [ 0.57180245]
logarithmic  (leastsq            ): [ 0.6  0. ]
quadratic    (leastsq            ): [ 0.00717934  0.65416204]
power        (leastsq            ): [ 0.27032565]

]include figure]]ivs_limbdark_fitcomp.png]

Author: Pieter Degroote, with thanks to Steven Bloemen.

Functions [hide private]
    Interface to the library
 
set_defaults(**kwargs)
Set defaults of this module
source code
list of str
get_gridnames()
Return a list of available grid names.
source code
(ndarray,ndarray)
get_grid_dimensions(**kwargs)
Retrieve the possible effective temperatures and gravities from a grid.
source code
(3x1Darray,3Darray,interp_func)
get_grid_mesh(wave=None, teffrange=None, loggrange=None, **kwargs)
Return InterpolatingFunction spanning the available grid of atmosphere models.
source code
str
get_file(integrated=False, **kwargs)
Retrieve the filename containing the specified SED grid.
source code
array, array, array
get_table(teff=None, logg=None, ebv=None, vrad=None, star=None, wave_units='AA', flux_units='erg/cm2/s/AA/sr', **kwargs)
Retrieve the specific intensity of a model atmosphere.
source code
 
get_itable2(teff=None, logg=None, theta=None, mu=1, photbands=None, absolute=False, **kwargs)
mu=1 is center of disk
source code
 
get_limbdarkening(teff=None, logg=None, ebv=None, vrad=None, z=None, photbands=None, normalised=False, **kwargs)
Retrieve a limb darkening law for a specific star and specific bandpass.
source code
 
get_coeffs(teff, logg, photband, ebv=None, vrad=None, law='claret', fitmethod='equidist_r_leastsq')
Retrieve limb darkening coefficients on the fly.
source code
 
get_ld_grid_dimensions(**kwargs)
Returns the gridpoints of the limbdarkening grid (not unique values).
source code
 
intensity_moment(coeffs, ll=0, **kwargs)
Calculate the intensity moment (see Townsend 2003, eq.
source code
 
_get_itable_markers(photband, gridfile, teffrange=(-np.inf,np.inf), loggrange=(-np.inf,np.inf))
Get a list of markers to more easily retrieve integrated fluxes.
source code
    Limbdarkening laws
 
ld_eval(mu, coeffs)
Evaluate Claret's limb darkening law.
source code
 
ld_claret(mu, coeffs)
Claret's limb darkening law.
source code
 
ld_linear(mu, coeffs)
Linear or linear cosine law
source code
 
ld_nonlinear(mu, coeffs)
Nonlinear or logarithmic law
source code
 
ld_logarithmic(mu, coeffs)
Nonlinear or logarithmic law
source code
 
ld_quadratic(mu, coeffs)
Quadratic law
source code
 
ld_uniform(mu, coeffs)
Uniform law.
source code
 
ld_power(mu, coeffs)
Power law.
source code
    Fitting routines (thanks to Steven Bloemen)
 
fit_law(mu, Imu, law='claret', fitmethod='equidist_r_leastsq')
Fit an LD law to a sampled set of limb angles/intensities.
source code
 
fit_law_to_grid(photband, vrads=[0], ebvs=[0], zs=[0], law='claret', fitmethod='equidist_r_leastsq', **kwargs)
Gets the grid and fits LD law to all the models.
source code
 
generate_grid(photbands, vrads=[0], ebvs=[0], zs=[0], law='claret', fitmethod='equidist_r_leastsq', outfile='mygrid.fits', **kwargs) source code
    Internal functions
 
_r(mu)
Convert mu to r coordinates
source code
 
_mu(r_)
Convert r to mu coordinates
source code
 
ldres_fmin(coeffs, mu, Imu, law)
Residual function for Nelder-Mead optimizer.
source code
 
ldres_leastsq(coeffs, mu, Imu, law)
Residual function for Levenberg-Marquardt optimizer.
source code
 
_I_ls(ll, ss)
Limb darkening moments (Dziembowski 1977, Townsend 2002)
source code
 
get_ld_grid(photband, **kwargs)
Retrieve an interpolating grid for the LD coefficients
source code
Variables [hide private]
  logger = logging.getLogger("SED.LIMBDARK")
  defaults = dict(grid= 'kurucz', odfnew= False, z=+ 0.0, vturb=...
  basedir = 'ldtables'
Function Details [hide private]

set_defaults(**kwargs)

source code 

Set defaults of this module

If you give no keyword arguments, the default values will be reset.

get_gridnames()

source code 

Return a list of available grid names.

Returns: list of str
list of grid names

get_grid_dimensions(**kwargs)

source code 

Retrieve the possible effective temperatures and gravities from a grid.

Returns: (ndarray,ndarray)
effective temperatures, gravities

get_grid_mesh(wave=None, teffrange=None, loggrange=None, **kwargs)

source code 

Return InterpolatingFunction spanning the available grid of atmosphere models.

WARNING: the grid must be entirely defined on a mesh grid, but it does not need to be equidistant.

It is thus the user's responsibility to know whether the grid is evenly spaced in logg and teff (e.g. this is not so for the CMFGEN models).

You can supply your own wavelength range, since the grid models' resolution are not necessarily homogeneous. If not, the first wavelength array found in the grid will be used as a template.

It might take a long a time and cost a lot of memory if you load the entire grid. Therefor, you can also set range of temperature and gravity.

Parameters:
  • wave (ndarray) - wavelength to define the grid on
  • teffrange (tuple of floats) - starting and ending of the grid in teff
  • loggrange (tuple of floats) - starting and ending of the grid in logg
Returns: (3x1Darray,3Darray,interp_func)
wavelengths, teffs, loggs and fluxes of grid, and the interpolating function
Decorators:
  • @memoized

get_file(integrated=False, **kwargs)

source code 

Retrieve the filename containing the specified SED grid.

The keyword arguments are specific to the kind of grid you're using.

Basic keywords are 'grid' for the name of the grid, and 'z' for metallicity. For other keywords, see the source code.

Available grids and example keywords:

  • grid='kurucz93': * metallicity (z): m01 is -0.1 log metal abundance relative to solar (solar abundances from Anders and Grevesse 1989) * metallicity (z): p01 is +0.1 log metal abundance relative to solar (solar abundances from Anders and Grevesse 1989) * alpha enhancement (alpha): True means alpha enhanced (+0.4) * turbulent velocity (vturb): vturb in km/s * nover= True means no overshoot * odfnew=True means no overshoot but with better opacities and abundances
Parameters:
  • integrated (boolean) - choose integrated version of the grid
  • grid (str) - gridname (default Kurucz)
Returns: str
gridfile

get_table(teff=None, logg=None, ebv=None, vrad=None, star=None, wave_units='AA', flux_units='erg/cm2/s/AA/sr', **kwargs)

source code 

Retrieve the specific intensity of a model atmosphere.

ebv is reddening vrad is radial velocity: positive is redshift, negative is blueshift (km/s!)

extra kwargs are for reddening

You get limb angles, wavelength and a table. The shape of the table is (N_wave,N_mu).

WARNING: wave and flux units cannot be specificed for the moment.

>>> mu,wave,table = get_table(10000,4.0)
>>> p = pl.figure()
>>> ax1 = pl.subplot(221)
>>> p = pl.title('E(B-V)=0, vrad=0')
>>> ax = pl.gca()
>>> ax.set_color_cycle([pl.cm.spectral(i) for i in np.linspace(0,1,len(mu))])
>>> p = pl.loglog(wave,table)
>>> p = pl.xlim(700,15000)
>>> p = pl.ylim(1e3,1e8)
>>> mu,wave,table = get_table(10000,4.0,ebv=0.5)
>>> p = pl.subplot(222,sharex=ax1,sharey=ax1)
>>> p = pl.title('E(B-V)=0.5, vrad=0')
>>> ax = pl.gca()
>>> ax.set_color_cycle([pl.cm.spectral(i) for i in np.linspace(0,1,len(mu))])
>>> p = pl.loglog(wave,table)
>>> p = pl.xlim(700,15000)
>>> p = pl.ylim(1e3,1e8)
>>> mu,wave,table = get_table(10000,4.0,vrad=-1000.)
>>> p = pl.subplot(223,sharex=ax1,sharey=ax1)
>>> p = pl.title('E(B-V)=0., vrad=-10000.')
>>> ax = pl.gca()
>>> ax.set_color_cycle([pl.cm.spectral(i) for i in np.linspace(0,1,len(mu))])
>>> p = pl.loglog(wave,table)
>>> p = pl.xlim(700,15000)
>>> p = pl.ylim(1e3,1e8)
>>> mu,wave,table = get_table(10000,4.0,vrad=-1000.,ebv=0.5)
>>> p = pl.subplot(224,sharex=ax1,sharey=ax1)
>>> p = pl.title('E(B-V)=0.5, vrad=-10000.')
>>> ax = pl.gca()
>>> ax.set_color_cycle([pl.cm.spectral(i) for i in np.linspace(0,1,len(mu))])
>>> p = pl.loglog(wave,table)
>>> p = pl.xlim(700,15000)
>>> p = pl.ylim(1e3,1e8)
>>> mu,wave,table = get_table(10050,4.12)
>>> p = pl.figure()
>>> pl.gca().set_color_cycle([pl.cm.spectral(i) for i in np.linspace(0,1,len(mu))])
>>> p = pl.loglog(wave,table)
Parameters:
  • teff (float) - effective temperature (K)
  • logg (float) - log surface gravity (cgs, dex)
  • ebv (float) - reddening (mag)
  • vrad (float) - radial velocity (for doppler shifting) (km/s)
Returns: array, array, array
mu angles, wavelengths, table (Nwave x Nmu)

get_limbdarkening(teff=None, logg=None, ebv=None, vrad=None, z=None, photbands=None, normalised=False, **kwargs)

source code 

Retrieve a limb darkening law for a specific star and specific bandpass.

Possibility to include reddening via EB-V parameter. If not given, reddening will not be performed...

You choose your own reddening function.

See e.g. Heyrovsky et al., 2007

If you specify one angle (mu in radians), it will take the closest match from the grid.

Mu = cos(theta) where theta is the angle between the surface and the line of sight. mu=1 means theta=0 means center of the star.

Example usage:

>>> teff,logg = 5000,4.5
>>> mu,intensities = get_limbdarkening(teff=teff,logg=logg,photbands=['JOHNSON.V'])
Parameters:
  • teff (float) - effective temperature
  • logg (float) - logarithmic gravity (cgs)
  • system (string) - bandpass system
  • photbands (list of strings) - bandpass filters
  • ebv (float) - reddening coefficient
  • vrad (float) - radial velocity (+ is redshift, - is blueshift)
  • mu (float) - specificy specific angle

get_coeffs(teff, logg, photband, ebv=None, vrad=None, law='claret', fitmethod='equidist_r_leastsq')

source code 

Retrieve limb darkening coefficients on the fly.

This is particularly useful if you only need a few and speed is not really a problem (although this function is nearly instantaneous, looping over it will expose that it's actually pretty slow).

Parameters:
  • teff (float) - effective temperature
  • logg (float) - logarithmic gravity (cgs)
  • photbands (list of strings) - bandpass filters
  • ebv (float) - reddening coefficient
  • vrad (float) - radial velocity (+ is redshift, - is blueshift)

intensity_moment(coeffs, ll=0, **kwargs)

source code 

Calculate the intensity moment (see Townsend 2003, eq. 39).

Test analytical versus numerical implementation:

#>>> photband = 'JOHNSON.V' #>>> l,logg = 2.,4.0 #>>> gridfile = 'tables/ikurucz93_z0.0_k2_ld.fits' #>>> mu = np.linspace(0,1,100000) #>>> P_l = legendre(l)(mu) #>>> check = [] #>>> for teff in np.linspace(9000,12000,19): #... a1x,a2x,a3x,a4x,I_x1 = get_itable(gridfile,teff=teff,logg=logg,mu=1,photband=photband,evaluate=False) #... coeffs = [a1x,a2x,a3x,a4x,I_x1] #... Ix_mu = ld_claret(mu,coeffs) #... Ilx1 = I_x1*np.trapz(P_l*mu*Ix_mu,x=mu) #... a0x = 1 - a1x - a2x - a3x - a4x #... limb_coeffs = [a0x,a1x,a2x,a3x,a4x] #... Ilx2 = 0 #... for r,ar in enumerate(limb_coeffs): #... s = 1 + r/2. #... myIls = _I_ls(l,s) #... Ilx2 += ar*myIls #... Ilx2 = I_x1*Ilx2 #... Ilx3 = intensity_moment(teff,logg,photband,coeffs) #... check.append(abs(Ilx1-Ilx2)<0.1) #... check.append(abs(Ilx1-Ilx3)<0.1) #>>> np.all(np.array(check)) #True

Parameters:
  • teff (float) - effecitve temperature (K)
  • logg (float) - log of surface gravity (cgs)
  • ll (float) - degree of the mode
  • photband (list of strings ( or iterable container)) - photometric passbands
  • full_output (boolean) - if True, returns intensity, coefficients and integrals separately
Returns:
intensity moment

fit_law(mu, Imu, law='claret', fitmethod='equidist_r_leastsq')

source code 

Fit an LD law to a sampled set of limb angles/intensities.

In my (Pieter) experience, C{fitmethod='equidist_r_leastsq' seems
appropriate for the Kurucz models.

Make sure the intensities are normalised!

>>> mu,intensities = get_limbdarkening(teff=10000,logg=4.0,photbands=['JOHNSON.V'],normalised=True)
>>> p = pl.figure()
>>> p = pl.plot(mu,intensities[:,0],'ko-')
>>> cl,ssr,rdiff = fit_law(mu,intensities[:,0],law='claret')

>>> mus = np.linspace(0,1,1000)
>>> Imus = ld_claret(mus,cl)
>>> p = pl.plot(mus,Imus,'r-',lw=2)



@return: coefficients, sum of squared residuals,relative flux difference between prediction and model integrated intensity
@rtype: array, float, float

fit_law_to_grid(photband, vrads=[0], ebvs=[0], zs=[0], law='claret', fitmethod='equidist_r_leastsq', **kwargs)

source code 

Gets the grid and fits LD law to all the models.

Does not use mu=0 point in the fitting process.

_I_ls(ll, ss)

source code 

Limb darkening moments (Dziembowski 1977, Townsend 2002)

Recursive implementation.

>>> _I_ls(0,0.5)
0.6666666666666666
>>> _I_ls(1,0.5)
0.4
>>> _I_ls(2,0.5)
0.09523809523809523

get_ld_grid(photband, **kwargs)

source code 

Retrieve an interpolating grid for the LD coefficients

Check outcome:

#>>> bands = ['GENEVA.U', 'GENEVA.B', 'GENEVA.G', 'GENEVA.V'] #>>> f_ld_grid = get_ld_grid(bands) #>>> ff = pf.open(_atmos['file']) #>>> all(ff['GENEVA.U'].data[257][2:]==f_ld_grid(ff['GENEVA.U'].data[257][0],ff['GENEVA.U'].data[257][1])[0:5]) #True #>>> all(ff['GENEVA.G'].data[257][2:]==f_ld_grid(ff['GENEVA.G'].data[257][0],ff['GENEVA.G'].data[257][1])[10:15]) #True #>>> ff.close()

#Make some plots:

#>>> photband = ['GENEVA.V'] #>>> f_ld = get_ld_grid(photband) #>>> logg = 4.0 #>>> mu = linspace(0,1,100) #>>> p = figure() #>>> p = gcf().canvas.set_window_title('test of function <get_ld_grid>') #>>> for teff in linspace(9000,12000,19): #... out = f_ld(teff,logg) #... a1x,a2x,a3x,a4x, I_x1 = out.reshape((len(photband),5)).T #... p = subplot(221);p = title('Interpolation of absolute intensities') #... p = plot(teff,I_x1,'ko') #... p = subplot(222);p = title('Interpolation of LD coefficients') #... p = scatter(4*[teff],[a1x,a2x,a3x,a4x],c=range(4),vmin=0,vmax=3,cmap=cm.spectral,edgecolors='none') #... p = subplot(223);p = title('Without absolute intensity') #... p = plot(mu,ld_eval(mu,[a1x,a2x,a3x,a4x]),'-') #... p = subplot(224);p = title('With absolute intensity') #... p = plot(mu,I_x1*ld_eval(mu,[a1x,a2x,a3x,a4x]),'-')

Decorators:
  • @memoized

_get_itable_markers(photband, gridfile, teffrange=(-np.inf,np.inf), loggrange=(-np.inf,np.inf))

source code 

Get a list of markers to more easily retrieve integrated fluxes.

Decorators:
  • @memoized

Variables Details [hide private]

defaults

Value:
dict(grid= 'kurucz', odfnew= False, z=+ 0.0, vturb= 2, alpha= False, n\
over= False)