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

Module model

source code

Interface to the SED library.

The most basic usage of this module is:

>>> wave,flux = get_table(teff=10000,logg=4.0)

This will retrieve the model SED with the specified effective temperature and logg, from the standard grid, in standard units and with zero reddening. All these things can be specified though (see below).

Section 1. Available model grids

Section 1.1 Available grids

Section 1.2 Plotting the domains of all spectral grids

We make a plot of the domains of all spectral grids. Therefore, we first collect all the grid names

>>> grids = get_gridnames()

Preparation of the plot: set the color cycle of the current axes to the spectral color cycle.

>>> p = pl.figure(figsize=(10,8))
>>> color_cycle = [pl.cm.spectral(j) for j in np.linspace(0, 1.0, len(grids))]
>>> p = pl.gca().set_color_cycle(color_cycle)

To plot all the grid points, we run over all grid names (which are strings), and retrieve their dimensions. The dimensions are just two arrays giving the teff- and logg-coordinate of each SED in the grid. They can thus be easily plot:

>>> for grid in grids:
...    teffs,loggs = get_grid_dimensions(grid=grid)
...    p = pl.plot(np.log10(teffs),loggs,'o',ms=7,label=grid)

And we need to set some of the plotting details to make it look nicer.

>>> p = pl.xlim(pl.xlim()[::-1])
>>> p = pl.ylim(pl.ylim()[::-1])
>>> p = pl.xlabel('Effective temperature [K]')
>>> p = pl.ylabel('log( Surface gravity [cm s$^{-1}$]) [dex]')
>>> xticks = [3000,5000,7000,10000,15000,25000,35000,50000,65000]
>>> p = pl.xticks([np.log10(i) for i in xticks],['%d'%(i) for i in xticks])
>>> p = pl.legend(loc='upper left',prop=dict(size='small'))
>>> p = pl.grid()

]include figure]]ivs_sed_model_grid.png]

Section 2. Retrieval of model SEDs

Subsection 2.1 Default settings

To get information on the grid that is currently defined, you can type the following. Note that not all parameters are relevant for all grids, e.g. the convection theory parameter ct has no influence when the Kurucz grid is chosen.

>>> print defaults
{'use_scratch': False, 'Rv': 3.1, 'co': 1.05, 'c': 0.5, 'grid': 'kurucz', 'alpha': False, 'odfnew': True, 'ct': 'mlt', 'a': 0.0, 'vturb': 2, 'law': 'fitzpatrick2004', 'm': 1.0, 't': 1.0, 'z': 0.0, 'nover': False, 'He': 97}

or

>>> print os.path.basename(get_file())
kurucz93_z0.0_k2odfnew_sed.fits

You can change the defaults with the function set_defaults:

>>> set_defaults(z=0.5)
>>> print defaults
{'use_scratch': False, 'Rv': 3.1, 'co': 1.05, 'c': 0.5, 'grid': 'kurucz', 'alpha': False, 'odfnew': True, 'ct': 'mlt', 'a': 0.0, 'vturb': 2, 'law': 'fitzpatrick2004', 'm': 1.0, 't': 1.0, 'z': 0.5, 'nover': False, 'He': 97}

And reset the 'default' default values by calling set_defaults without arguments

>>> set_defaults()
>>> print defaults
{'use_scratch': False, 'Rv': 3.1, 'co': 1.05, 'c': 0.5, 'grid': 'kurucz', 'alpha': False, 'odfnew': True, 'ct': 'mlt', 'a': 0.0, 'vturb': 2, 'law': 'fitzpatrick2004', 'm': 1.0, 't': 1.0, 'z': 0.0, 'nover': False, 'He': 97}

Subsection 2.2 Speeding up

When fitting an sed using the builder class, or repeatedly reading model seds, or integrated photometry, the main bottleneck on the speed will be the disk access This can be circumvented by using the scratch disk. To do this, call the function copy2scratch() after setting the default settings as explained above. f.x.:

>>> set_defaults(grid='kurucz', z=0.5)
>>> copy2scratch()

You have to do this every time you change a grid setting. This function creates a directory named 'your_username' on the scratch disk and works from there. So you won`t disturbed other users.

After the fitting process use the function

>>> clean_scratch()

to remove the models that you used from the scratch disk. Be carefull with this, because it will remove the models without checking if there is another process using them. So if you have multiple scripts running that are using the same models, only clean the scratch disk after the last process is finished.

The gain in speed can be up to 70% in single sed fitting, and up to 40% in binary and multiple sed fitting.

For the sake of the examples, we'll set the defaults back to z=0.0:

>>> set_defaults()

Subsection 2.3 Model SEDs

Be careful when you supply parameters: e.g., not all grids are calculated for the same range of metallicities. In get_table, only the effective temperature and logg are 'interpolatable' quantities. You have to set the metallicity to a grid value. The reddening value can take any value: it is not interpolated but calculated. You can thus also specify the type of reddening law (see reddening).

>>> wave,flux = get_table(teff=12345,logg=4.321,ebv=0.12345,z=0.5)

but

>>> try:
...     wave,flux = get_table(teff=12345,logg=4.321,ebv=0.12345,z=0.6)
... except IOError,msg:
...     print msg
File sedtables/modelgrids/kurucz93_z0.6_k2odfnew_sed.fits not found in any of the specified data directories /STER/pieterd/IVSDATA/, /STER/kristofs/IVSdata

Since the Kurucz model atmospheres have not been calculated for the value of z=0.6.

Instead of changing the defaults of this module with set_defaults, you can also give extra arguments to get_table to specify the grid you want to use. The default settings will not change in this case.

>>> wave,flux = get_table(teff=16321,logg=4.321,ebv=0.12345,z=0.3,grid='tlusty')

The default units of the SEDs are angstrom and erg/s/cm2/AA/sr. To change them, do:

>>> wave,flux = get_table(teff=16321,logg=4.321,wave_units='micron',flux_units='Jy/sr')

To remove the steradian from the units when you know the angular diameter of your star in milliarcseconds, you can do (we have to convert diameter to surface):

>>> ang_diam = 3.21 # mas
>>> scale = conversions.convert('mas','sr',ang_diam/2.)
>>> wave,flux = get_table(teff=9602,logg=4.1,ebv=0.0,z=0.0,grid='kurucz')
>>> flux *= scale

The example above is representative for the case of Vega. So, if we now calculate the synthetic flux in the GENEVA.V band, we should end up with the zeropoint magnitude of this band, which is close to zero:

>>> flam = synthetic_flux(wave,flux,photbands=['GENEVA.V'])
>>> print '%.3f'%(conversions.convert('erg/s/cm2/AA','mag',flam,photband='GENEVA.V')[0])
0.063

Compare this with the calibrated value

>>> print filters.get_info(['GENEVA.V'])['vegamag'][0]
0.061

Section 3. Retrieval of integrated photometry

Instead of retrieving a model SED, you can immediately retrieve pre-calculated integrated photometry. The benefit of this approach is that it is much faster than retrieving the model SED and then calculating the synthetic flux. Also, you can supply arbitrary metallicities within the grid boundaries, as interpolation is done in effective temperature, surface gravity, reddening and metallicity.

Note that also the reddening law is fixed now, you need to recalculate the tables for different parameters if you need them.

The massive speed-up is accomplished the following way: it may take a few tens of seconds to retrieve the first pre-integrated SED, because all available files from the specified grid will be loaded into memory, and a `markerarray' will be made allowing a binary search in the grid. This makes it easy to retrieve all models around the speficied point in N-dimensional space. Next, a linear interpolation method is applied to predict the photometric values of the specified point.

All defaults set for the retrieval of model SEDs are applicable for the integrated photometry tables as well.

When retrieving integrated photometry, you also get the absolute luminosity (integration of total SED) as a bonus. This is the absolute luminosity assuming the star has a radius of 1Rsol. Multiply by Rstar**2 to get the true luminosity.

Because photometric filters cannot trivially be assigned a wavelength to (see filters.eff_wave), by default, no wavelength information is retrieved. If you want to retrieve the effective wavelengths of the filters themselves (not taking into account the model atmospheres), you can give an extra keyword argument wave_units. If you want to take into account the model atmosphere, use filters.eff_wave.

>>> photbands = ['GENEVA.U','2MASS.J']
>>> fluxes,Labs = get_itable(teff=16321,logg=4.321,ebv=0.12345,z=0.123,photbands=photbands)
>>> waves,fluxes,Labs = get_itable(teff=16321,logg=4.321,ebv=0.12345,z=0.123,photbands=photbands,wave_units='AA')

Note that the integration only gives you fluxes, and is thus independent from the zeropoints of the filters (but dependent on the transmission curves). To get the synthetic magnitudes, you can do

>>> mymags = [conversions.convert('erg/s/cm2/AA','mag',fluxes[i],photband=photbands[i]) for i in range(len(photbands))]

The mags don't mean anything in this case because they have not been corrected for the distance to the star.

The retrieval of integrated photometry can go much faster if you want to do it for a whole set of parameters. The get_itable_pix function has a much more flexible, reliable and fast interpolation scheme. It is possible to interpolate also over doppler shift and interstellar Rv, as long as the grids have been computed before. See get_itable_pix for more information.

Subsection 3. Full example

We build an SED of Vega and compute synthetic magnitudes in the GENEVA and 2MASS bands.

These are the relevant parameters of Vega and photometric passbands

>>> ang_diam = 3.21 # mas
>>> teff = 9602
>>> logg = 4.1
>>> ebv = 0.0
>>> z = 0.0
>>> photbands = ['GENEVA.U','GENEVA.G','2MASS.J','2MASS.H','2MASS.KS']

We can compute (R/d) to scale the synthetic flux as

>>> scale = conversions.convert('mas','sr',ang_diam/2.)

We retrieve the SED

>>> wave,flux = get_table(teff=teff,logg=logg,ebv=ebv,z=z,grid='kurucz')
>>> flux *= scale

Then compute the synthetic fluxes, and compare them with the synthetic fluxes as retrieved from the pre-calculated tables

>>> fluxes_calc = synthetic_flux(wave,flux,photbands)
>>> wave_int,fluxes_int,Labs = get_itable(teff=teff,logg=logg,ebv=ebv,z=z,photbands=photbands,wave_units='AA')
>>> fluxes_int *= scale

Convert to magnitudes:

>>> m1 = [conversions.convert('erg/s/cm2/AA','mag',fluxes_calc[i],photband=photbands[i]) for i in range(len(photbands))]
>>> m2 = [conversions.convert('erg/s/cm2/AA','mag',fluxes_int[i],photband=photbands[i]) for i in range(len(photbands))]

And make a nice plot

>>> p = pl.figure()
>>> p = pl.loglog(wave,flux,'k-',label='Kurucz model')
>>> p = pl.plot(wave_int,fluxes_calc,'ro',label='Calculated')
>>> p = pl.plot(wave_int,fluxes_int,'bx',ms=10,mew=2,label='Pre-calculated')
>>> p = [pl.annotate('%s: %.3f'%(b,m),(w,f),color='r') for b,m,w,f in zip(photbands,m1,wave_int,fluxes_calc)]
>>> p = [pl.annotate('%s: %.3f'%(b,m),(w-1000,0.8*f),color='b') for b,m,w,f in zip(photbands,m2,wave_int,fluxes_int)]
>>> p = pl.xlabel('Wavelength [Angstrom]')
>>> p = pl.ylabel('Flux [erg/s/cm2/AA]')

]include figure]]ivs_sed_model_example.png]

Functions [hide private]
 
_get_itable_markers(photbands, teffrange=(-np.inf,np.inf), loggrange=(-np.inf,np.inf), ebvrange=(-np.inf,np.inf), zrange=(-np.inf,np.inf), include_Labs=True, clear_memory=True, **kwargs)
Get a list of markers to more easily retrieve integrated fluxes.
source code
 
_get_pix_grid(photbands, teffrange=(-np.inf,np.inf), loggrange=(-np.inf,np.inf), ebvrange=(-np.inf,np.inf), zrange=(-np.inf,np.inf), rvrange=(-np.inf,np.inf), vradrange=(-np.inf,np.inf), include_Labs=True, clear_memory=True, variables=['teff','logg','ebv','z','rv','vrad'], **kwargs)
Prepare the pixalted grid.
source code
 
_get_flux_from_table(fits_ext, photbands, index=None, include_Labs=True)
Retrieve flux and flux ratios from an integrated SED table.
source code
    Interface to library
 
set_defaults(*args, **kwargs)
Set defaults of this module
source code
 
set_defaults_multiple(*args)
Set defaults for multiple stars
source code
 
copy2scratch(**kwargs)
Copy the grids to the scratch directory to speed up the fitting process.
source code
 
clean_scratch(**kwargs)
Remove the grids that were copied to the scratch directory by using the function copy2scratch().
source code
 
defaults2str()
Convert the defaults to a string, e.g.
source code
 
defaults_multiple2str()
Convert the defaults to a string, e.g.
source code
list of str
get_gridnames(grid=None)
Return a list of available grid names.
source code
str
get_file(integrated=False, **kwargs)
Retrieve the filename containing the specified SED grid.
source code
 
_blackbody_input(fctn)
Prepare input and output for blackbody-like functions.
source code
array
blackbody(x, T, wave_units='AA', flux_units='erg/s/cm2/AA', disc_integrated=True, ang_diam=None)
Definition of black body curve.
source code
array
rayleigh_jeans(x, T, wave_units='AA', flux_units='erg/s/cm2/AA', disc_integrated=True, ang_diam=None)
Rayleigh-Jeans approximation of a black body.
source code
array
wien(x, T, wave_units='AA', flux_units='erg/s/cm2/AA', disc_integrated=True, ang_diam=None)
Wien approximation of a black body.
source code
(ndarray,ndarray)
get_table_single(teff=None, logg=None, ebv=None, rad=None, star=None, wave_units='AA', flux_units='erg/s/cm2/AA/sr', **kwargs)
Retrieve the spectral energy distribution of a model atmosphere.
source code
(ndarray,)ndarray,float
get_itable_single(teff=None, logg=None, ebv=0, z=0, rad=None, photbands=None, wave_units=None, flux_units='erg/s/cm2/AA/sr', **kwargs)
Retrieve the spectral energy distribution of a model atmosphere in photometric passbands.
source code
(ndarray,ndarray)
get_itable(photbands=None, wave_units=None, flux_units='erg/s/cm2/AA/sr', grids=None, **kwargs)
Retrieve the integrated spectral energy distribution of a combined model atmosphere.
source code
 
get_itable_single_pix(teff=None, logg=None, ebv=None, z=0, rv=3.1, vrad=0, photbands=None, wave_units=None, flux_units='erg/s/cm2/AA/sr', **kwargs)
Super fast grid interpolator.
source code
 
get_itable_pix(photbands=None, wave_units=None, flux_units='erg/s/cm2/AA/sr', grids=None, **kwargs)
Super fast grid interpolator for multiple tables, completely based on get_itable_pix.
source code
(ndarray,ndarray)
get_table(wave_units='AA', flux_units='erg/cm2/s/AA/sr', grids=None, full_output=False, **kwargs)
Retrieve the spectral energy distribution of a combined model atmosphere.
source code
(ndarray,ndarray)
get_grid_dimensions(**kwargs)
Retrieve possible effective temperatures and gravities from a grid.
source code
(ndarray,ndarray,ndarray)
get_igrid_dimensions(**kwargs)
Retrieve possible effective temperatures, surface gravities and reddenings from an integrated 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
    Calibration
list of str
list_calibrators(library='calspec')
Print and return the list of calibrators
source code
(ndarray,ndarray)
get_calibrator(name='alpha_lyr', version=None, wave_units=None, flux_units=None, library='calspec')
Retrieve a calibration SED
source code
 
read_calibrator_info(library='ngsl') source code
 
calibrate()
Calibrate photometry.
source code
    Synthetic photometry
ndarray
synthetic_flux(wave, flux, photbands, units=None)
Extract flux measurements from a synthetic SED (Fnu or Flambda).
source code
ndarray
synthetic_color(wave, flux, colors, units=None)
Construct colors from a synthetic SED.
source code
float
luminosity(wave, flux, radius=1.)
Calculate the bolometric luminosity of a model SED.
source code
Variables [hide private]
  new_scipy = False
  logger = logging.getLogger("SED.MODEL")
  caldir = os.sep.join(['sedtables', 'calibrators'])
  __defaults__ = dict(grid= 'kurucz', odfnew= True, z=+ 0.0, vtu...
  defaults = __defaults__.copy()
  defaults_multiple = [defaults.copy(), defaults.copy()]
  basedir = 'sedtables/modelgrids/'
  scratchdir = None
hash(x)
Function Details [hide private]

set_defaults(*args, **kwargs)

source code 

Set defaults of this module

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

copy2scratch(**kwargs)

source code 

Copy the grids to the scratch directory to speed up the fitting process. Files are placed in the directory: /scratch/uname/ where uname is your username.

This function checks the grids that are set with the functions set_defaults() and set_defaults_multiple(). Every time a grid setting is changed, this function needs to be called again.

Don`t forget to remove the files from the scratch directory after the fitting process is completed with clean_scratch()

It is possible to give z='*' and Rv='*' as an option; when you do that, the grids with all z, Rv values are copied. Don't forget to add that option to clean_scratch too!

clean_scratch(**kwargs)

source code 

Remove the grids that were copied to the scratch directory by using the function copy2scratch(). Be carefull with this function, as it doesn't check if the models are still in use. If you are running multiple scripts that use the same models, only clean the scratch disk after the last script is finnished.

defaults2str()

source code 

Convert the defaults to a string, e.g. for saving files.

defaults_multiple2str()

source code 

Convert the defaults to a string, e.g. for saving files.

get_gridnames(grid=None)

source code 

Return a list of available grid names.

If you specificy the grid's name, you get two lists: one with all available original, non-integrated grids, and one with the pre-calculated photometry.

Parameters:
  • grid (string) - name of the type of grid (optional)
Returns: list of str
list of grid names

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
  • grid='tlusty':
    • z: log10(Z/Z0)
  • grid='sdb_uli': metallicity and helium fraction (z, he=98)
  • grid='fastwind': no options
  • grid='wd_boris': no options
  • grid='stars': precomputed stars (vega, betelgeuse...)
  • grid='uvblue'
  • grid='marcs'
  • grid='marcs2'
  • grid='atlas12'
  • grid='tkachenko': metallicity z
  • grid='nemo': convection theory and metallicity (CM=Canuto and Mazzitelli 1991), (CGM=Canuto,Goldman,Mazzitelli 1996), (MLT=mixinglengththeory a=0.5)
  • grid='marcsjorissensp': high resolution spectra from 4000 to 25000 A of (online available) MARCS grid computed by A. Jorissen with turbospectrum v12.1.1 in late 2012, then converted to the Kurucz wavelength grid (by S. Bloemen and M. Hillen).
Parameters:
  • integrated (boolean) - choose integrated version of the gridcopy2scratch
  • grid (str) - gridname (default Kurucz)
Returns: str
gridfile

_blackbody_input(fctn)

source code 

Prepare input and output for blackbody-like functions.

If the user gives wavelength units and Flambda units, we only need to convert everything to SI (and back to the desired units in the end).

If the user gives frequency units and Fnu units, we only need to convert everything to SI ( and back to the desired units in the end).

If the user gives wavelength units and Fnu units, we need to convert the wavelengths first to frequency.

blackbody(x, T, wave_units='AA', flux_units='erg/s/cm2/AA', disc_integrated=True, ang_diam=None)

source code 

Definition of black body curve.

To get them into the same units as the Kurucz disc-integrated SEDs, they are multiplied by sqrt(2*pi) (set disc_integrated=True).

You can only give an angular diameter if disc_integrated is True.

To convert the scale parameter back to mas, simply do:

ang_diam = 2*conversions.convert('sr','mas',scale)

See decorator blackbody_input for details on how the input parameters are handled: the user is free to choose wavelength or frequency units, choose *which* wavelength or frequency units, and can even mix them. To be sure that everything is handled correctly, we need to do some preprocessing and unit conversions.

Be careful when, e.g. during fitting, scale contains an error: be sure to set the option unpack=True in the conversions.convert function!

>>> x = np.linspace(2.3595,193.872,500)
>>> F1 = blackbody(x,280.,wave_units='AA',flux_units='Jy',ang_diam=(1.,'mas'))
>>> F2 = rayleigh_jeans(x,280.,wave_units='micron',flux_units='Jy',ang_diam=(1.,'mas'))
>>> F3 = wien(x,280.,wave_units='micron',flux_units='Jy',ang_diam=(1.,'mas'))
>>> p = pl.figure()
>>> p = pl.subplot(121)
>>> p = pl.plot(x,F1)
>>> p = pl.plot(x,F2)
>>> p = pl.plot(x,F3)
>>> F1 = blackbody(x,280.,wave_units='AA',flux_units='erg/s/cm2/AA',ang_diam=(1.,'mas'))
>>> F2 = rayleigh_jeans(x,280.,wave_units='micron',flux_units='erg/s/cm2/AA',ang_diam=(1.,'mas'))
>>> F3 = wien(x,280.,wave_units='micron',flux_units='erg/s/cm2/AA',ang_diam=(1.,'mas'))
>>> p = pl.subplot(122)
>>> p = pl.plot(x,F1)
>>> p = pl.plot(x,F2)
>>> p = pl.plot(x,F3)
Parameters:
  • T - temperature, unit
  • wave_units (str (units)) - wavelength units (frequency or length)
  • flux_units (str (units)) - flux units (could be in Fnu-units or Flambda-units)
  • disc_integrated (bool) - if True, they are in the same units as Kurucz-disc-integrated SEDs
  • ang_diam ((value, unit)) - angular diameter (in mas or rad or something similar)
Returns: array
intensity
Decorators:
  • @_blackbody_input

rayleigh_jeans(x, T, wave_units='AA', flux_units='erg/s/cm2/AA', disc_integrated=True, ang_diam=None)

source code 

Rayleigh-Jeans approximation of a black body.

Valid at long wavelengths.

For input details, see blackbody.

Returns: array
intensity
Decorators:
  • @_blackbody_input

wien(x, T, wave_units='AA', flux_units='erg/s/cm2/AA', disc_integrated=True, ang_diam=None)

source code 

Wien approximation of a black body.

Valid at short wavelengths.

For input details, see blackbody.

Returns: array
intensity
Decorators:
  • @_blackbody_input

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

source code 

Retrieve the spectral energy distribution of a model atmosphere.

Wavelengths in A (angstrom) Fluxes in Ilambda = ergs/cm2/s/AA/sr, except specified via 'units',

If you give 'units', and /sr is not included, you are responsible yourself for giving an extra keyword with the angular diameter ang_diam, or other possibilities offered by the units.conversions.convert function.

Possibility to redden the fluxes according to the reddening parameter EB_V.

Extra kwargs can specify the grid type. Extra kwargs can specify constraints on the size of the grid to interpolate. Extra kwargs can specify reddening law types. Extra kwargs can specify information for conversions.

Example usage:

>>> from pylab import figure,gca,subplot,title,gcf,loglog
>>> p = figure(figsize=(10,6))
>>> p=gcf().canvas.set_window_title('Test of <get_table>')
>>> p = subplot(131)
>>> p = loglog(*get_table(grid='FASTWIND',teff=35000,logg=4.0),**dict(label='Fastwind'))
>>> p = loglog(*get_table(grid='KURUCZ',teff=35000,logg=4.0),**dict(label='Kurucz'))
>>> p = loglog(*get_table(grid='TLUSTY',teff=35000,logg=4.0),**dict(label='Tlusty'))
>>> p = loglog(*get_table(grid='MARCS',teff=5000,logg=2.0),**dict(label='Marcs'))
>>> p = loglog(*get_table(grid='KURUCZ',teff=5000,logg=2.0),**dict(label='Kurucz'))
>>> p = pl.xlabel('Wavelength [angstrom]');p = pl.ylabel('Flux [erg/s/cm2/AA/sr]')
>>> p = pl.legend(loc='upper right',prop=dict(size='small'))
>>> p = subplot(132)
>>> p = loglog(*get_table(grid='FASTWIND',teff=35000,logg=4.0,wave_units='micron',flux_units='Jy/sr'),**dict(label='Fastwind'))
>>> p = loglog(*get_table(grid='KURUCZ',teff=35000,logg=4.0,wave_units='micron',flux_units='Jy/sr'),**dict(label='Kurucz'))
>>> p = loglog(*get_table(grid='TLUSTY',teff=35000,logg=4.0,wave_units='micron',flux_units='Jy/sr'),**dict(label='Tlusty'))
>>> p = loglog(*get_table(grid='MARCS',teff=5000,logg=2.0,wave_units='micron',flux_units='Jy/sr'),**dict(label='Marcs'))
>>> p = loglog(*get_table(grid='KURUCZ',teff=5000,logg=2.0,wave_units='micron',flux_units='Jy/sr'),**dict(label='Kurucz'))
>>> p = pl.xlabel('Wavelength [micron]');p = pl.ylabel('Flux [Jy/sr]')
>>> p = pl.legend(loc='upper right',prop=dict(size='small'))
>>> p = subplot(133);p = title('Kurucz')
>>> p = loglog(*get_table(grid='KURUCZ',teff=10000,logg=4.0,wave_units='micron',flux_units='Jy/sr'),**dict(label='10000'))
>>> p = loglog(*get_table(grid='KURUCZ',teff=10250,logg=4.0,wave_units='micron',flux_units='Jy/sr'),**dict(label='10250'))
>>> p = loglog(*get_table(grid='KURUCZ',teff=10500,logg=4.0,wave_units='micron',flux_units='Jy/sr'),**dict(label='10500'))
>>> p = loglog(*get_table(grid='KURUCZ',teff=10750,logg=4.0,wave_units='micron',flux_units='Jy/sr'),**dict(label='10750'))
>>> p = loglog(*get_table(grid='KURUCZ',teff=11000,logg=4.0,wave_units='micron',flux_units='Jy/sr'),**dict(label='11000'))
>>> p = pl.xlabel('Wavelength [micron]');p = pl.ylabel('Flux [Jy/sr]')
>>> p = pl.legend(loc='upper right',prop=dict(size='small'))

]]include figure]]ivs_sed_model_comparison.png]

Parameters:
  • teff (float) - effective temperature
  • logg (float) - logarithmic gravity (cgs)
  • ebv (float) - reddening coefficient
  • wave_units (str) - units to convert the wavelengths to (if not given, A)
  • flux_units (str) - units to convert the fluxes to (if not given, erg/s/cm2/AA/sr)
Returns: (ndarray,ndarray)
wavelength,flux

get_itable_single(teff=None, logg=None, ebv=0, z=0, rad=None, photbands=None, wave_units=None, flux_units='erg/s/cm2/AA/sr', **kwargs)

source code 

Retrieve the spectral energy distribution of a model atmosphere in photometric passbands.

Wavelengths in A (angstrom). If you set 'wavelengths' to None, no effective wavelengths will be calculated. Otherwise, the effective wavelength is calculated taking the model flux into account. Fluxes in Ilambda = ergs/cm2/s/AA/sr, except specified via 'units',

If you give 'units', and /sr is not included, you are responsible yourself for giving an extra keyword with the angular diameter ang_diam, or other possibilities offered by the units.conversions.convert function.

Possibility to redden the fluxes according to the reddening parameter EB_V.

Extra kwargs can specify the grid type. Extra kwargs can specify constraints on the size of the grid to interpolate. Extra kwargs can specify reddening law types. Extra kwargs can specify information for conversions.

Parameters:
  • teff (float) - effective temperature
  • logg (float) - logarithmic gravity (cgs)
  • ebv (float) - reddening coefficient
  • photbands (list of photometric passbands) - photometric passbands
  • wave_units (str) - units to convert the wavelengths to (if not given, A)
  • flux_units (str) - units to convert the fluxes to (if not given, erg/s/cm2/AA/sr)
  • clear_memory (boolean) - flag to clear memory from previously loaded SED tables. If you set it to False, you can easily get an overloaded memory!
Returns: (ndarray,)ndarray,float
(wave,) flux, absolute luminosity

get_itable(photbands=None, wave_units=None, flux_units='erg/s/cm2/AA/sr', grids=None, **kwargs)

source code 

Retrieve the integrated spectral energy distribution of a combined model atmosphere.

>>> teff1,teff2 = 20200,5100
>>> logg1,logg2 = 4.35,2.00
>>> ebv = 0.2,0.2
>>> photbands = ['JOHNSON.U','JOHNSON.V','2MASS.J','2MASS.H','2MASS.KS']
>>> wave1,flux1 = get_table(teff=teff1,logg=logg1,ebv=ebv[0])
>>> wave2,flux2 = get_table(teff=teff2,logg=logg2,ebv=ebv[1])
>>> wave3,flux3 = get_table_multiple(teff=(teff1,teff2),logg=(logg1,logg2),ebv=ebv,radius=[1,20])
>>> iwave1,iflux1,iLabs1 = get_itable(teff=teff1,logg=logg1,ebv=ebv[0],photbands=photbands,wave_units='AA')
>>> iflux2,iLabs2 = get_itable(teff=teff2,logg=logg2,ebv=ebv[1],photbands=photbands)
>>> iflux3,iLabs3 = get_itable_multiple(teff=(teff1,teff2),logg=(logg1,logg2),z=(0,0),ebv=ebv,radius=[1,20.],photbands=photbands)
>>> p = pl.figure()
>>> p = pl.gcf().canvas.set_window_title('Test of <get_itable_multiple>')
>>> p = pl.loglog(wave1,flux1,'r-')
>>> p = pl.loglog(iwave1,iflux1,'ro',ms=10)
>>> p = pl.loglog(wave2,flux2*20**2,'b-')
>>> p = pl.loglog(iwave1,iflux2*20**2,'bo',ms=10)
>>> p = pl.loglog(wave3,flux3,'k-',lw=2)
>>> p = pl.loglog(iwave1,iflux3,'kx',ms=10,mew=2)
Parameters:
  • teff (tuple floats) - effective temperature
  • logg (tuple floats) - logarithmic gravity (cgs)
  • ebv (tuple floats) - reddening coefficient
  • z (tuple floats) - metallicity
  • radius (tuple of floats) - ratio of R_i/(R_{i-1})
  • photbands (list) - photometric passbands
  • flux_units (str) - units to convert the fluxes to (if not given, erg/s/cm2/AA/sr)
  • grids (list of dict) - specifications for grid1
  • full_output (boolean) - return all individual SEDs
Returns: (ndarray,ndarray)
wavelength,flux

get_itable_single_pix(teff=None, logg=None, ebv=None, z=0, rv=3.1, vrad=0, photbands=None, wave_units=None, flux_units='erg/s/cm2/AA/sr', **kwargs)

source code 

Super fast grid interpolator.

Possible kwargs are teffrange,loggrange etc.... that are past on to _get_pix_grid. You should probably use these options when you want to interpolate in many variables; supplying these ranges will make the grid smaller and thus decrease memory usage.

It is possible to fix teff, logg, ebv, z, rv and/or vrad to one value, in which case it has to be a point in the grid. If you want to retrieve a list of fluxes with the same ebv value that is not in the grid, you need to give an array with all equal values. The reason is that the script can try to minimize the number of interpolations, by fixing a variable on a grid point. The fluxes on the other gridpoints will then not be interpolated over. These parameter also have to be listed with the additional exc_interpolpar keyword.

>>> teffs = np.linspace(5000,7000,100)
>>> loggs = np.linspace(4.0,4.5,100)
>>> ebvs = np.linspace(0,1,100)
>>> zs = np.linspace(-0.5,0.5,100)
>>> rvs = np.linspace(2.2,5.0,100)
>>> set_defaults(grid='kurucz2')
>>> flux,labs = get_itable_pix(teffs,loggs,ebvs,zs,rvs,photbands=['JOHNSON.V'])
>>> names = ['teffs','loggs','ebvs','zs','rvs']
>>> p = pl.figure()
>>> for i in range(len(names)):
...     p = pl.subplot(2,3,i+1)
...     p = pl.plot(locals()[names[i]],flux[0],'k-')
...     p = pl.xlabel(names[i])

Thanks to Steven Bloemen for the core implementation of the interpolation algorithm.

The addition of the exc_interpolpar keyword was done by Michel Hillen (Jan 2016).

get_table(wave_units='AA', flux_units='erg/cm2/s/AA/sr', grids=None, full_output=False, **kwargs)

source code 

Retrieve the spectral energy distribution of a combined model atmosphere.

Example usage:

>>> teff1,teff2 = 20200,5100
>>> logg1,logg2 = 4.35,2.00
>>> wave1,flux1 = get_table(teff=teff1,logg=logg1,ebv=0.2)
>>> wave2,flux2 = get_table(teff=teff2,logg=logg2,ebv=0.2)
>>> wave3,flux3 = get_table_multiple(teff=(teff1,teff2),logg=(logg1,logg2),ebv=(0.2,0.2),radius=[1,20])
>>> p = pl.figure()
>>> p = pl.gcf().canvas.set_window_title('Test of <get_table_multiple>')
>>> p = pl.loglog(wave1,flux1,'r-')
>>> p = pl.loglog(wave2,flux2,'b-')
>>> p = pl.loglog(wave2,flux2*20**2,'b--')
>>> p = pl.loglog(wave3,flux3,'k-',lw=2)
Parameters:
  • teff (tuple floats) - effective temperature
  • logg (tuple floats) - logarithmic gravity (cgs)
  • ebv (tuple floats) - tuple reddening coefficients
  • radius (tuple of floats) - radii of the stars
  • wave_units (str) - units to convert the wavelengths to (if not given, A)
  • flux_units (str) - units to convert the fluxes to (if not given, erg/s/cm2/AA/sr)
  • grids (list of dict) - specifications for grid1
  • full_output (boolean) - return all individual SEDs
Returns: (ndarray,ndarray)
wavelength,flux

get_grid_dimensions(**kwargs)

source code 

Retrieve possible effective temperatures and gravities from a grid.

E.g. kurucz, sdB, fastwind...

Returns: (ndarray,ndarray)
effective temperatures, gravities

get_igrid_dimensions(**kwargs)

source code 

Retrieve possible effective temperatures, surface gravities and reddenings from an integrated grid.

E.g. kurucz, sdB, fastwind...

Returns: (ndarray,ndarray,ndarray)
effective temperatures, surface, gravities, E(B-V)s

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.

WARNING: 30000,50000 did not work out for FASTWIND, since we miss a model!

Example usage:

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

list_calibrators(library='calspec')

source code 

Print and return the list of calibrators

Parameters:
  • library (str) - name of the library (calspec, ngsl, stelib)
Returns: list of str
list of calibrator names

get_calibrator(name='alpha_lyr', version=None, wave_units=None, flux_units=None, library='calspec')

source code 

Retrieve a calibration SED

If version is None, get the last version.

Example usage:

>>> wave,flux = get_calibrator(name='alpha_lyr')
>>> wave,flux = get_calibrator(name='alpha_lyr',version='003')
Parameters:
  • name (str) - calibrator name
  • version (str) - version of the calibration file
  • wave_units (str (interpretable by units.conversions.convert)) - units of wavelength arrays (default: AA)
  • flux_units (str (interpretable by units.conversions.convert)) - units of flux arrays (default: erg/s/cm2/AA)
Returns: (ndarray,ndarray)
wavelength and flux arrays of calibrator

read_calibrator_info(library='ngsl')

source code 
Decorators:
  • @memoized

calibrate()

source code 

Calibrate photometry.

Not finished!

ABmag = -2.5 Log F_nu - 48.6 with F_nu in erg/s/cm2/Hz Flux computed as 10**(-(meas-mag0)/2.5)*F0 Magnitude computed as -2.5*log10(Fmeas/F0) F0 = 3.6307805477010029e-20 erg/s/cm2/Hz

STmag = -2.5 Log F_lam - 21.10 with F_lam in erg/s/cm2/AA Flux computed as 10**(-(meas-mag0)/2.5)*F0 Magnitude computed as -2.5*log10(Fmeas/F0) F0 = 3.6307805477010028e-09 erg/s/cm2/AA

Vegamag = -2.5 Log F_lam - C with F_lam in erg/s/cm2/AA Flux computed as 10**(-meas/2.5)*F0 Magnitude computed as -2.5*log10(Fmeas/F0)

synthetic_flux(wave, flux, photbands, units=None)

source code 

Extract flux measurements from a synthetic SED (Fnu or Flambda).

The fluxes below 4micron are calculated assuming PHOTON-counting detectors (e.g. CCDs).

Flam = int(P_lam * f_lam * lam, dlam) / int(P_lam * lam, dlam)

When otherwise specified, we assume ENERGY-counting detectors (e.g. bolometers)

Flam = int(P_lam * f_lam, dlam) / int(P_lam, dlam)

Where P_lam is the total system dimensionless sensitivity function, which is normalised so that the maximum equals 1. Also, f_lam is the SED of the object, in units of energy per time per unit area per wavelength.

The PHOTON-counting part of this routine has been thoroughly checked with respect to johnson UBV, geneva and stromgren filters, and only gives offsets with respect to the Kurucz integrated files (.geneva and stuff on his websites). These could be due to different normalisation.

You can also readily integrate in Fnu instead of Flambda by suppling a list of strings to 'units'. This should have equal length of photbands, and should contain the strings 'flambda' and 'fnu' corresponding to each filter. In that case, the above formulas reduce to

Fnu = int(P_nu * f_nu / nu, dnu) / int(P_nu / nu, dnu)

and

Fnu = int(P_nu * f_nu, dnu) / int(P_nu, dnu)

Small note of caution: P_nu is not equal to P_lam according to Maiz-Apellaniz, he states that P_lam = P_nu/lambda. But in the definition we use above here, it *is* the same!

The model fluxes should always be given in Flambda (erg/s/cm2/AA). The program will convert them to Fnu where needed.

The output is a list of numbers, equal in length to the 'photband' inputs. The units of the output are erg/s/cm2/AA where Flambda was given, and erg/s/cm2/Hz where Fnu was given.

The difference is only marginal for 'blue' bands. For example, integrating 2MASS in Flambda or Fnu is only different below the 1.1% level:

>>> wave,flux = get_table(teff=10000,logg=4.0)
>>> energys = synthetic_flux(wave,flux,['2MASS.J','2MASS.J'],units=['flambda','fnu'])
>>> e0_conv = conversions.convert('erg/s/cm2/AA','erg/s/cm2/Hz',energys[0],photband='2MASS.J')
>>> np.abs(energys[1]-e0_conv)/energys[1]<0.012
True

But this is not the case for IRAS.F12:

>>> energys = synthetic_flux(wave,flux,['IRAS.F12','IRAS.F12'],units=['flambda','fnu'])
>>> e0_conv = conversions.convert('erg/s/cm2/AA','erg/s/cm2/Hz',energys[0],photband='IRAS.F12')
>>> np.abs(energys[1]-e0_conv)/energys[1]>0.1
True

If you have a spectrum in micron vs Jy and want to calculate the synthetic fluxes in Jy, a little bit more work is needed to get everything in the right units. In the following example, we first generate a constant flux spectrum in micron and Jy. Then, we convert flux to erg/s/cm2/AA using the wavelengths (this is no approximation) and convert wavelength to angstrom. Next, we compute the synthetic fluxes in the IRAS band in Fnu, and finally convert the outcome (in erg/s/cm2/Hz) to Jansky.

>>> wave,flux = np.linspace(0.1,200,10000),np.ones(10000)
>>> flam = conversions.convert('Jy','erg/s/cm2/AA',flux,wave=(wave,'micron'))
>>> lam = conversions.convert('micron','AA',wave)
>>> energys = synthetic_flux(lam,flam,['IRAS.F12','IRAS.F25','IRAS.F60','IRAS.F100'],units=['Fnu','Fnu','Fnu','Fnu'])
>>> energys = conversions.convert('erg/s/cm2/Hz','Jy',energys)

You are responsible yourself for having a response curve covering the model fluxes!

Now. let's put this all in practice in a more elaborate example: we want to check if the effective wavelength is well defined. To do that we will:

  1. construct a model (black body)
  2. make our own weird, double-shaped filter (CCD-type and BOL-type detector)
  3. compute fluxes in Flambda, and convert to Fnu via the effective wavelength
  4. compute fluxes in Fnu, and compare with step 3.

In an ideal world, the outcome of step (3) and (4) must be equal:

Step (1): We construct a black body model.

WARNING: OPEN.BOL only works in Flambda for now.

See e.g. Maiz-Apellaniz, 2006.

Parameters:
  • wave (ndarray) - model wavelengths (angstrom)
  • flux (ndarray) - model fluxes (erg/s/cm2/AA)
  • photbands (list of str) - list of photometric passbands
  • units (list of strings or str) - list containing Flambda or Fnu flag (defaults to all Flambda)
Returns: ndarray
model fluxes (erg/s/cm2/AA or erg/s/cm2/Hz)

synthetic_color(wave, flux, colors, units=None)

source code 

Construct colors from a synthetic SED.

Parameters:
  • wave (ndarray) - model wavelengths (angstrom)
  • flux (ndarray) - model fluxes (erg/s/cm2/AA)
  • colors (list of str) - list of photometric passbands
  • units (list of strings or str) - list containing Flambda or Fnu flag (defaults to all Flambda)
Returns: ndarray
flux ratios or colors

luminosity(wave, flux, radius=1.)

source code 

Calculate the bolometric luminosity of a model SED.

Flux should be in cgs per unit wavelength (same unit as wave). The latter is integrated out, so it is of no importance. After integration, flux, should have units erg/s/cm2.

Returned luminosity is in solar units.

If you give radius=1 and want to correct afterwards, multiply the obtained Labs with radius**2.

Parameters:
  • wave (ndarray) - model wavelengths
  • flux (ndarray) - model fluxes (Flam)
  • radius (float) - stellar radius in solar units
Returns: float
total bolometric luminosity

_get_itable_markers(photbands, teffrange=(-np.inf,np.inf), loggrange=(-np.inf,np.inf), ebvrange=(-np.inf,np.inf), zrange=(-np.inf,np.inf), include_Labs=True, clear_memory=True, **kwargs)

source code 

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

Decorators:
  • @memoized

_get_pix_grid(photbands, teffrange=(-np.inf,np.inf), loggrange=(-np.inf,np.inf), ebvrange=(-np.inf,np.inf), zrange=(-np.inf,np.inf), rvrange=(-np.inf,np.inf), vradrange=(-np.inf,np.inf), include_Labs=True, clear_memory=True, variables=['teff','logg','ebv','z','rv','vrad'], **kwargs)

source code 

Prepare the pixalted grid.

In principle, it should be possible to return any number of free parameters
here. I'm thinking about:

    teff, logg, ebv, z, Rv, vrad.

Decorators:
  • @memoized

_get_flux_from_table(fits_ext, photbands, index=None, include_Labs=True)

source code 

Retrieve flux and flux ratios from an integrated SED table.

Parameters:
  • fits_ext (FITS extension) - fits extension containing integrated flux
  • photbands (list of str) - list of photometric passbands
  • index (slice or integer) - slice or index of rows to retrieve
Returns:
fluxes or flux ratios #@rtype: list

Variables Details [hide private]

__defaults__

Value:
dict(grid= 'kurucz', odfnew= True, z=+ 0.0, vturb= 2, alpha= False, no\
ver= False, He= 97, ct= 'mlt', t= 1.0, a= 0.0, c= 0.5, m= 1.0, co= 1.0\
5, Rv= 3.1, law= 'fitzpatrick2004', use_scratch= False)