Spectral library

In this tutorial, we will have a look at some brown dwarf spectra from the IRTF library. We will also calculate synthetic fluxes and combine the spectra and photometric fluxes in a plot.

Getting started

We start by importing species and initiating the database with the SpeciesInit class.

[1]:
import species
species.SpeciesInit()
Initiating species v0.4.0... [DONE]
Creating species_config.ini... [DONE]
Database: /Users/tomasstolker/applications/species/docs/tutorials/species_database.hdf5
Data folder: /Users/tomasstolker/applications/species/docs/tutorials/data
Working folder: /Users/tomasstolker/applications/species/docs/tutorials
Creating species_database.hdf5... [DONE]
Creating data folder... [DONE]
[1]:
<species.core.init.SpeciesInit at 0x10e389760>

Adding a spectral library to the database

Next, we create an instance of Database, which is used for adding data to the database.

[2]:
database = species.Database()

We will now download and add the spectral library. For IRTF spectra, we can set the spectral types that we want to use. The parallax will be queried from SIMBAD and several VizieR catalogs. A warning will be printed in case no parallax can be retrieved and a NaN is stored. Therefore, computing an absolute, synthetic magnitude from these spectra will not be possible.

[3]:
database.add_spectra(spec_library='irtf', sptypes=['L', 'T'])
Downloading IRTF Spectral Library - L dwarfs (850 kB)... [DONE]
Downloading IRTF Spectral Library - T dwarfs (100 kB)... [DONE]
Unpacking IRTF Spectral Library... [DONE]
Adding spectra... DENIS-P 025503.3-470049.0
/Users/tomasstolker/.pyenv/versions/3.9.6/envs/species3.9/lib/python3.9/site-packages/astroquery/simbad/core.py:135: UserWarning: Warning: The script line number 3 raised an error (recorded in the `errors` attribute of the result table): 'DENIS-P 025503.3-470049.0' this identifier has an incorrect format for catalog:  DENIS : Deep Near-Infrared Survey
  warnings.warn("Warning: The script line number %i raised "
Adding spectra... 2MASS J05591915-1404489
/Users/tomasstolker/.pyenv/versions/3.9.6/envs/species3.9/lib/python3.9/site-packages/astroquery/simbad/core.py:135: UserWarning: Warning: The script line number 3 raised an error (recorded in the `errors` attribute of the result table): Identifier not found in the database : 2MASS J05591915-1404489
  warnings.warn("Warning: The script line number %i raised "
Adding spectra... [DONE]

Reading a spectral library

To read the spectra from the database, we first create an instance of ReadSpectrum. The full spectra are read if the argument of filter_name is set to None.

[4]:
read_spectrum = species.ReadSpectrum(spec_library='irtf', filter_name=None)

The spectra are extracted with the get_spectrum method and by providing a list of spectral types as argument for sptypes.

[5]:
specbox = read_spectrum.get_spectrum(sptypes=['L0', 'L1'])

The method returns a SpectrumBox with the requested data.

Opening a SpectrumBox

Let’s have a look at the attributes that are stored in the SpectrumBox by using the open_box method, which can be used on any of the Box objects. Among others, it contains the spectrum, the original names (from the IRTF library) and SIMBAD names, and the distances.

[6]:
specbox.open_box()
Opening SpectrumBox...
spectrum = None
wavelength = [array([0.8125008, 0.8125008, 0.8127338, ..., 4.126095 , 4.1269007,
       4.127706 ], dtype=float32), array([0.93558633, 0.93558633, 0.93585825, ..., 2.416591  , 2.4171278 ,
       2.417665  ], dtype=float32), array([0.8106775 , 0.8106775 , 0.81091094, ..., 4.113586  , 4.1143913 ,
       4.1151967 ], dtype=float32)]
flux = [array([1.8895840e-14, 1.8895840e-14, 2.1758479e-14, ..., 3.7088523e-15,
       4.1113438e-15, 4.4284915e-15], dtype=float32), array([-1.0867816e-15, -1.0867816e-15,  2.5373139e-15, ...,
        2.0060095e-15,  2.1450817e-15,  2.2615936e-15], dtype=float32), array([3.8497135e-15, 3.8497135e-15, 2.5441878e-15, ..., 1.3200795e-15,
       1.2305833e-15, 1.0569799e-15], dtype=float32)]
error = [array([2.5401353e-15, 2.5401353e-15, 2.8612678e-15, ..., 4.1515258e-16,
       4.3247181e-16, 4.4612945e-16], dtype=float32), array([2.2947999e-15, 2.2947999e-15, 1.3184451e-15, ..., 2.5160439e-16,
       1.7856300e-16, 9.8540571e-17], dtype=float32), array([1.9933140e-15, 1.9933140e-15, 2.2894352e-15, ..., 3.6852164e-16,
       3.4700822e-16, 3.5634480e-16], dtype=float32)]
name = ['2MASS J07464256+2000321', '2MASS J02081833+2542533', '2MASS J14392836+1929149']
simbad = ['LSPM J0746+2000', '2MASS J02081833+2542533', '2MASS J14392836+1929149']
sptype = ['L0', 'L1', 'L1']
distance = [(array([12.33045623]), array([0.13685299])), (23.6577760744179, 0.3513951187454545), (array([14.36781609]), array([0.1032224]))]
spec_library = irtf

Synthetic photometry

To calculate synthetic fluxes, we use again the ReadSpectrum class but we now also set the argument of filter_name to a filter as listed by the SVO Filter Profile Service. In this example, use an H-band filter from the MKO system.

[7]:
read_spectrum = species.ReadSpectrum(spec_library='irtf', filter_name='MKO/NSFCam.H')
Adding filter: MKO/NSFCam.H... [DONE]

The flux is now calculated with the get_flux method by again selecting the L0- and L1-type objects.

[8]:
photbox = read_spectrum.get_flux(sptypes=['L0', 'L1'])

Let’s have a look at the content of the returned PhotometryBox.

[9]:
photbox.open_box()
Opening PhotometryBox...
name = ['2MASS J07464256+2000321', '2MASS J02081833+2542533', '2MASS J14392836+1929149']
sptype = ['L0', 'L1', 'L1']
wavelength = [1.6298258 1.6298258 1.6298258]
flux = [[4.58844219e-14 8.08979388e-18]
 [6.09467692e-15 6.91485540e-18]
 [1.75018623e-14 5.23308674e-18]]
app_mag = None
abs_mag = None
filter_name = ['MKO/NSFCam.H' 'MKO/NSFCam.H' 'MKO/NSFCam.H']

Plotting spectrum and synthetic fluxes

Now that we have created a SpectrumBox and PhotometryBox, we pass them to the plot_spectrum function.

[10]:
species.plot_spectrum(boxes=[specbox, photbox],
                      filters=['MKO/NSFCam.J', 'MKO/NSFCam.H', 'MKO/NSFCam.Ks'],
                      xlim=(0.9, 2.5),
                      ylim=(0., 8.5e-14),
                      offset=(-0.1, -0.04),
                      legend={'loc':'upper right', 'frameon': False, 'fontsize': 11.},
                      figsize=(8, 4),
                      output='spectrum.png')
Adding filter: MKO/NSFCam.J... [DONE]
Adding filter: MKO/NSFCam.Ks... [DONE]
Plotting spectrum: spectrum.png... [DONE]

Let’s have a look at the result! The uncertainties on the spectrum have been propagated into the synthetic flux but the error bars are smaller than the plotted markers. The horizontal “error bars” of the fluxes indicate the FWHM of the filter profile.

[11]:
from IPython.display import Image
Image('spectrum.png')
[11]:
../_images/tutorials_spectral_library_30_0.png