{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Getting Started\n", "\n", "Before starting here, all the instructions on the [installation page](https://natashabatalha.github.io/PandExo/installation.html) should be completed! \n", "\n", "Here you will learn how to: \n", "\n", "- set planet properties \n", "- set stellar properties\n", "- run default instrument modes \n", "- adjust instrument modes \n", "- run pandexo" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import warnings\n", "warnings.filterwarnings('ignore')\n", "import pandexo.engine.justdoit as jdi # THIS IS THE HOLY GRAIL OF PANDEXO\n", "import numpy as np\n", "import os\n", "#pip install pandexo.engine --upgrade" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Make sure that your environment path is set to match the correct version of pandeia" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(os.environ['pandeia_refdata'] )\n", "import pandeia.engine\n", "print(pandeia.engine.__version__)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Load blank exo dictionary\n", "\n", "To start, load in a blank exoplanet dictionary with empty keys. You will fill these out for yourself in the next step. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "exo_dict = jdi.load_exo_dict()\n", "print(exo_dict.keys())\n", "#print(exo_dict['star']['w_unit'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Edit exoplanet observation inputs\n", "Editting each keys are annoying. But, do this carefully or it could result in nonsense runs" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "exo_dict['observation']['sat_level'] = 80 #saturation level in percent of full well \n", "exo_dict['observation']['sat_unit'] = '%'\n", "exo_dict['observation']['noccultations'] = 1 #number of transits \n", "exo_dict['observation']['R'] = None #fixed binning. I usually suggest ZERO binning.. you can always bin later \n", " #without having to redo the calcualtion\n", "exo_dict['observation']['baseline_unit'] = 'total' #Defines how you specify out of transit observing time\n", " #'frac' : fraction of time in transit versus out = in/out \n", " #'total' : total observing time (seconds)\n", "exo_dict['observation']['baseline'] = 4.0*60.0*60.0 #in accordance with what was specified above (total observing time)\n", "\n", "exo_dict['observation']['noise_floor'] = 0 #this can be a fixed level or it can be a filepath \n", " #to a wavelength dependent noise floor solution (units are ppm)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Edit exoplanet host star inputs\n", "\n", "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. \n", "\n", "#### Option 1) Grab stellar model from database" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#OPTION 1 get start from database\n", "exo_dict['star']['type'] = 'phoenix' #phoenix or user (if you have your own)\n", "exo_dict['star']['mag'] = 8.0 #magnitude of the system\n", "exo_dict['star']['ref_wave'] = 1.25 #For J mag = 1.25, H = 1.6, K =2.22.. etc (all in micron)\n", "exo_dict['star']['temp'] = 5500 #in K \n", "exo_dict['star']['metal'] = 0.0 # as log Fe/H\n", "exo_dict['star']['logg'] = 4.0 #log surface gravity cgs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Option 1) Input as dictionary or filename" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Let's create a little fake stellar input\n", "\n", "import scipy.constants as sc\n", "wl = np.linspace(0.8, 5, 3000)\n", "nu = sc.c/(wl*1e-6) # frequency in sec^-1\n", "teff = 5500.0\n", "planck_5500K = nu**3 / (np.exp(sc.h*nu/sc.k/teff) - 1)\n", "\n", "#can either be dictionary input\n", "starflux = {'f':planck_5500K, 'w':wl}\n", "#or can be as a stellar file\n", "#starflux = 'planck_5500K.dat'\n", "#with open(starflux, 'w') as sf:\n", "# for w,f in zip(wl, planck_5500K):\n", "# sf.write(f'{w:.15f} {f:.15e}\\n')\n", "\n", "exo_dict['star']['type'] = 'user' \n", "exo_dict['star']['mag'] = 8.0 #magnitude of the system\n", "exo_dict['star']['ref_wave'] = 1.25 \n", "exo_dict['star']['starpath'] = starflux \n", "exo_dict['star']['w_unit'] = 'um'\n", "exo_dict['star']['f_unit'] = 'erg/cm2/s/Hz'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Edit exoplanet inputs using one of three options\n", "\n", "1) user specified\n", "2) constant value\n", "3) select from grid" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 1) Edit exoplanet planet inputs if using your own model" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "exo_dict['planet']['type'] ='user' #tells pandexo you are uploading your own spectrum\n", "exo_dict['planet']['exopath'] = 'wasp12b.txt'\n", "\n", "#or as a dictionary\n", "#exo_dict['planet']['exopath'] = {'f':spectrum, 'w':wavelength}\n", "\n", "exo_dict['planet']['w_unit'] = 'cm' #other options include \"um\",\"nm\" ,\"Angs\", \"sec\" (for phase curves)\n", "exo_dict['planet']['f_unit'] = 'rp^2/r*^2' #other options are 'fp/f*' \n", "exo_dict['planet']['transit_duration'] = 2.0*60.0*60.0 #transit duration \n", "exo_dict['planet']['td_unit'] = 's' #Any unit of time in accordance with astropy.units can be added" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 2) Users can also add in a constant temperature or a constant transit depth " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "exo_dict['planet']['type'] = 'constant' #tells pandexo you want a fixed transit depth\n", "exo_dict['planet']['transit_duration'] = 2.0*60.0*60.0 #transit duration \n", "exo_dict['planet']['td_unit'] = 's' \n", "exo_dict['planet']['radius'] = 1\n", "exo_dict['planet']['r_unit'] = 'R_jup' #Any unit of distance in accordance with astropy.units can be added here\n", "exo_dict['star']['radius'] = 1\n", "exo_dict['star']['r_unit'] = 'R_sun' #Same deal with astropy.units here\n", "exo_dict['planet']['f_unit'] = 'rp^2/r*^2' #this is what you would do for primary transit \n", "\n", "#ORRRRR....\n", "#if you wanted to instead to secondary transit at constant temperature \n", "#exo_dict['planet']['f_unit'] = 'fp/f*' \n", "#exo_dict['planet']['temp'] = 1000" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### 3) Select from grid\n", "NOTE: Currently only the fortney grid for hot Jupiters from Fortney+2010 is supported. Holler though, if you want another grid supported" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "exo_dict['planet']['type'] = 'grid' #tells pandexo you want to pull from the grid\n", "exo_dict['planet']['temp'] = 1000 #grid: 500, 750, 1000, 1250, 1500, 1750, 2000, 2250, 2500\n", "exo_dict['planet']['chem'] = 'noTiO' #options: 'noTiO' and 'eqchem', noTiO is chemical eq. without TiO\n", "exo_dict['planet']['cloud'] = 'ray10' #options: nothing: '0', \n", "# Weak, medium, strong scattering: ray10,ray100, ray1000\n", "# Weak, medium, strong cloud: flat1,flat10, flat100\n", "exo_dict['planet']['mass'] = 1\n", "exo_dict['planet']['m_unit'] = 'M_jup' #Any unit of mass in accordance with astropy.units can be added here\n", "exo_dict['planet']['radius'] = 1\n", "exo_dict['planet']['r_unit'] = 'R_jup' #Any unit of distance in accordance with astropy.units can be added here\n", "exo_dict['star']['radius'] = 1\n", "exo_dict['star']['r_unit'] = 'R_sun' #Same deal with astropy.units here\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Load in instrument dictionary (OPTIONAL)\n", " \n", "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): \n", "- NIRCam F444W\n", "- NIRSpec Prism\n", "- NIRSpec G395M\n", "- NIRSpec G395H\n", "- NIRSpec G235H\n", "- NIRSpec G235M\n", "- NIRCam F322W\n", "- NIRSpec G140M\n", "- NIRSpec G140H\n", "- MIRI LRS\n", "- NIRISS SOSS" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "jdi.print_instruments()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "inst_dict = jdi.load_mode_dict('NIRSpec G140H')\n", "\n", "#loading in instrument dictionaries allow you to personalize some of \n", "#the fields that are predefined in the templates. The templates have \n", "#the subbarays with the lowest frame times and the readmodes with 1 frame per group. \n", "#if that is not what you want. change these fields\n", "\n", "#Try printing this out to get a feel for how it is structured: \n", "\n", "print(inst_dict['configuration'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Another way to display this is to print out the keys \n", "inst_dict.keys()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Don't know what instrument options there are?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(\"SUBARRAYS\")\n", "print(jdi.subarrays('nirspec'))\n", "\n", "print(\"FILTERS\")\n", "print(jdi.filters('nircam'))\n", "\n", "print(\"DISPERSERS\")\n", "print(jdi.dispersers('nirspec'))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#you can try personalizing some of these fields\n", "\n", "inst_dict[\"configuration\"][\"detector\"][\"ngroup\"] = 'optimize' #running \"optimize\" will select the maximum \n", " #possible groups before saturation. \n", " #You can also write in any integer between 2-65536\n", "\n", "inst_dict[\"configuration\"][\"detector\"][\"subarray\"] = 'substrip256' #change the subbaray\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Adjusting the Background Level\n", "\n", "You may want to think about adjusting the background level of your observation, based on the position of your target. PandExo two options and three levels for the position: \n", "\n", "- ``ecliptic`` or ``minzodi`` \n", "- ``low``, ``medium``, ``high``" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "inst_dict['background'] = 'ecliptic'\n", "inst_dict['background_level'] = 'high'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Running NIRISS SOSS Order 2\n", "\n", "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. \n", "\n", "**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. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "inst_dict = jdi.load_mode_dict('NIRISS SOSS')\n", "inst_dict['strategy']['order'] = 2\n", "inst_dict['configuration']['detector']['subarray'] = 'substrip256'\n", "ngroup_from_order1_run = 2\n", "inst_dict[\"configuration\"][\"detector\"][\"ngroup\"] = ngroup_from_order1_run" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Running PandExo\n", "\n", "You have **four options** for running PandExo. All of them are accessed through attribute **jdi.run_pandexo**. See examples below. \n", "\n", "` jdi.run_pandexo(exo, inst, param_space = 0, param_range = 0,save_file = True,\n", " output_path=os.getcwd(), output_file = '', verbose=True)`\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Option 1- Run single instrument mode, single planet\n", "If you forget which instruments are available run **jdi.print_isntruments()** and pick one " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "jdi.print_instruments()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "result = jdi.run_pandexo(exo_dict,['NIRCam F322W2'], verbose=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note, you can turn off print statements with `verbose=False`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Option 2- Run single instrument mode (with user dict), single planet\n", "This is the same thing as option 1 but instead of feeding it a list of keys, you can feed it a instrument dictionary (this is for users who wanted to simulate something NOT pre defined within pandexo)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "inst_dict = jdi.load_mode_dict('NIRSpec G140H')\n", "#personalize subarray\n", "inst_dict[\"configuration\"][\"detector\"][\"subarray\"] = 'sub2048'\n", "result = jdi.run_pandexo(exo_dict, inst_dict)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Option 3- Run several modes, single planet\n", "Use several modes from **print_isntruments()** options. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#choose select \n", "result = jdi.run_pandexo(exo_dict,['NIRSpec G140M','NIRSpec G235M','NIRSpec G395M'],\n", " output_file='three_nirspec_modes.p',verbose=True)\n", "#run all \n", "#result = jdi.run_pandexo(exo_dict, ['RUN ALL'], save_file = False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Option 4- Run single mode, several planet cases\n", "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\n", "\n", "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. \n", "\n", "i.e. planet+exopath, star+temp, star+metal, star+logg, observation+sat_level.. etc" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#looping over different exoplanet models \n", "jdi.run_pandexo(exo_dict, ['NIRCam F444W'], param_space = 'planet+exopath',\n", " param_range = os.listdir('/path/to/location/of/models'),\n", " output_path = '/path/to/output/simulations')\n", "\n", "#looping over different stellar temperatures \n", "jdi.run_pandexo(exo_dict, ['NIRCam F444W'], param_space = 'star+temp',\n", " param_range = np.linspace(5000,8000,2),\n", " output_path = '/path/to/output/simulations')\n", "\n", "#looping over different saturation levels\n", "jdi.run_pandexo(exo_dict, ['NIRCam F444W'], param_space = 'observation+sat_level',\n", " param_range = np.linspace(.5,1,5),\n", " output_path = '/path/to/output/simulations')\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.0" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": true, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 1 }