<jupyter_start><jupyter_text>Model spectra and synthetic photometry In this tutorial, we will have a look at some spectra of the DRIFT-PHOENIX atmospheric model. The spectra are first downloaded and added to the database. Then we will use the functionalities of [ReadModel](https://species.readthedocs.io/en/latest/species.read.html?highlight=ReadModelspecies.read.read_model.ReadModel) to extract a spectrum and calculate a photometric flux.  Getting started We start by importing the required Python modules.<jupyter_code>import species<jupyter_output><empty_output><jupyter_text>Then we initialize [species](https://species.readthedocs.io/en/latest/species.html) with [SpeciesInit](https://species.readthedocs.io/en/latest/species.core.htmlspecies.core.init.SpeciesInit), which creates a default configuration file and the HDF5 database.<jupyter_code>species.SpeciesInit()<jupyter_output>Initiating species v0.5.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]<jupyter_text>Adding model spectra to the database To store the spectra, we first create an instance of [Database](https://species.readthedocs.io/en/latest/species.data.html?highlight=database.Databasespecies.data.database.Database).<jupyter_code>database = species.Database()<jupyter_output><empty_output><jupyter_text>Let's check which atmospheric models are available by running the [available_models](https://species.readthedocs.io/en/latest/species.data.htmlspecies.data.database.Database.available_models) method of the [Database](https://species.readthedocs.io/en/latest/species.data.htmlspecies.data.database.Database) object.<jupyter_code>_ = database.available_models()<jupyter_output>Available model grids:
   - AMES-Cond:
      - Label = ames-cond
      - Model parameters: ['teff', 'logg']
      - Teff range (K): [100, 6600]
      - Wavelength range (um): [0.5, 40]
      - Resolution lambda/Dlambda: 4000
      - File size: 150 MB

   - AMES-Dusty:
      - Label = ames-dusty
      - Model parameters: ['teff', 'logg']
      - Teff range (K): [500, 4000]
      - Wavelength range (um): [0.5, 40]
      - Resolution lambda/Dlambda: 4000
      - File size: 59 MB

   - ATMO:
      - Label = atmo
      - Model parameters: ['teff', 'logg']
      - Teff range (K): [200, 3000]
      - Wavelength range (um): [0.4, 6000]
      - Resolution lambda/Dlambda: 10000
      - File size: 425 MB
      - Reference: Phillips et al. (2020)
      - URL: https://ui.adsabs.harvard.edu/abs/2020A%26A...637A..38P/abstract

   - blackbody:
      - Label = blackbody
      - Model parameters: ['teff']
      - Teff range (K): [10, 20000]
      - Wavelength range (um): [0.1, 5000]
      - Resolution l[...]<jupyter_text>Next, we will import the model spectra with the [add_model](https://species.readthedocs.io/en/latest/species.data.htmlspecies.data.database.Database.add_model) method of [Database](https://species.readthedocs.io/en/latest/species.data.htmlspecies.data.database.Database). This step will automatically download the DRIFT-PHOENIX spectra (R = 2000) to the [data_folder](https://species.readthedocs.io/en/latest/configuration.html). The dowloaded data will then be unpacked and added to the database. We restrict the temperature range to 1300-1700 K, so not all spectra are added to the databse.<jupyter_code>database.add_model(model='drift-phoenix', teff_range=(1300., 1700.))<jupyter_output>Downloading DRIFT-PHOENIX model spectra (229 MB)... [DONE]
Unpacking DRIFT-PHOENIX model spectra (229 MB)... [DONE]
Please cite Helling et al. (2008) when using DRIFT-PHOENIX in a publication
Reference URL: https://ui.adsabs.harvard.edu/abs/2008ApJ...675L.105H/abstract
Wavelength range (um) = 0.1 -50
Spectral resolution = 4000
Teff range (K) = 1300.0 - 1700.0
Adding DRIFT-PHOENIX model spectra... [DONE]                                            
Grid points stored in the database:
   - Teff = [1300. 1400. 1500. 1600. 1700.]
   - log(g) = [3.  3.5 4.  4.5 5.  5.5]
   - [Fe/H] = [-0.6 -0.3 -0.   0.3]<jupyter_text>Two of the grid points were missing in the original data and have been added with a linear, multidimensional interpolation.  Interpolating the model grid We will read the spectra from the database by creating an instance of [ReadModel](https://species.readthedocs.io/en/latest/species.read.htmlspecies.read.read_model.ReadModel).<jupyter_code>read_model = species.ReadModel(model='drift-phoenix', wavel_range=(0.5, 10.))<jupyter_output><empty_output><jupyter_text>Let's see what the grid boundaries are from the spectra that are stored in the database.<jupyter_code>read_model.get_bounds()<jupyter_output><empty_output><jupyter_text>We will now interpolate the grid in the ($T_\mathrm{eff}$, $\log(g)$, $[\mathrm{Fe}/\mathrm{H}]$) space at some specific parameter values, which need to be provided in a dictionary. The radius and distance are optional, otherwise the emitted flux is given at the planet surface.<jupyter_code>model_param = {'teff':1510., 'logg':4.1, 'feh':0.1, 'radius': 1., 'distance': 100.}<jupyter_output><empty_output><jupyter_text>To interpolate a spectrum, we use the [get_model](https://species.readthedocs.io/en/latest/species.read.htmlspecies.read.read_model.ReadModel.get_model) method and provide the parameter dictionary, and also an optional spectral resolution. Together with `smooth=True`, the spectrum will be smoothed (but not resampeld) to the given spectral resolution.<jupyter_code>model_box = read_model.get_model(model_param=model_param, spec_res=200., smooth=True)<jupyter_output><empty_output><jupyter_text>The data is stored in a [ModelBox](https://species.readthedocs.io/en/latest/species.core.htmlspecies.core.box.ModelBox). Let's have a look at its content.<jupyter_code>model_box.open_box()<jupyter_output>Opening ModelBox...
model = drift-phoenix
type = None
wavelength = [ 0.49989727  0.50002105  0.50014486 ...  9.99710369  9.99957902
 10.00205496]
flux = [9.44339097e-20 9.38011967e-20 9.31147817e-20 ... 1.53571943e-18
 1.53924349e-18 1.54301688e-18]
parameters = {'teff': 1510.0, 'logg': 4.1, 'feh': 0.1, 'radius': 1.0, 'distance': 100.0, 'luminosity': 4.729862212008143e-05, 'mass': 4.857062223118246}
quantity = flux
contribution = None
bol_flux = None<jupyter_text>We will now use the same atmospheric parameters but we will add some [ISM extinction](https://species.readthedocs.io/en/latest/species.util.html?species.util.dust_util.ism_extinction) with the relation from [Cardelli et al. (1989)](https://ui.adsabs.harvard.edu/abs/1989ApJ...345..245C/abstract). Therefore, we add the V band extinction and reddening parameters to the dictionary.<jupyter_code>model_param = {'teff':1510., 'logg':4.1, 'feh':0.1, 'radius': 1., 'distance': 100., 'ism_ext': 5., 'ism_red': 3.}<jupyter_output><empty_output><jupyter_text>We use again the [get_model](https://species.readthedocs.io/en/latest/species.read.htmlspecies.read.read_model.ReadModel.get_model) method and store the result in a different [ModelBox](https://species.readthedocs.io/en/latest/species.core.htmlspecies.core.box.ModelBox).<jupyter_code>model_ext = read_model.get_model(model_param=model_param, spec_res=200., smooth=True)<jupyter_output><empty_output><jupyter_text>The two boxes with the model spectra are provided to the [plot_spectrum](https://species.readthedocs.io/en/latest/species.plot.htmlspecies.plot.plot_spectrum.plot_spectrum). We also include some filter profiles to indicate where the telluric windows are.<jupyter_code>species.plot_spectrum(boxes=[model_box, model_ext],
                      filters=['MKO/NSFCam.J', 'MKO/NSFCam.H', 'MKO/NSFCam.K', 'MKO/NSFCam.Lp', 'MKO/NSFCam.Mp'],
                      offset=(-0.15, -0.04),
                      xlim=(0.8, 5.),
                      ylim=(0., 5.5e-17),
                      legend={'loc': 'lower right', 'frameon': False, 'fontsize': 10.},
                      figsize=(7., 3.),
                      output=None)<jupyter_output>Adding filter: MKO/NSFCam.J... [DONE]
Adding filter: MKO/NSFCam.H... [DONE]
Adding filter: MKO/NSFCam.K... [DONE]
Adding filter: MKO/NSFCam.Lp... [DONE]
Adding filter: MKO/NSFCam.Mp... [DONE]
Plotting spectrum... [DONE]<jupyter_text>Extracting a spectrum at a grid point It is also possible to extract a spectrum at one of the grid points, which doesn't require any interpolation. Let's check with the [get_points](https://species.readthedocs.io/en/latest/species.read.htmlspecies.read.read_model.ReadModel.get_points) method what parameter values are stored in the database.<jupyter_code>read_model.get_points()<jupyter_output><empty_output><jupyter_text>We create a dictionary with values at one of the grid points.<jupyter_code>model_param = {'teff':1500., 'logg':4., 'feh':0.}<jupyter_output><empty_output><jupyter_text>And now use the [get_data](https://species.readthedocs.io/en/latest/species.read.htmlspecies.read.read_model.ReadModel.get_data) method to extract a spectrum.<jupyter_code>model_full = read_model.get_data(model_param)<jupyter_output><empty_output><jupyter_text>Let's make another plot with [plot_spectrum](https://species.readthedocs.io/en/latest/species.plot.htmlspecies.plot.plot_spectrum.plot_spectrum). The spectrum is now shown at the spectral resolution as stored in the database ($R = 2000$).<jupyter_code>species.plot_spectrum(boxes=[model_full],
                      filters=None,
                      offset=(-0.12, -0.05),
                      xlim=(0.8, 5.),
                      ylim=(0., 1e5),
                      legend={'loc': 'upper right', 'fontsize': 10.},
                      figsize=(7., 3.),
                      output=None)<jupyter_output>Plotting spectrum... [DONE]<jupyter_text>Calculating synthetic photometry The [ReadModel](https://species.readthedocs.io/en/latest/species.read.html?highlight=ReadModelspecies.read.read_model.ReadModel) class can also be used for calculating photometric fluxes and magnitudes. To do so, we create a new instance and set the `filter_name` argument to the [VLT/NACO M' filter](http://svo2.cab.inta-csic.es/svo/theory/fps/index.php?id=Paranal/NACO.Mp&&mode=browse&gname=Paranal&gname2=NACOfilter). This will automatically downloadd and addd the filter profile.<jupyter_code>read_model = species.ReadModel(model='drift-phoenix', filter_name='Paranal/NACO.Mp')<jupyter_output>Adding filter: Paranal/NACO.Mp... [DONE]<jupyter_text>We create again a dictionary with the parameters but now run the [get_flux](https://species.readthedocs.io/en/latest/species.read.html?highlight=ReadModelspecies.read.read_model.ReadModel.get_flux) method, which returns the flux in W m-2 um-1.<jupyter_code>model_param = {'teff':1510., 'logg':4.1, 'feh':0.1, 'radius': 1., 'distance': 100.}
flux = read_model.get_flux(model_param)
print(f'Flux (W m-2 um-1) = {flux[0]:.2e}')<jupyter_output>Flux (W m-2 um-1) = 1.33e-17<jupyter_text>Since we provided a radius and distance, the emitted flux at the planet surface has been scaled by (radius/distance)$^2$. Similarly, we can use the [get_magnitude](https://species.readthedocs.io/en/latest/species.read.html?highlight=ReadModelspecies.read.read_model.ReadModel.get_magnitude) method to calculate the magnitude for the NACO M' filter. Note that the returned absolute magnitude is set to `None` if the parameter dictionary does not contain a radius and distance.<jupyter_code>app_mag, abs_mag = read_model.get_magnitude(model_param)
print(f'Apparent magnitude = {app_mag:.2f}')
print(f'Absolute magnitude = {abs_mag:.2f}')<jupyter_output>Downloading Vega spectrum (270 kB)... [DONE]
Adding Vega spectrum... [DONE]
Apparent magnitude = 15.53
Absolute magnitude = 10.53