Extracting data of directly imaged companions

In this tutorial, we will add photometric data, parallaxes, and spectra of directly imaged planets and brown dwarfs to the database and use the reading functionalities to easily access those data.

Getting started

We start by importing the required Python packages.

[1]:
from species import SpeciesInit
from species.data.database import Database
from species.read.read_object import ReadObject

The species HDF5 database is initiated by creating an instance of the SpeciesInit class.

[2]:
SpeciesInit()
=======
species
=======

Version: 0.10.5.dev13
Working folder: /Users/tomasstolker/code/species/docs/tutorials

Creating species_config.ini... [DONE]
Creating species_database.hdf5... [DONE]
Creating data folder... [DONE]

Configuration settings:
   - Database: species_database.hdf5
   - Data folder: data
   - Magnitude of Vega: 0.03

Multiprocessing: mpi4py installed
Process number 1 out of 1...
[2]:
<species.core.species_init.SpeciesInit at 0x110e98ec0>

Adding companion data to the database

To add data to the database, we first create an instance of Database.

[3]:
database = Database()

Next, we use the add_companion method of Database to add all companion data that are available in the companion_data and companion_spectra files. This includes filter names, magnitudes, and parallaxes of most directly imaged planets and brown dwarfs, as well as spectra for some objects. We set the argument of name to None such that all data are added instead of selecting a single companion.

Running this method will also download the relevant filter profiles from the SVO Filter Profile Service and a flux-calibrated spectrum of Vega. The magnitudes that are available in the toolkit are converted into fluxes and both stored in the database. We set verbose to False to not print a overview of all the filter and companion data that are being added.

[4]:
database.add_companion(name=None, verbose=False)
Add companion: ['HD 135344 Ab', 'AF Lep b', 'beta Pic b', 'beta Pic c', 'HIP 65426 b', 'HIP 99770 b', '51 Eri b', 'HR 8799 b', 'HR 8799 c', 'HR 8799 d', 'HR 8799 e', 'HD 95086 b', 'PDS 70 b', 'PDS 70 c', '2M 1207 B', 'AB Pic B', 'HD 206893 B', 'HD 206893 c', 'RZ Psc B', 'GQ Lup B', 'PZ Tel B', 'kappa And b', 'HD 1160 B', 'ROXs 12 B', 'ROXs 42 Bb', 'GJ 504 b', 'GJ 758 B', 'GU Psc b', '2M0103 ABb', '1RXS 1609 B', 'GSC 06214 B', 'HD 72946 B', 'HIP 64892 B', 'HD 13724 B', 'YSES 1 b', 'YSES 1 c', 'HD 142527 B', 'CS Cha B', 'CT Cha B', 'SR 12 C', 'DH Tau B', 'HD 4747 B', 'HR 3549 B', 'CHXR 73 B', 'HD 19467 B', 'b Cen (AB)b', 'eps Ind Ab', 'WISPIT 2 b', 'VHS 1256 B']
Downloading data from 'https://archive.stsci.edu/hlsps/reference-atlases/cdbs/current_calspec/alpha_lyr_stis_011.fits' to file '/Users/tomasstolker/code/species/docs/tutorials/data/alpha_lyr_stis_011.fits'.

Downloading data from 'https://home.strw.leidenuniv.nl/~stolker/species/alpha_lyr_stis_011.fits' to file '/Users/tomasstolker/code/species/docs/tutorials/data/alpha_lyr_stis_011.fits'.

Adding spectrum: Vega
Downloading data from 'https://home.strw.leidenuniv.nl/~stolker/species/spectra/betapicb_gpi_yjhk.dat' to file '/Users/tomasstolker/code/species/docs/tutorials/data/companion_data/betapicb_gpi_yjhk.dat'.

Reference: Bohlin et al. 2014, PASP, 126
URL: https://ui.adsabs.harvard.edu/abs/2014PASP..126..711B
SHA256 hash of downloaded file: 33e8d3ee32aa661f97624eda64e4a7f67dac2a7f22a072136a8414713379ef50
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://home.strw.leidenuniv.nl/~stolker/species/spectra/BetaPictorisb_2018-09-22.fits' to file '/Users/tomasstolker/code/species/docs/tutorials/data/companion_data/BetaPictorisb_2018-09-22.fits'.
SHA256 hash of downloaded file: 4b4507e4af6cec5711d2110974061584b8d23cc108daae7fa3be8c27d866847c
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://xwcl.science/magao/visao/VisAO_Ys_filter_curve.dat' to file '/Users/tomasstolker/code/species/docs/tutorials/data/VisAO_Ys_filter_curve.dat'.
SHA256 hash of downloaded file: 4d523a06d8daae91f91d98f4ee8dacbfef7d17c6161a4c217dd56cd6006b9d56
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
/Users/tomasstolker/code/species/species/data/database.py:1526: UserWarning: Found 33 fluxes with NaN in the data of GPI_YJHK. Removing the spectral fluxes that contain a NaN.
  warnings.warn(
Downloading data from 'https://home.strw.leidenuniv.nl/~stolker/species/spectra/51erib_sphere_yjh.dat' to file '/Users/tomasstolker/code/species/docs/tutorials/data/companion_data/51erib_sphere_yjh.dat'.
SHA256 hash of downloaded file: d050f0a5762b2fb277284fd7a514c9656605d720ee4dab1b61c35f05256d16a9
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
/Users/tomasstolker/code/species/species/data/filter_data/filter_data.py:374: UserWarning: The minimum transmission value of Subaru/CIAO.z is smaller than zero (-1.80e-03). Wavelengths with negative transmission values will be removed.
  warnings.warn(
Downloading data from 'https://home.strw.leidenuniv.nl/~stolker/species/spectra/hr8799e_sphere_yjh.dat' to file '/Users/tomasstolker/code/species/docs/tutorials/data/companion_data/hr8799e_sphere_yjh.dat'.
SHA256 hash of downloaded file: 8807ff91d417513b6f4ca2c5a21e68830830c81cd8ef7399260de8796d72496b
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://home.strw.leidenuniv.nl/~stolker/species/spectra/pds70b_sphere_yjh.dat' to file '/Users/tomasstolker/code/species/docs/tutorials/data/companion_data/pds70b_sphere_yjh.dat'.
SHA256 hash of downloaded file: d9ca1a0e4783bed66ab8512a5939927d3846bf82ac16981565747f2e9459fc0b
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://home.strw.leidenuniv.nl/~stolker/species/spectra/hd206893b_sphere_yjh.dat' to file '/Users/tomasstolker/code/species/docs/tutorials/data/companion_data/hd206893b_sphere_yjh.dat'.
SHA256 hash of downloaded file: 676f9140257b0e5fd70a6ae8c95e8543d59a83b16dd4cab0ddcb0dcc41544f35
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://home.strw.leidenuniv.nl/~stolker/species/spectra/HD206893C_GRAVITYK_fluxcal_spectrum.fits' to file '/Users/tomasstolker/code/species/docs/tutorials/data/companion_data/HD206893C_GRAVITYK_fluxcal_spectrum.fits'.
SHA256 hash of downloaded file: abacbf0435af6f5b06ff4f01567dbdc37e529e9f7ba5ddfc588ce73a4df0b43b
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://home.strw.leidenuniv.nl/~stolker/species/spectra/gqlupb_muse.dat' to file '/Users/tomasstolker/code/species/docs/tutorials/data/companion_data/gqlupb_muse.dat'.
SHA256 hash of downloaded file: a96bb9e2de04cd001cd5cf1c5297eaed88eb0a888bc41e6b2d861c8d47e9db56
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://home.strw.leidenuniv.nl/~stolker/species/spectra/gqlupb_sinfoni_j.dat' to file '/Users/tomasstolker/code/species/docs/tutorials/data/companion_data/gqlupb_sinfoni_j.dat'.
SHA256 hash of downloaded file: 8667316e76424eb64a8816cbec7e1359a502304bcafcc6fb326af840ecec0eed
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://home.strw.leidenuniv.nl/~stolker/species/spectra/gqlupb_sinfoni_h.dat' to file '/Users/tomasstolker/code/species/docs/tutorials/data/companion_data/gqlupb_sinfoni_h.dat'.
SHA256 hash of downloaded file: 1a8b0ecb0908076d0a347fe5d0b0ae7a615daaf0be525c7a642fe57d003e9566
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://home.strw.leidenuniv.nl/~stolker/species/spectra/gqlupb_sinfoni_k.dat' to file '/Users/tomasstolker/code/species/docs/tutorials/data/companion_data/gqlupb_sinfoni_k.dat'.
SHA256 hash of downloaded file: d2e62c8f9e803cc06d6d3b85a78c23b202e0742b97e8e27a717cf251ba5513bf
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://xwcl.science/magao/visao/VisAO_ip_filter_curve.dat' to file '/Users/tomasstolker/code/species/docs/tutorials/data/VisAO_ip_filter_curve.dat'.
SHA256 hash of downloaded file: cbda362353fe25b78bec67506288fa6220ca22228cb7ddf94d5fcf8bc2a4dfb3
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://xwcl.science/magao/visao/VisAO_zp_filter_curve.dat' to file '/Users/tomasstolker/code/species/docs/tutorials/data/VisAO_zp_filter_curve.dat'.
SHA256 hash of downloaded file: 8d1ee51d7e52beb2fd1d6405c2bc1b83f2691324c2dba609b4f97de4b30329bd
Use this value as the 'known_hash' argument of 'pooch.retrieve' to ensure that the file hasn't changed if it is downloaded again in the future.
Downloading data from 'https://home.strw.leidenuniv.nl/~stolker/species/filters/Keck_NIRC2.NB_4.05.dat' to file '/Users/tomasstolker/code/species/docs/tutorials/data/Keck_NIRC2.NB_4.05.dat'.

To get an overview of the companion data that are stored in the database, one can use the list_companions method of Database. This will also return a list with the companion names, which could for example be iterated when using the reading functionalities below.

Reading companion data

For reading data of individual companions/objects, we can use the reading functionalities of the toolkit. We start by creating an instance of ReadObject with the object name as stored in the database given as argument.

[5]:
read_obj = ReadObject('beta Pic b')

We can check for which filters there is photometric data available with the list_filters method of ReadObject.

[6]:
filter_list = read_obj.list_filters()
Available photometric data for beta Pic b:
   - Gemini/NICI.ED286
   - Magellan/VisAO.Ys
   - Paranal/NACO.H
   - Paranal/NACO.J
   - Paranal/NACO.Ks
   - Paranal/NACO.Lp
   - Paranal/NACO.Mp
   - Paranal/NACO.NB374
   - Paranal/NACO.NB405
[7]:
print(filter_list)
['Gemini/NICI.ED286', 'Magellan/VisAO.Ys', 'Paranal/NACO.H', 'Paranal/NACO.J', 'Paranal/NACO.Ks', 'Paranal/NACO.Lp', 'Paranal/NACO.Mp', 'Paranal/NACO.NB374', 'Paranal/NACO.NB405']

Let’s now extract the photometric data of the NACO \(M'\) filter. The get_photometry method returns an array with the apparent magnitude, magnitude error, flux density (W m\(^{-2}\) \(\mu\)m\(^{-1}\)), and flux density error.

[8]:
mp_phot = read_obj.get_photometry('Paranal/NACO.Mp', return_mag=True)
print(mp_phot)
[np.float64(11.1), np.float64(0.12)]

Similarly, we can use the get_spectrum method to return a dictionary with available spectra. In this case a GPI spectrum in the \(YJHK\) bands from Chilcote et al. 2017 and a GRAVITY spectrum in the \(K\) band from Gravity Collaboration et al. 2020.

[9]:
spec_dict = read_obj.get_spectrum()
print(spec_dict.keys())
dict_keys(['GPI_YJHK', 'GRAVITY'])

Other methods for ReadObject are get_distance for returning the distance and get_absmag for calculating the absolute magnitude and uncertainty.

[10]:
distance = read_obj.get_distance()
print(f'Distance (pc) = {distance[0]:.2f} +/- {distance[1]:.2f}')
Distance (pc) = 19.63 +/- 0.06
[11]:
abs_mag = read_obj.get_absmag('Paranal/NACO.Mp')
print(f'Apparent magnitude = {mp_phot[0]:.2f} +/- {mp_phot[1]:.2f}')
print(f'Absolute magnitude = {abs_mag[0]:.2f} +/- {abs_mag[1]:.2f}')
Apparent magnitude = 11.10 +/- 0.12
Absolute magnitude = 9.63 +/- 0.12

Extracting an ObjectBox with data

Instead of using the ReadObject functionalities, we can also use the get_object method of Database to extract an ObjectBox with the companion data from the database. The inc_phot and inc_spec parameters are either a boolean or a list of filter names / spectra. In this example, we will include all photometric data.

[12]:
object_box = database.get_object('beta Pic b', inc_phot=True, inc_spec=False)

----------
Get object
----------

Object name: beta Pic b
Include photometry: True
Include spectra: False

We can inspect the content of the ObjectBox with the open_box method. Let’s have a look!

[13]:
object_box.open_box()
Opening ObjectBox...
name = beta Pic b
filters = ['Gemini/NICI.ED286', 'Magellan/VisAO.Ys', 'Paranal/NACO.H', 'Paranal/NACO.J', 'Paranal/NACO.Ks', 'Paranal/NACO.Lp', 'Paranal/NACO.Mp', 'Paranal/NACO.NB374', 'Paranal/NACO.NB405']
mean_wavel = {'Gemini/NICI.ED286': np.float64(1.5841803431418238), 'Magellan/VisAO.Ys': np.float64(0.9826820974261752), 'Paranal/NACO.H': np.float64(1.6588090664617747), 'Paranal/NACO.J': np.float64(1.265099894847529), 'Paranal/NACO.Ks': np.float64(2.144954491491888), 'Paranal/NACO.Lp': np.float64(3.8050282724280526), 'Paranal/NACO.Mp': np.float64(4.780970919324577), 'Paranal/NACO.NB374': np.float64(3.744805012092439), 'Paranal/NACO.NB405': np.float64(4.055862923806052)}
filter_width = {'Gemini/NICI.ED286': np.float64(0.017525193213729695), 'Magellan/VisAO.Ys': np.float64(0.07888689300636698), 'Paranal/NACO.H': np.float64(0.34479579328929977), 'Paranal/NACO.J': np.float64(0.24904070813234003), 'Paranal/NACO.Ks': np.float64(0.36972828247409306), 'Paranal/NACO.Lp': np.float64(0.6276348582389186), 'Paranal/NACO.Mp': np.float64(0.5952960574619803), 'Paranal/NACO.NB374': np.float64(0.04548071316770308), 'Paranal/NACO.NB405': np.float64(0.06124789557254662)}
magnitude = {'Gemini/NICI.ED286': array([13.18,  0.15]), 'Magellan/VisAO.Ys': array([15.53,  0.34]), 'Paranal/NACO.H': array([13.32,  0.14]), 'Paranal/NACO.J': array([14.11,  0.21]), 'Paranal/NACO.Ks': array([12.64,  0.11]), 'Paranal/NACO.Lp': array([11.3 ,  0.06]), 'Paranal/NACO.Mp': array([11.1 ,  0.12]), 'Paranal/NACO.NB374': array([11.25,  0.23]), 'Paranal/NACO.NB405': array([10.98,  0.05])}
flux = {'Gemini/NICI.ED286': array([6.88473179e-15, 9.54189511e-16]), 'Magellan/VisAO.Ys': array([4.21442946e-15, 1.34143128e-15]), 'Paranal/NACO.H': array([5.38576426e-15, 6.96392162e-16]), 'Paranal/NACO.J': array([6.78430595e-15, 1.32039804e-15]), 'Paranal/NACO.Ks': array([3.97213973e-15, 4.03121161e-16]), 'Paranal/NACO.Lp': array([1.55661222e-15, 8.60653603e-17]), 'Paranal/NACO.Mp': array([7.69564549e-16, 8.52286898e-17]), 'Paranal/NACO.NB374': array([1.65829270e-15, 3.53922391e-16]), 'Paranal/NACO.NB405': array([1.57733391e-15, 7.26645888e-17])}
spectrum = None
parallax = [50.9307  0.1482]
distance = None

Each Box is a Python object and the items in a box can be extracted as attributes. For example, to get the list of filter names:

[14]:
print(object_box.filters)
['Gemini/NICI.ED286', 'Magellan/VisAO.Ys', 'Paranal/NACO.H', 'Paranal/NACO.J', 'Paranal/NACO.Ks', 'Paranal/NACO.Lp', 'Paranal/NACO.Mp', 'Paranal/NACO.NB374', 'Paranal/NACO.NB405']