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.
|
|
list of str
|
|
(ndarray,ndarray)
|
|
(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
|
|
|
|
|
_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
|
|
|
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
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
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
|
|
|
|
|
logger = logging.getLogger("SED.LIMBDARK")
|
|
defaults = dict(grid= 'kurucz', odfnew= False, z=+ 0.0, vturb=...
|
|
basedir = 'ldtables'
|
Set defaults of this module
If you give no keyword arguments, the default values will be
reset.
|
Return a list of available grid names.
- Returns: list of str
- list of grid names
|
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:
|
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)
|
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.
|
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
|
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:
|
_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:
|
defaults
- Value:
dict(grid= 'kurucz', odfnew= False, z=+ 0.0, vturb= 2, alpha= False, n
over= False)
|
|