Before starting here, all the instructions on the installation page should be completed!
Here you will learn how to:
In [ ]:
import warnings
warnings.filterwarnings('ignore')
import pandexo.engine.justdoit as jdi # THIS IS THE HOLY GRAIL OF PANDEXO
import numpy as np
import os
#pip install pandexo.engine --upgrade
In [ ]:
exo_dict = jdi.load_exo_dict()
print(exo_dict.keys())
#print(exo_dict['star']['w_unit'])
In [ ]:
exo_dict['observation']['sat_level'] = 80 #saturation level in percent of full well
exo_dict['observation']['sat_unit'] = '%'
exo_dict['observation']['noccultations'] = 2 #number of transits
exo_dict['observation']['R'] = None #fixed binning. I usually suggest ZERO binning.. you can always bin later
#without having to redo the calcualtion
exo_dict['observation']['baseline_unit'] = 'total' #Defines how you specify out of transit observing time
#'frac' : fraction of time in transit versus out = in/out
#'total' : total observing time (seconds)
exo_dict['observation']['baseline'] = 4.0*60.0*60.0 #in accordance with what was specified above (total observing time)
exo_dict['observation']['noise_floor'] = 0 #this can be a fixed level or it can be a filepath
#to a wavelength dependent noise floor solution (units are ppm)
Note... If you select phoenix
you do not have to provide a starpath
, w_unit
or f_unit
, but you do have to provide a temp
, metal
and logg
. If you select user
you do not need to provide a temp
, metal
and logg
, but you do need to provide units and starpath.
In [ ]:
#OPTION 1 get start from database
exo_dict['star']['type'] = 'phoenix' #phoenix or user (if you have your own)
exo_dict['star']['mag'] = 8.0 #magnitude of the system
exo_dict['star']['ref_wave'] = 1.25 #For J mag = 1.25, H = 1.6, K =2.22.. etc (all in micron)
exo_dict['star']['temp'] = 5500 #in K
exo_dict['star']['metal'] = 0.0 # as log Fe/H
exo_dict['star']['logg'] = 4.0 #log surface gravity cgs
In [ ]:
#Let's create a little fake stellar input
import scipy.constants as sc
wl = np.linspace(0.8, 5, 3000)
nu = sc.c/(wl*1e-6) # frequency in sec^-1
teff = 5500.0
planck_5500K = nu**3 / (np.exp(sc.h*nu/sc.k/teff) - 1)
#can either be dictionary input
starflux = {'f':planck_5500K, 'w':wl}
#or can be as a stellar file
#starflux = 'planck_5500K.dat'
#with open(starflux, 'w') as sf:
# for w,f in zip(wl, planck_5500K):
# sf.write(f'{w:.15f} {f:.15e}\n')
exo_dict['star']['type'] = 'user'
exo_dict['star']['mag'] = 8.0 #magnitude of the system
exo_dict['star']['ref_wave'] = 1.25
exo_dict['star']['starpath'] = starflux
exo_dict['star']['w_unit'] = 'um'
exo_dict['star']['f_unit'] = 'erg/cm2/s/Hz'
In [ ]:
exo_dict['planet']['type'] ='user' #tells pandexo you are uploading your own spectrum
exo_dict['planet']['exopath'] = 'wasp12b.txt'
#or as a dictionary
#exo_dict['planet']['exopath'] = {'f':spectrum, 'w':wavelength}
exo_dict['planet']['w_unit'] = 'cm' #other options include "um","nm" ,"Angs", "sec" (for phase curves)
exo_dict['planet']['f_unit'] = 'rp^2/r*^2' #other options are 'fp/f*'
exo_dict['planet']['transit_duration'] = 2.0*60.0*60.0 #transit duration
exo_dict['planet']['td_unit'] = 's' #Any unit of time in accordance with astropy.units can be added
In [ ]:
exo_dict['planet']['type'] = 'constant' #tells pandexo you want a fixed transit depth
exo_dict['planet']['transit_duration'] = 2.0*60.0*60.0 #transit duration
exo_dict['planet']['td_unit'] = 's'
exo_dict['planet']['radius'] = 1
exo_dict['planet']['r_unit'] = 'R_jup' #Any unit of distance in accordance with astropy.units can be added here
exo_dict['star']['radius'] = 1
exo_dict['star']['r_unit'] = 'R_sun' #Same deal with astropy.units here
exo_dict['planet']['f_unit'] = 'rp^2/r*^2' #this is what you would do for primary transit
#ORRRRR....
#if you wanted to instead to secondary transit at constant temperature
#exo_dict['planet']['f_unit'] = 'fp/f*'
#exo_dict['planet']['temp'] = 1000
In [ ]:
exo_dict['planet']['type'] = 'grid' #tells pandexo you want to pull from the grid
exo_dict['planet']['temp'] = 1000 #grid: 500, 750, 1000, 1250, 1500, 1750, 2000, 2250, 2500
exo_dict['planet']['chem'] = 'noTiO' #options: 'noTiO' and 'eqchem', noTiO is chemical eq. without TiO
exo_dict['planet']['cloud'] = 'ray10' #options: nothing: '0',
# Weak, medium, strong scattering: ray10,ray100, ray1000
# Weak, medium, strong cloud: flat1,flat10, flat100
exo_dict['planet']['mass'] = 1
exo_dict['planet']['m_unit'] = 'M_jup' #Any unit of mass in accordance with astropy.units can be added here
exo_dict['planet']['radius'] = 1
exo_dict['planet']['r_unit'] = 'R_jup' #Any unit of distance in accordance with astropy.units can be added here
exo_dict['star']['radius'] = 1
exo_dict['star']['r_unit'] = 'R_sun' #Same deal with astropy.units here
Step 2 is optional because PandExo has the functionality to automatically load in instrument dictionaries. Skip this if you plan on observing with one of the following and want to use the subarray with the smallest frame time and the readout mode with 1 frame/1 group (standard):
In [ ]:
#jdi.print_instruments()
result = jdi.run_pandexo(exo_dict,['NIRCam F322W2'])
In [ ]:
inst_dict = jdi.load_mode_dict('NIRSpec G140H')
#loading in instrument dictionaries allow you to personalize some of
#the fields that are predefined in the templates. The templates have
#the subbarays with the lowest frame times and the readmodes with 1 frame per group.
#if that is not what you want. change these fields
#Try printing this out to get a feel for how it is structured:
print(inst_dict['configuration'])
In [ ]:
#Another way to display this is to print out the keys
inst_dict.keys()
In [ ]:
print("SUBARRAYS")
print(jdi.subarrays('nirspec'))
print("FILTERS")
print(jdi.filters('nircam'))
print("DISPERSERS")
print(jdi.dispersers('nirspec'))
In [ ]:
#you can try personalizing some of these fields
inst_dict["configuration"]["detector"]["ngroup"] = 'optimize' #running "optimize" will select the maximum
#possible groups before saturation.
#You can also write in any integer between 2-65536
inst_dict["configuration"]["detector"]["subarray"] = 'substrip256' #change the subbaray
In [ ]:
inst_dict['background'] = 'ecliptic'
inst_dict['background_level'] = 'high'
PandExo only will extract a single order at a time. By default, it is set to extract Order 1. Below you can see how to extract the second order.
NOTE! Users should be careful with this calculation. Saturation will be limited by the first order. Therefore, I suggest running one calculation with ngroup='optmize'
for Order 1. This will give you an idea of a good number of groups to use. Then, you can use that in this order 2 calculation.
In [ ]:
inst_dict = jdi.load_mode_dict('NIRISS SOSS')
inst_dict['strategy']['order'] = 2
inst_dict['configuration']['detector']['subarray'] = 'substrip256'
ngroup_from_order1_run = 2
inst_dict["configuration"]["detector"]["ngroup"] = ngroup_from_order1_run
In [ ]:
jdi.print_instruments()
In [ ]:
result = jdi.run_pandexo(exo_dict,['NIRCam F322W2'])
In [ ]:
inst_dict = jdi.load_mode_dict('NIRSpec G140H')
#personalize subarray
inst_dict["configuration"]["detector"]["subarray"] = 'sub2048'
result = jdi.run_pandexo(exo_dict, inst_dict)
In [ ]:
#choose select
result = jdi.run_pandexo(exo_dict,['NIRSpec G140M','NIRSpec G235M','NIRSpec G395M'],
output_file='three_nirspec_modes.p')
#run all
#result = jdi.run_pandexo(exo_dict, ['RUN ALL'], save_file = False)
Use a single modes from print_isntruments() options. But explore parameter space with respect to any parameter in the exo dict. The example below shows how to loop over several planet models
You can loop through anything in the exoplanet dictionary. It will be planet, star or observation followed by whatever you want to loop through in that set.
i.e. planet+exopath, star+temp, star+metal, star+logg, observation+sat_level.. etc
In [ ]:
#looping over different exoplanet models
jdi.run_pandexo(exo_dict, ['NIRCam F444W'], param_space = 'planet+exopath',
param_range = os.listdir('/path/to/location/of/models'),
output_path = '/path/to/output/simulations')
#looping over different stellar temperatures
jdi.run_pandexo(exo_dict, ['NIRCam F444W'], param_space = 'star+temp',
param_range = np.linspace(5000,8000,2),
output_path = '/path/to/output/simulations')
#looping over different saturation levels
jdi.run_pandexo(exo_dict, ['NIRCam F444W'], param_space = 'observation+sat_level',
param_range = np.linspace(.5,1,5),
output_path = '/path/to/output/simulations')