├── workshops ├── EPSCDPS_2019_Geneva │ └── sbpy.pdf ├── EPSC_2018_Berlin │ └── sbpy_berlin.pdf ├── DPS_2018_Knoxville │ └── sbpy_DPS2018.pdf └── LSST_SSSC_Sprint_2022 │ ├── LSST_SSSC_Sprint_2022.pdf │ ├── 5-gas.ipynb │ ├── 4-dust.ipynb │ └── 1-data-containers.ipynb ├── notebooks ├── activity │ ├── data │ │ ├── CO.csv │ │ ├── CH3OH.csv │ │ └── HCN.csv │ ├── nucleus-corrected-afrho.ipynb │ └── NonLTE_prodrate.ipynb ├── spectroscopy │ ├── spectral-gradient.ipynb │ └── reddened-solar-spectrum.ipynb └── data │ ├── Phys.ipynb │ ├── Orbit.ipynb │ └── Names.ipynb ├── .gitignore ├── LICENSE.rst └── README.md /workshops/EPSCDPS_2019_Geneva/sbpy.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NASA-Planetary-Science/sbpy-tutorial/HEAD/workshops/EPSCDPS_2019_Geneva/sbpy.pdf -------------------------------------------------------------------------------- /workshops/EPSC_2018_Berlin/sbpy_berlin.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NASA-Planetary-Science/sbpy-tutorial/HEAD/workshops/EPSC_2018_Berlin/sbpy_berlin.pdf -------------------------------------------------------------------------------- /workshops/DPS_2018_Knoxville/sbpy_DPS2018.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NASA-Planetary-Science/sbpy-tutorial/HEAD/workshops/DPS_2018_Knoxville/sbpy_DPS2018.pdf -------------------------------------------------------------------------------- /workshops/LSST_SSSC_Sprint_2022/LSST_SSSC_Sprint_2022.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NASA-Planetary-Science/sbpy-tutorial/HEAD/workshops/LSST_SSSC_Sprint_2022/LSST_SSSC_Sprint_2022.pdf -------------------------------------------------------------------------------- /notebooks/activity/data/CO.csv: -------------------------------------------------------------------------------- 1 | U_T,Time,T_B,Q,log(Q) 2 | 2017-12-22.21,2017-12-22 05:02:24,0.26,4.40E+28,28.64345268 3 | 2017-12-23.09,2017-12-23 02:09:36,0.28,4.60E+28,28.66275783 4 | 2017-12-30.14,2017-12-30 03:21:36,0.26,4.60E+28,28.66275783 5 | 2017-12-31.13,2017-12-31 03:07:12,0.27,4.60E+28,28.66275783 6 | 2018-01-16.03,2018-01-16 00:43:12,0.27,4.60E+28,28.66275783 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled files 2 | *.py[cod] 3 | *.a 4 | *.o 5 | *.so 6 | __pycache__ 7 | 8 | # Ignore .c files by default to avoid including generated code. If you want to 9 | # add a non-generated .c extension, use `git add -f filename.c`. 10 | *.c 11 | 12 | # Other generated files 13 | */version.py 14 | */cython_version.py 15 | htmlcov 16 | .coverage 17 | MANIFEST 18 | .ipynb_checkpoints 19 | 20 | # Sphinx 21 | docs/api 22 | docs/_build 23 | 24 | # Eclipse editor project files 25 | .project 26 | .pydevproject 27 | .settings 28 | 29 | # Pycharm editor project files 30 | .idea 31 | 32 | # Floobits project files 33 | .floo 34 | .flooignore 35 | 36 | # Packages/installer info 37 | *.egg 38 | *.egg-info 39 | dist 40 | build 41 | eggs 42 | parts 43 | bin 44 | var 45 | sdist 46 | develop-eggs 47 | .installed.cfg 48 | distribute-*.tar.gz 49 | 50 | # Other 51 | .cache 52 | .tox 53 | .*.sw[op] 54 | *~ 55 | .project 56 | .pydevproject 57 | .settings 58 | 59 | # Mac OSX 60 | .DS_Store 61 | -------------------------------------------------------------------------------- /LICENSE.rst: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-2022, sbpy Developers 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | * Neither the name of the Astropy Team nor the names of its contributors may be 14 | used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 21 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 24 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /notebooks/activity/data/CH3OH.csv: -------------------------------------------------------------------------------- 1 | UT_Date,Time,T_B,log(Q),error_top,error_bottom,Q,Q_top,Q_bottom3.0339,2010-11-03 00:48:49,0.07,26.44,0.044,0.02,2.75E+26,3.05E+26,2.63E+26 2 | 3.0868,2010-11-03 02:05:00,0.088,26.534,0.4,0.017,3.42E+26,8.59E+26,3.29E+26 3 | 3.1495,2010-11-03 03:35:17,0.118,26.664,0.035,0.009,4.61E+26,5.00E+26,4.52E+26 4 | 3.2062,2010-11-03 04:56:56,0.115,26.653,0.036,0.011,4.50E+26,4.89E+26,4.39E+26 5 | 3.2593,2010-11-03 06:13:24,0.123,26.681,0.038,0.012,4.80E+26,5.24E+26,4.67E+26 6 | 3.302,2010-11-03 07:14:53,0.124,26.685,0.037,0.014,4.84E+26,5.27E+26,4.69E+26 7 | 3.3527,2010-11-03 08:27:53,0.097,26.578,0.037,0.015,3.78E+26,4.12E+26,3.66E+26 8 | 4.0268,2010-11-04 00:38:36,0.093,26.56,0.045,0.02,3.63E+26,4.03E+26,3.47E+26 9 | 4.0676,2010-11-04 01:37:21,0.11,26.633,0.036,0.015,4.30E+26,4.67E+26,4.15E+26 10 | 4.1222,2010-11-04 02:55:58,0.098,26.584,0.035,0.013,3.84E+26,4.16E+26,3.72E+26 11 | 4.1852,2010-11-04 04:26:41,0.093,26.559,0.039,0.014,3.62E+26,3.96E+26,3.51E+26 12 | 4.2492,2010-11-04 05:58:51,0.089,26.541,0.041,0.019,3.48E+26,3.82E+26,3.33E+26 13 | 4.2904,2010-11-04 06:58:11,0.081,26.5,0.043,0.016,3.16E+26,3.49E+26,3.05E+26 14 | 4.3399,2010-11-04 08:09:27,0.069,26.432,0.043,0.023,2.70E+26,2.99E+26,2.56E+26 15 | 5.0163,2010-11-05 00:23:28,0.09,26.545,0.043,0.021,3.51E+26,3.87E+26,3.34E+26 16 | 5.0673,2010-11-05 01:36:55,0.067,26.42,0.041,0.02,2.63E+26,2.89E+26,2.51E+26 17 | 5.1246,2010-11-05 02:59:25,0.075,26.467,0.04,0.019,2.93E+26,3.21E+26,2.81E+26 18 | 5.1873,2010-11-05 04:29:43,0.061,26.375,0.046,0.021,2.37E+26,2.64E+26,2.26E+26 19 | 5.2426,2010-11-05 05:49:21,0.063,26.394,0.045,0.022,2.48E+26,2.75E+26,2.36E+26 20 | 5.2932,2010-11-05 07:02:12,0.075,26.467,0.043,0.021,2.93E+26,3.24E+26,2.79E+26 21 | 5.3477,2010-11-05 08:20:41,0.107,26.623,0.044,0.016,4.20E+26,4.65E+26,4.05E+26 22 | -------------------------------------------------------------------------------- /notebooks/activity/data/HCN.csv: -------------------------------------------------------------------------------- 1 | UT_Date,Time,T_B,log(Q),error_top,error_bottom,Q,Q_top,Q_bottom 2 | 2.0558,2010-11-02 01:20:21,0.672,24.813,0.081,0.013,6.5013E+24,7.8343E+24,6.30957E+24 3 | 2.1075,2010-11-02 02:34:48,1.06,25.011,0.078,0.007,1.02565E+25,1.22744E+25,1.00925E+25 4 | 2.1672,2010-11-02 04:00:46,1.234,25.076,0.078,0.004,1.19124E+25,1.42561E+25,1.18032E+25 5 | 2.2289,2010-11-02 05:29:37,1.357,25.118,0.082,0.004,1.3122E+25,1.58489E+25,1.30017E+25 6 | 2.2817,2010-11-02 06:45:39,1.89,25.262,0.077,0.004,1.8281E+25,2.18273E+25,1.81134E+25 7 | 2.3359,2010-11-02 08:03:42,1.786,25.237,0.081,0.007,1.72584E+25,2.0797E+25,1.69824E+25 8 | 2.3723,2010-11-02 08:56:07,1.509,25.164,0.087,0.012,1.45881E+25,1.78238E+25,1.41906E+25 9 | 3.0339,2010-11-03 00:48:49,1.222,25.072,0.077,0.008,1.18032E+25,1.40929E+25,1.15878E+25 10 | 3.0868,2010-11-03 02:05:00,1.503,25.162,0.079,0.005,1.45211E+25,1.74181E+25,1.43549E+25 11 | 3.1495,2010-11-03 03:35:17,1.916,25.268,0.078,0.004,1.85353E+25,2.2182E+25,1.83654E+25 12 | 3.2062,2010-11-03 04:56:56,1.72,25.221,0.084,0.004,1.66341E+25,2.01837E+25,1.64816E+25 13 | 3.2593,2010-11-03 06:13:24,2.154,25.319,0.083,0.004,2.08449E+25,2.52348E+25,2.06538E+25 14 | 3.302,2010-11-03 07:14:53,1.869,25.257,0.08,0.005,1.80717E+25,2.1727E+25,1.78649E+25 15 | 3.3527,2010-11-03 08:27:53,1.115,25.032,0.082,0.005,1.07647E+25,1.30017E+25,1.06414E+25 16 | 4.0268,2010-11-04 00:38:36,1.595,25.188,0.077,0.007,1.5417E+25,1.84077E+25,1.51705E+25 17 | 4.0676,2010-11-04 01:37:21,1.775,25.234,0.077,0.005,1.71396E+25,2.04644E+25,1.69434E+25 18 | 4.1222,2010-11-04 02:55:58,1.577,25.183,0.081,0.005,1.52405E+25,1.83654E+25,1.50661E+25 19 | 4.1852,2010-11-04 04:26:41,1.186,25.059,0.083,0.005,1.14551E+25,1.38676E+25,1.1324E+25 20 | 4.2492,2010-11-04 05:58:51,0.889,24.934,0.085,0.01,8.59014E+24,1.04472E+25,8.3946E+24 21 | 4.2904,2010-11-04 06:58:11,0.978,24.976,0.085,0.009,9.46237E+24,1.1508E+25,9.2683E+24 22 | 4.3399,2010-11-04 08:09:27,0.753,24.862,0.087,0.011,7.2778E+24,8.89201E+24,7.09578E+24 23 | 5.0163,2010-11-05 00:23:28,0.795,24.886,0.088,0.013,7.6913E+24,9.4189E+24,7.46449E+24 24 | 5.0673,2010-11-05 01:36:55,0.762,24.867,0.078,0.011,7.36207E+24,8.81049E+24,7.17794E+24 25 | 5.1246,2010-11-05 02:59:25,0.67,24.811,0.076,0.009,6.47143E+24,7.70903E+24,6.3387E+24 26 | 5.1873,2010-11-05 04:29:43,0.521,24.702,0.082,0.013,5.03501E+24,6.08135E+24,4.88652E+24 27 | 5.2426,2010-11-05 05:49:21,0.578,24.747,0.081,0.015,5.5847E+24,6.72977E+24,5.39511E+24 28 | 5.2932,2010-11-05 07:02:12,1.009,24.989,0.084,0.009,9.7499E+24,1.18304E+25,9.54993E+24 29 | 5.3477,2010-11-05 08:20:41,1.216,25.07,0.083,0.015,1.1749E+25,1.42233E+25,1.13501E+25 30 | -------------------------------------------------------------------------------- /notebooks/spectroscopy/spectral-gradient.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Spectral Gradient\n", 8 | "\n", 9 | "In this exercise, we will measure the spectral gradient of a comet nucleus. The data set is comet 322P/SOHO as measured by Knight et al. (2016, ApJ 823, L6).\n", 10 | "\n", 11 | "## Data\n", 12 | "\n", 13 | "Knight et al. observed 322P with the FORS2 instrument on VLT, with the *g_High*, *R_special*, and *i_Bessel* filters. The data were calibrated to the SDSS photometric system (Smith et al. 2002, BAAS 34, 1272), resulting in *g'-r'* and *r'-i'* colors.\n", 14 | "\n", 15 | "## Top-level imports\n", 16 | "\n", 17 | "We need astropy's ``units``, and the `SpectralGradient` class from sbpy. The SDSS filter bandpasses are distributed with sbpy, and retrievable via `bandpass`. We will also use sbpy's solar spectrum." 18 | ] 19 | }, 20 | { 21 | "cell_type": "code", 22 | "execution_count": 1, 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "import astropy.units as u\n", 27 | "from sbpy.spectroscopy import SpectralGradient\n", 28 | "from sbpy.photometry import bandpass\n", 29 | "from sbpy.calib import Sun" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "## Define input data\n", 37 | "\n", 38 | "SDSS uses the AB-magnitude system:" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 2, 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [ 47 | "g = bandpass('SDSS g')\n", 48 | "r = bandpass('SDSS r')\n", 49 | "i = bandpass('SDSS i')\n", 50 | "\n", 51 | "gmr = 0.52 * u.mag # ±0.04\n", 52 | "rmi = 0.03 * u.mag # ±0.06" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "## Ratio with the Sun\n", 60 | "\n", 61 | "`SpectralGradient` requires observations in units of reflectance, i.e., the spectrum of the Sun must be removed. Calculate the color of the Sun in the same units as the SDSS photometric system (AB magnitudes)." 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": 3, 67 | "metadata": {}, 68 | "outputs": [ 69 | { 70 | "name": "stdout", 71 | "output_type": "stream", 72 | "text": [ 73 | "Sun(g'-r') = 0.48 mag\n", 74 | "Sun(r'-i') = 0.11 mag\n" 75 | ] 76 | } 77 | ], 78 | "source": [ 79 | "sun = Sun.from_default()\n", 80 | "\n", 81 | "lambda_eff, color = sun.color_index((g, r), u.ABmag)\n", 82 | "print(\"Sun(g'-r') = {:.2f}\".format(color))\n", 83 | "gmr = gmr - color\n", 84 | "\n", 85 | "lambda_eff, color = sun.color_index((r, i), u.ABmag)\n", 86 | "print(\"Sun(r'-i') = {:.2f}\".format(color))\n", 87 | "rmi = rmi - color" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "## Calculate spectral gradient" 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 4, 100 | "metadata": {}, 101 | "outputs": [ 102 | { 103 | "name": "stdout", 104 | "output_type": "stream", 105 | "text": [ 106 | "g'-r' = 0.04 mag → S(g'-r') = 2.6 % / 100 nm\n", 107 | "r'-i' = -0.08 mag → S(r'-i') = -5.4 % / 100 nm\n" 108 | ] 109 | } 110 | ], 111 | "source": [ 112 | "for label, filters, color in ((\"g'-r'\", (g, r), gmr), (\"r'-i'\", (r, i), rmi)):\n", 113 | " S = SpectralGradient.from_color(filters, color)\n", 114 | " print(\"{} = {:.2f} → S({}) = {:.1f}\".format(label, color, label, S))" 115 | ] 116 | } 117 | ], 118 | "metadata": { 119 | "kernelspec": { 120 | "display_name": "Python 3", 121 | "language": "python", 122 | "name": "python3" 123 | }, 124 | "language_info": { 125 | "codemirror_mode": { 126 | "name": "ipython", 127 | "version": 3 128 | }, 129 | "file_extension": ".py", 130 | "mimetype": "text/x-python", 131 | "name": "python", 132 | "nbconvert_exporter": "python", 133 | "pygments_lexer": "ipython3", 134 | "version": "3.6.8" 135 | } 136 | }, 137 | "nbformat": 4, 138 | "nbformat_minor": 2 139 | } 140 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sbpy Tutorials and Workshops Materials 2 | 3 | This repository provide tutorials and materials used in workshops related to [sbpy](http://sbpy.org). 4 | 5 | ## Future Workshops 6 | 7 | ## Previous Workshops 8 | 9 | * **LSST Solar System Science Collaboration Sprint 2022**, virtual: June 6, 2022 UTC. 10 | 11 | * **European Planetary Science Congress/Division for Planetary Science Joint Meeting ([EPSC/DPS](https://www.epsc-dps2019.eu/)) 2019**, Genève, Switzerland: Tuesday, September 17, 2019, 13:30 to 15:00 ([SMW1.22](https://meetingorganizer.copernicus.org/EPSC-DPS2019/session/34640), Room Ceres) 12 | 13 | * **Division for Planetary Science Meeting ([DPS](https://aas.org/meetings/dps50)) 2018**, Knoxville, Tennessee: Thursday, October 25, 4:30 pm to 7:00 pm (Room 301 D-E) 14 | 15 | * **European Planetary Science Congress ([EPSC](https://www.epsc2018.eu/)) 2018**, Berlin, Germany: Tuesday, September 18 2018, 18:15 to 20:00 (SMW1.8) 16 | 17 | # List of Notebooks and Examples 18 | 19 | This repository contains a number of examples for how to use sbpy. For your convenience, we here list these examples by topic. 20 | 21 | ## Notebooks related to data handling 22 | 23 | * [General concepts](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/data/General_concepts.ipynb) of `DataClass` and data handling 24 | * [Querying asteroid and satellite ephemerides](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/data/Ephem.ipynb) from JPL Horizons and other systems 25 | * [Computing ephemerides with pyoorb](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/data/Ephem.ipynb) 26 | * [Querying orbital elements](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/data/Orbit.ipynb) from JPL Horizons and other systems 27 | * [Create an orbit and ephemeris from scratch](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/data/Orbit_and_ephemeris_from_scratch.ipynb), without an online service 28 | * [Transforming and propagating orbits](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/data/Orbit.ipynb) using pyoorb 29 | * [Curating observational data](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/data/Obs.ipynb) 30 | * [Querying observations reported to the Minor Planet Center](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/data/Obs.ipynb#Retrieving-observations-from-the-Minor-Planet-Center) 31 | * [Querying physical properties](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/data/Phys.ipynb) from [JPL SBDB](https://ssd.jpl.nasa.gov/sbdb.cgi) 32 | * [Querying molecular data](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/data/Phys.ipynb#Querying-Molecular-Data) from the [JPL Molecular Spectroscopy Catalog](https://spec.jpl.nasa.gov/home.html) 33 | * [Parsing asteroid and comet identifiers](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/data/Names.ipynb) 34 | * [Plotting orbit diagrams](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/data/orbit-diagram.ipynb) 35 | 36 | ## Notebooks related to cometary activity 37 | 38 | * [Modeling dust coma brightness](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/activity/dust-coma-brightness.ipynb) using Afρ 39 | * [Haser model](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/activity/haser-model.ipynb) examples 40 | * [Calculating non-LTE column densities](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/activity/NonLTE_prodrate.ipynb) using pyradex 41 | * [Calculating LTE production rates using a Haser Model](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/activity/LTE_prodrate_Haser.ipynb) 42 | * [Calculating LTE production rates without photodissociation effects](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/activity/LTE_prodrate_without_photolysis.ipynb) 43 | 44 | ## Notebooks related to photometry and phase curve modeling 45 | 46 | * [Disk-integrated photometric phase functions](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/photometry/integrated_phasefunc.ipynb) 47 | 48 | ## Notebooks related to spectroscopy 49 | 50 | * [Using spectral gradients](https://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/spectroscopy/spectral-gradient.ipynb) 51 | 52 | * [Reddening a solar spectrum](ttps://github.com/NASA-Planetary-Science/sbpy-tutorial/blob/master/notebooks/spectroscopy/reddened-solar-spectrum.ipynb) 53 | 54 | ## Acknowledgements 55 | 56 | *sbpy* is supported by NASA PDART Grant No. 80NSSC18K0987. 57 | -------------------------------------------------------------------------------- /notebooks/activity/nucleus-corrected-afrho.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "attachments": {}, 5 | "cell_type": "markdown", 6 | "metadata": {}, 7 | "source": [ 8 | "# Nucleus-corrected *Afρ* values\n", 9 | "\n", 10 | "Given a measurement of a comet with an estimated nuclear size, what is the *Afρ* quantity with and without the nucleus brightness removed?\n", 11 | "\n", 12 | "## Background\n", 13 | "\n", 14 | "Given a circular aperture of radius *ρ* centered on the comet, *Afρ* is the product of albedo, filling factor, and aperture radius in units of length projected to the distance of the comet. With some caveats, it is useful for inter-comparing cometary photometry (A'Hearn et al. 1984; Fink and Rubin 2012).\n", 15 | "\n", 16 | "In some cases, a cometary nucleus may contribute a significant fraction of the observed brightness. Such a scenario may bias one's interpretation of the *Afρ* value. If the nucleus size or brightness is known, it ca be removed before computing *Afρ*. `sbpy` can help address this problem." 17 | ] 18 | }, 19 | { 20 | "attachments": {}, 21 | "cell_type": "markdown", 22 | "metadata": {}, 23 | "source": [ 24 | "## The observational data and nominal *Afρ*\n", 25 | "\n", 26 | "Given the following observational circumstances, what is the *Afρ* quantity, neglecting any potential nuclear contribution?\n", 27 | "\n", 28 | "* *V* = 18 mag (VEGA magnitude system)\n", 29 | "* *ρ* = 5 arcsec\n", 30 | "* heliocentric distance, $r_h$ = 2.5 au\n", 31 | "* observer-target distance, *Δ* = 3.5 au\n", 32 | "* phase angle, 3.5°\n", 33 | "\n", 34 | "In addition, use the Schleicher-Marcus (née, Halley-Marcus) phase function to correct the photometry to a phase angle of 0°." 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": 1, 40 | "metadata": {}, 41 | "outputs": [ 42 | { 43 | "name": "stdout", 44 | "output_type": "stream", 45 | "text": [ 46 | "Afρ based on nominal photometry: 77.5 cm\n" 47 | ] 48 | } 49 | ], 50 | "source": [ 51 | "import astropy.units as u\n", 52 | "from sbpy.activity import Afrho, phase_HalleyMarcus\n", 53 | "from sbpy.data import Ephem\n", 54 | "import sbpy.units as sbu\n", 55 | "\n", 56 | "m_comet = 18 * sbu.VEGAmag\n", 57 | "bandpass = \"Johnson V\"\n", 58 | "eph = Ephem.from_dict(dict(rh=2.5 * u.au, delta=3.5 * u.au, phase=3.5 * u.deg))\n", 59 | "rho = 5 * u.arcsec\n", 60 | "\n", 61 | "afrho = Afrho.from_fluxd(bandpass, m_comet, rho, eph, phasecor=True, Phi=phase_HalleyMarcus)\n", 62 | "\n", 63 | "print(f'Afρ based on nominal photometry: {afrho:.1f}')" 64 | ] 65 | }, 66 | { 67 | "attachments": {}, 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "To be sure we understand what went into this calculation behind the scenes, let's retrieve the apparent magnitude of the Sun from `sbpy`'s calibration system." 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 2, 77 | "metadata": {}, 78 | "outputs": [ 79 | { 80 | "name": "stdout", 81 | "output_type": "stream", 82 | "text": [ 83 | "Apparent magnitude of the Sun: -26.76 mag(VEGA)\n" 84 | ] 85 | } 86 | ], 87 | "source": [ 88 | "from sbpy.calib import Sun\n", 89 | "\n", 90 | "sun = Sun.from_default()\n", 91 | "_, _, m_sun = sun.observe_filter_name(bandpass, unit=sbu.VEGAmag)\n", 92 | "\n", 93 | "print(f\"Apparent magnitude of the Sun: {m_sun:.2f}\")" 94 | ] 95 | }, 96 | { 97 | "attachments": {}, 98 | "cell_type": "markdown", 99 | "metadata": {}, 100 | "source": [ 101 | "## Nucleus corrected photometry\n", 102 | "\n", 103 | "Let's assume on a previous observing run we measured the nucleus size when the comet was inactive. With the IAU HG model, we estimated an absolute magnitude *H*=14 mag (again, VEGA magnitude system), for a phase function parameter *G*=0.15.\n", 104 | "\n", 105 | "Remove the nucleus contribution from our photometry and re-compute *Afρ*." 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "execution_count": 3, 111 | "metadata": {}, 112 | "outputs": [ 113 | { 114 | "name": "stdout", 115 | "output_type": "stream", 116 | "text": [ 117 | "Total comet magnitude: 18.00 mag(VEGA)\n", 118 | "Apparent magnitude of nucleus: 19.05 mag(VEGA)\n", 119 | "Apparent magnitude of the coma: 18.52 mag(VEGA)\n", 120 | "\n", 121 | "Nucleus-corrected *Afρ*: 48.0 cm\n", 122 | "\n", 123 | "\n" 124 | ] 125 | } 126 | ], 127 | "source": [ 128 | "import numpy as np\n", 129 | "from sbpy.photometry import HG\n", 130 | "\n", 131 | "model = HG(H=14, G=0.15)\n", 132 | "m_nucleus = 5 * np.log10(eph['rh'].value * eph['delta'].value)[0] + model(eph['phase'][0])\n", 133 | "m_nucleus = m_nucleus * sbu.VEGAmag\n", 134 | "\n", 135 | "# using `.physical` to convert magnitudes into linear units\n", 136 | "coma = m_comet.physical - m_nucleus.physical\n", 137 | "\n", 138 | "# convert back to VEGA magnitudes\n", 139 | "m_coma = coma.to(sbu.VEGAmag)\n", 140 | "\n", 141 | "# recalculate Afrho\n", 142 | "afrho_coma = Afrho.from_fluxd(bandpass, m_coma, rho, eph, phasecor=True, Phi=phase_HalleyMarcus)\n", 143 | "\n", 144 | "print(f\"\"\"Total comet magnitude: {m_comet:.2f}\n", 145 | "Apparent magnitude of nucleus: {m_nucleus:.2f}\n", 146 | "Apparent magnitude of the coma: {m_coma:.2f}\n", 147 | "\n", 148 | "Nucleus-corrected *Afρ*: {afrho_coma:.1f}\n", 149 | "\n", 150 | "\"\"\")" 151 | ] 152 | } 153 | ], 154 | "metadata": { 155 | "kernelspec": { 156 | "display_name": ".venv", 157 | "language": "python", 158 | "name": "python3" 159 | }, 160 | "language_info": { 161 | "codemirror_mode": { 162 | "name": "ipython", 163 | "version": 3 164 | }, 165 | "file_extension": ".py", 166 | "mimetype": "text/x-python", 167 | "name": "python", 168 | "nbconvert_exporter": "python", 169 | "pygments_lexer": "ipython3", 170 | "version": "3.10.12" 171 | }, 172 | "orig_nbformat": 4 173 | }, 174 | "nbformat": 4, 175 | "nbformat_minor": 2 176 | } 177 | -------------------------------------------------------------------------------- /notebooks/data/Phys.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "sbpy.data.Phys Example Notebook\n", 8 | "=================================\n", 9 | "\n", 10 | "[sbpy.data.Phys](https://sbpy.readthedocs.io/en/latest/api/sbpy.data.Phys.html#sbpy.data.Phys) provides functionality to query and store small-body physical properties." 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": {}, 16 | "source": [ 17 | "Querying Physical Properties from JPL SBDB\n", 18 | "--------------------------------------------\n", 19 | "\n", 20 | "Query the physical properties for a few asteroids:" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 1, 26 | "metadata": { 27 | "collapsed": false 28 | }, 29 | "outputs": [ 30 | { 31 | "name": "stdout", 32 | "output_type": "stream", 33 | "text": [ 34 | "\n" 35 | ] 36 | } 37 | ], 38 | "source": [ 39 | "from sbpy.data import Phys\n", 40 | "\n", 41 | "phys = Phys.from_sbdb(['433', 'Itokawa', '12893'])\n", 42 | "print(phys.field_names)" 43 | ] 44 | }, 45 | { 46 | "cell_type": "markdown", 47 | "metadata": {}, 48 | "source": [ 49 | "We can calculate their volumes assuming spherical shapes:" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 2, 55 | "metadata": { 56 | "collapsed": false 57 | }, 58 | "outputs": [ 59 | { 60 | "data": { 61 | "text/plain": [ 62 | "[('433 Eros (1898 DQ)', ),\n", 63 | " ('25143 Itokawa (1998 SF36)', ),\n", 64 | " ('12893 Mommert (1998 QS55)', )]" 65 | ] 66 | }, 67 | "execution_count": 2, 68 | "metadata": {}, 69 | "output_type": "execute_result" 70 | } 71 | ], 72 | "source": [ 73 | "import numpy as np\n", 74 | "list(zip(phys['targetname'], 4/3*np.pi*phys['diameter']**3))" 75 | ] 76 | }, 77 | { 78 | "cell_type": "markdown", 79 | "metadata": {}, 80 | "source": [ 81 | "Please keep in mind that physical properties information provided by SBDB is incomplete and scarce. Missing values are replaced with `nan`." 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "Querying Molecular Data from `astroquery.jplspec`\n", 89 | "==========================\n", 90 | "\n", 91 | "`sbpy.data.Phys` also contains a function to query molecular data that\n", 92 | "might be useful for various calculations such as production rate calculations.\n", 93 | "`sbpy.data.Phys.from_jplspec` queries the [JPL Molecular Spectroscopy Catalog](https://spec.jpl.nasa.gov/home.html) molecular properties, and stores the\n", 94 | "data in a `sbpy.data.Phys` object, offering the same functionality as all the\n", 95 | "other `sbpy.data` functions, including the use of `~astropy.units`. `sbpy.data.Phys.from_jplspec` also\n", 96 | "calculates the partition function at the desired temperature using log-space interpolation. For\n", 97 | "a briefing of how this is done look at the sbpy jplspec notebook: [jplspec notebook](jplspec.ipynb). The results\n", 98 | "from `sbpy.data.Phys.from_jplspec` include the following data:\n", 99 | "\n", 100 | "- Transition frequency\n", 101 | "- Temperature\n", 102 | "- Integrated line intensity at 300 K\n", 103 | "- Partition function at 300 K\n", 104 | "- Partition function at designated temperature\n", 105 | "- Upper state degeneracy\n", 106 | "- Upper level energy in Joules\n", 107 | "- Lower level energy in Joules\n", 108 | "- Degrees of freedom\n", 109 | "\n", 110 | "For the names of these fields and their alternatives, see [here](https://sbpy.readthedocs.io/en/latest/sbpy/data/fieldnames.html#id1)" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": 5, 116 | "metadata": { 117 | "collapsed": true 118 | }, 119 | "outputs": [], 120 | "source": [ 121 | "import astropy.units as u" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 8, 127 | "metadata": { 128 | "collapsed": false 129 | }, 130 | "outputs": [], 131 | "source": [ 132 | "temp_estimate = 47. * u.K # kinetic temperature\n", 133 | "\n", 134 | "mol_tag = 28001 # JPLSpec unique identifier\n", 135 | "\n", 136 | "transition_freq = (345.7 * u.GHz).to('MHz') # Transition frequency\n", 137 | "\n", 138 | "mol_data = Phys.from_jplspec(temp_estimate, transition_freq, mol_tag) # build Phys object" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": {}, 144 | "source": [ 145 | "Once the phys object has been created, one can access all the information given by astroquery.jplspec as well as the partition function at the desired temperature:" 146 | ] 147 | }, 148 | { 149 | "cell_type": "code", 150 | "execution_count": 9, 151 | "metadata": { 152 | "collapsed": false 153 | }, 154 | "outputs": [ 155 | { 156 | "name": "stdout", 157 | "output_type": "stream", 158 | "text": [ 159 | "[2.29136526e-22] J\n", 160 | "degfreedom\n", 161 | "----------\n", 162 | " 2\n", 163 | " partfn \n", 164 | "-----------------\n", 165 | "17.05551276908476\n" 166 | ] 167 | } 168 | ], 169 | "source": [ 170 | "print(mol_data['elo_j']) # print energy of lower level\n", 171 | "print(mol_data['degfr']) # print degrees of freedom\n", 172 | "print(mol_data['partfn']) # print interpolated partition function at desired temp" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "Regular expressions can also be used as molecule identifiers since astroquery.jplspec provides the functionality. It is important to understand regular expressions and how to use them in a way that gets the user exactly what they want. If the user is unfamiliar with regular expressions, using the JPL Spectral catalog unique identifier is the best course of action.\n", 180 | "\n", 181 | "Hint: in regular expressions, putting something between '^' and '\\$' will match the literal text in between. This is useful to remember in order to avoid matching unnecessary terms. i.e. using 'co' will match 'co', 'co2', 'hco' so you would want to input '^co$' to avoid such nuances" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "execution_count": 10, 187 | "metadata": { 188 | "collapsed": false 189 | }, 190 | "outputs": [ 191 | { 192 | "name": "stdout", 193 | "output_type": "stream", 194 | "text": [ 195 | "[2.29136526e-22] J\n", 196 | "degfreedom\n", 197 | "----------\n", 198 | " 2\n", 199 | " partfn \n", 200 | "-----------------\n", 201 | "17.05551276908476\n" 202 | ] 203 | } 204 | ], 205 | "source": [ 206 | "mol_tag = '^CO$'\n", 207 | "\n", 208 | "mol_data = Phys.from_jplspec(temp_estimate, transition_freq, mol_tag) # build Phys object\n", 209 | "\n", 210 | "print(mol_data['elo_j']) # print energy of lower level\n", 211 | "print(mol_data['degfr']) # print degrees of freedom\n", 212 | "print(mol_data['partfn']) # print interpolated partition function at desired temp" 213 | ] 214 | } 215 | ], 216 | "metadata": { 217 | "kernelspec": { 218 | "display_name": "Python 3", 219 | "language": "python", 220 | "name": "python3" 221 | }, 222 | "language_info": { 223 | "codemirror_mode": { 224 | "name": "ipython", 225 | "version": 3 226 | }, 227 | "file_extension": ".py", 228 | "mimetype": "text/x-python", 229 | "name": "python", 230 | "nbconvert_exporter": "python", 231 | "pygments_lexer": "ipython3", 232 | "version": "3.6.8" 233 | } 234 | }, 235 | "nbformat": 4, 236 | "nbformat_minor": 2 237 | } 238 | -------------------------------------------------------------------------------- /notebooks/data/Orbit.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "sbpy.data.Orbit Example Notebooks\n", 8 | "=================================\n", 9 | "\n", 10 | "[sbpy.data.Orbit](https://sbpy.readthedocs.io/en/latest/api/sbpy.data.Orbit.html#sbpy.data.Orbit) provides functionality to query, propagate, transform, modify, and store orbital element information." 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "metadata": {}, 16 | "source": [ 17 | "Querying Orbital Elements from JPL Horizons\n", 18 | "--------------------------------------------\n", 19 | "\n", 20 | "Query the orbital elements of an asteroid and a comet using [sbpy.data.Orbit.from_horizons](https://sbpy.readthedocs.io/en/latest/api/sbpy.data.Orbit.html#sbpy.data.Orbit.from_horizons) using the current epoch:" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 1, 26 | "metadata": {}, 27 | "outputs": [ 28 | { 29 | "data": { 30 | "text/html": [ 31 | "QTable masked=True length=2\n", 32 | "\n", 33 | "\n", 34 | "\n", 35 | "\n", 36 | "\n", 37 | "\n", 38 | "
targetnameHGeqinclOmegawnMnuaQPM1M2k1k2phasecoeffepochTp
magAUdegdegdegdeg / ddegdegAUAUdmagmagmag / deg
str26float64float64float64float64float64float64float64float64float64float64float64float64float64float64float64float64float64float64objectobject
3552 Don Quixote (1983 SA)12.90.150.70887352653012671.24002963755259631.08098504413249349.9947390801012316.45890465043280.11211882184684151.25263321761739136.43142558751664.2594190173533577.2788083971541193210.8792624647340.00.0----0.02458703.2521700652458246.124344662
259P/Garradd0.0--0.33814925706899971.80797236075525415.8881765179664951.47706567945443257.52495339748290.2183013817060264160.1129373839696169.48844228756372.731691971438553.6554115821218471649.0962960774613.718.922.05.00.032458703.2521700652457969.803136748
" 39 | ], 40 | "text/plain": [ 41 | "\n", 42 | " targetname H ... epoch Tp \n", 43 | " mag ... \n", 44 | " str26 float64 ... object object \n", 45 | "-------------------------- ------- ... ----------------- -----------------\n", 46 | "3552 Don Quixote (1983 SA) 12.9 ... 2458703.252170065 2458246.124344662\n", 47 | " 259P/Garradd 0.0 ... 2458703.252170065 2457969.803136748" 48 | ] 49 | }, 50 | "execution_count": 1, 51 | "metadata": {}, 52 | "output_type": "execute_result" 53 | } 54 | ], 55 | "source": [ 56 | "from sbpy.data import Orbit\n", 57 | "\n", 58 | "orb = Orbit.from_horizons(['3552', '259P'])\n", 59 | "orb.table" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "Orbit Transformations using OpenOrb\n", 67 | "-----------------------------------\n", 68 | "\n", 69 | "`sbpy.data.Orbit.oo_transform` provides a way to transform orbital elements between different definitions: Keplerian (`'KEP'`), cometary (`'COM'`), and cartesian (`'CART'`) among others. This function requires [pyoorb](https://github.com/oorb/oorb/tree/master/python) to be installed.\n", 70 | "\n", 71 | "You can use the following code snippet to do orbit transformations locally on your computer:" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": 2, 77 | "metadata": {}, 78 | "outputs": [ 79 | { 80 | "name": "stdout", 81 | "output_type": "stream", 82 | "text": [ 83 | "Keplerian orbit:\n", 84 | " targetname H G ... P epoch Tp \n", 85 | " mag ... d \n", 86 | "---------- ---- ---- ... ----------------- ----------------- -----------------\n", 87 | " 1 Ceres 3.34 0.12 ... 1683.801515747967 2458703.252181881 2458239.648984397 \n", 88 | "\n", 89 | "\n", 90 | "Cometary orbit:\n", 91 | " id q e ... epoch_scale H G \n", 92 | " AU ... mag \n", 93 | "------- ------------------ ------------------- ... ----------- ---- ----\n", 94 | "1 Ceres 2.5585684839252023 0.07629052204979339 ... 3.0 3.34 0.12 \n", 95 | "\n", 96 | "\n", 97 | "Cartesian orbit:\n", 98 | " id x y ... epoch_scale H G \n", 99 | " AU AU ... mag \n", 100 | "------- -------------------- ------------------- ... ----------- ---- ----\n", 101 | "1 Ceres -0.40871763457121035 -2.7889382794721302 ... 3.0 3.34 0.12 \n", 102 | "\n", 103 | "\n" 104 | ] 105 | } 106 | ], 107 | "source": [ 108 | "from sbpy.data import Orbit\n", 109 | "\n", 110 | "orbit = Orbit.from_horizons('Ceres')\n", 111 | "\n", 112 | "com = Orbit.oo_transform(orbit, 'COM') # to cometary orbit\n", 113 | "cart = Orbit.oo_transform(orbit, 'CART') # to cartesian orbit\n", 114 | "\n", 115 | "print('Keplerian orbit:\\n', orbit.table, '\\n\\n')\n", 116 | "print('Cometary orbit:\\n', com.table, '\\n\\n')\n", 117 | "print('Cartesian orbit:\\n', cart.table, '\\n\\n')\n" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "metadata": {}, 123 | "source": [ 124 | "Propagating Orbits with OpenOrb\n", 125 | "------------------------------------\n", 126 | "\n", 127 | "You can use the following code snippet using `sbpy.data.Orbit.oo_propagate` to propagate the orbit of Ceres 100 years into the future. This example will also produce a bibliography." 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "execution_count": 3, 133 | "metadata": {}, 134 | "outputs": [ 135 | { 136 | "name": "stdout", 137 | "output_type": "stream", 138 | "text": [ 139 | "Current orbit:\n", 140 | " \n", 141 | " a incl \n", 142 | " AU deg \n", 143 | " float64 float64 \n", 144 | "----------------- ----------------\n", 145 | "2.769884411737029 10.5937657010036 \n", 146 | "\n", 147 | "\n", 148 | "Future orbit:\n", 149 | " \n", 150 | " a incl \n", 151 | " AU deg \n", 152 | " float64 float64 \n", 153 | "------------------ ------------------\n", 154 | "2.7666783768423975 10.586581269532852 \n", 155 | "\n", 156 | "\n" 157 | ] 158 | } 159 | ], 160 | "source": [ 161 | "from sbpy.data import Orbit\n", 162 | "from astropy.time import Time\n", 163 | "from sbpy import bib\n", 164 | "\n", 165 | "bib.track()\n", 166 | "\n", 167 | "orbit = Orbit.from_horizons('Ceres')\n", 168 | "\n", 169 | "new_orbit = orbit.oo_propagate(Time(2454531.2313, format='jd'))\n", 170 | "\n", 171 | "print('Current orbit:\\n', orbit['a', 'i'], '\\n\\n')\n", 172 | "print('Future orbit:\\n', new_orbit['a', 'i'], '\\n\\n')" 173 | ] 174 | }, 175 | { 176 | "cell_type": "code", 177 | "execution_count": 4, 178 | "metadata": {}, 179 | "outputs": [ 180 | { 181 | "name": "stdout", 182 | "output_type": "stream", 183 | "text": [ 184 | "sbpy:\n", 185 | " software: sbpy:\n", 186 | " https://doi.org/10.21105/joss.01426\n", 187 | "sbpy.data.orbit.Orbit.from_horizons:\n", 188 | " software: astroquery:\n", 189 | " Ginsburg, Sipőcz, Brasseur et al. 2019, The Astronomical Journal, Vol 157, 3, 98\n", 190 | " data source:\n", 191 | " Giorgini, Yeomans, Chamberlin et al. 1996, AAS/Division for Planetary Sciences Meeting Abstracts #28, 25.04\n", 192 | "sbpy.data.orbit.Orbit.oo_propagate:\n", 193 | " method:\n", 194 | " Granvik, Virtanen, Oszkiewicz & Muinonen 2009, Meteoritics and Planetary Science, Vol 44, 12, 1853\n", 195 | " software:\n", 196 | " https://github.com/oorb/oorb\n", 197 | "\n" 198 | ] 199 | } 200 | ], 201 | "source": [ 202 | "print(bib.to_text())" 203 | ] 204 | }, 205 | { 206 | "cell_type": "code", 207 | "execution_count": null, 208 | "metadata": {}, 209 | "outputs": [], 210 | "source": [] 211 | } 212 | ], 213 | "metadata": { 214 | "kernelspec": { 215 | "display_name": "Python 3", 216 | "language": "python", 217 | "name": "python3" 218 | }, 219 | "language_info": { 220 | "codemirror_mode": { 221 | "name": "ipython", 222 | "version": 3 223 | }, 224 | "file_extension": ".py", 225 | "mimetype": "text/x-python", 226 | "name": "python", 227 | "nbconvert_exporter": "python", 228 | "pygments_lexer": "ipython3", 229 | "version": "3.6.8" 230 | } 231 | }, 232 | "nbformat": 4, 233 | "nbformat_minor": 2 234 | } 235 | -------------------------------------------------------------------------------- /notebooks/data/Names.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "Using sbpy.data.Names\n", 8 | "===========" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "metadata": {}, 14 | "source": [ 15 | "[sbpy.data.Names](https://sbpy.readthedocs.io/en/latest/api/sbpy.data.Names.html#sbpy.data.Names) provides functionality to parse asteroid and comet names, numbers, and designations and to identify an object's nature (asteroid or comet) based on the provided identifier." 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "Parsing asteroid and comet names\n", 23 | "--------------------------------\n", 24 | "\n", 25 | "Imagine you get data from somebody else, involving a somewhat random list of targets like the following two:" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 1, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "asteroids = ['3200 Phaethon', '2018 AA', '(433)', '1036 Ganymed (1924 TD)', 'K14J00D']\n", 35 | "comets = ['2P/Encke', '259P', '73P/Schwassmann Wachmann 3 C', 'X/1106 C1', 'P/1994 N2 (McNaught-Hartley)']" 36 | ] 37 | }, 38 | { 39 | "cell_type": "markdown", 40 | "metadata": {}, 41 | "source": [ 42 | "Dealing with a target list like this might be complicated, since different formats are involved. For instance, the list cannot easily matched with another target list, as it is not straightforward to know whether target names, numbers, or designations are used. [sbpy.data.Names.parse_asteroid](https://sbpy.readthedocs.io/en/latest/api/sbpy.data.Names.html#sbpy.data.Names.parse_asteroid) and [sbpy.data.Names.parse_comet](https://sbpy.readthedocs.io/en/latest/api/sbpy.data.Names.html#sbpy.data.Names.parse_comet) can be used to classify and disentangle these identifiers:" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 2, 48 | "metadata": {}, 49 | "outputs": [ 50 | { 51 | "name": "stdout", 52 | "output_type": "stream", 53 | "text": [ 54 | "3200 Phaethon -> {'number': 3200, 'name': 'Phaethon'}\n", 55 | "2018 AA -> {'desig': '2018 AA'}\n", 56 | "(433) -> {'number': 433}\n", 57 | "1036 Ganymed (1924 TD) -> {'number': 1036, 'name': 'Ganymed', 'desig': '1924 TD'}\n", 58 | "K14J00D -> {'desig': '2014 JD'}\n", 59 | "2P/Encke -> {'type': 'P', 'number': 2, 'name': 'Encke'}\n", 60 | "259P -> {'type': 'P', 'number': 259}\n", 61 | "73P/Schwassmann Wachmann 3 C -> {'type': 'P', 'number': 73, 'name': 'Schwassmann Wachmann 3 C'}\n", 62 | "X/1106 C1 -> {'type': 'X', 'desig': '1106 C1'}\n", 63 | "P/1994 N2 (McNaught-Hartley) -> {'type': 'P', 'desig': '1994 N2', 'name': 'McNaught-Hartley'}\n" 64 | ] 65 | } 66 | ], 67 | "source": [ 68 | "from sbpy.data import Names\n", 69 | "\n", 70 | "for asteroid in asteroids:\n", 71 | " print(asteroid, '->', Names.parse_asteroid(asteroid))\n", 72 | " \n", 73 | "for comet in comets:\n", 74 | " print(comet, '->', Names.parse_comet(comet))\n", 75 | " " 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "Each function dissects the identifier string provided and tries to find patterns that match those of names, numbers, and designations using regular expressions. The output of each function is a dictionary with the found patterns. Note that packed designations and numbers are un-packed. \n", 83 | "\n", 84 | "If [sbpy.data.Names.parse_asteroid](https://sbpy.readthedocs.io/en/latest/api/sbpy.data.Names.html#sbpy.data.Names.parse_asteroid) is applied to a comet identifier (and vice versa), a `TargetNameParseError` is raised:" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": 3, 90 | "metadata": {}, 91 | "outputs": [ 92 | { 93 | "ename": "TargetNameParseError", 94 | "evalue": "2P/Encke does not appear to be an asteroid identifier", 95 | "output_type": "error", 96 | "traceback": [ 97 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 98 | "\u001b[0;31mTargetNameParseError\u001b[0m Traceback (most recent call last)", 99 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mNames\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparse_asteroid\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcomets\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 100 | "\u001b[0;32m~/lowell/software/sbpy/sbpy/data/names.py\u001b[0m in \u001b[0;36mparse_asteroid\u001b[0;34m(s)\u001b[0m\n\u001b[1;32m 460\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrej\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 461\u001b[0m raise TargetNameParseError('{} does not appear to be an '\n\u001b[0;32m--> 462\u001b[0;31m 'asteroid identifier'.format(s))\n\u001b[0m\u001b[1;32m 463\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 464\u001b[0m \u001b[0;31m# match target patterns\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 101 | "\u001b[0;31mTargetNameParseError\u001b[0m: 2P/Encke does not appear to be an asteroid identifier" 102 | ] 103 | } 104 | ], 105 | "source": [ 106 | "Names.parse_asteroid(comets[0])" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "metadata": {}, 112 | "source": [ 113 | "Distinguishing between asteroid and comet identifiers\n", 114 | "--------------------------------------------" 115 | ] 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "metadata": {}, 120 | "source": [ 121 | "[sbpy.data.Names.asteroid_or_comet](https://sbpy.readthedocs.io/en/latest/api/sbpy.data.Names.html#sbpy.data.Names.asteroid_or_comet) can be used to identify asteroid and comet identifiers:" 122 | ] 123 | }, 124 | { 125 | "cell_type": "code", 126 | "execution_count": 4, 127 | "metadata": {}, 128 | "outputs": [ 129 | { 130 | "name": "stdout", 131 | "output_type": "stream", 132 | "text": [ 133 | "3200 Phaethon -> asteroid\n", 134 | "2018 AA -> asteroid\n", 135 | "(433) -> asteroid\n", 136 | "1036 Ganymed (1924 TD) -> asteroid\n", 137 | "K14J00D -> asteroid\n", 138 | "2P/Encke -> comet\n", 139 | "259P -> comet\n", 140 | "73P/Schwassmann Wachmann 3 C -> comet\n", 141 | "X/1106 C1 -> comet\n", 142 | "P/1994 N2 (McNaught-Hartley) -> comet\n" 143 | ] 144 | } 145 | ], 146 | "source": [ 147 | "for obj in asteroids + comets:\n", 148 | " print(obj, '->', Names.asteroid_or_comet(obj))" 149 | ] 150 | }, 151 | { 152 | "cell_type": "markdown", 153 | "metadata": {}, 154 | "source": [ 155 | "If the object identifier is ambiguous or does not match a pattern associated with asteroid or comet identifiers, a `TargetNameParseError` is returned:" 156 | ] 157 | }, 158 | { 159 | "cell_type": "code", 160 | "execution_count": 5, 161 | "metadata": {}, 162 | "outputs": [ 163 | { 164 | "ename": "TargetNameParseError", 165 | "evalue": "Target nature unclear.", 166 | "output_type": "error", 167 | "traceback": [ 168 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 169 | "\u001b[0;31mTargetNameParseError\u001b[0m Traceback (most recent call last)", 170 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mNames\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0masteroid_or_comet\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'1I'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 171 | "\u001b[0;32m~/lowell/software/sbpy/sbpy/data/names.py\u001b[0m in \u001b[0;36masteroid_or_comet\u001b[0;34m(s)\u001b[0m\n\u001b[1;32m 560\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m'comet'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 561\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 562\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mTargetNameParseError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Target nature unclear.'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 172 | "\u001b[0;31mTargetNameParseError\u001b[0m: Target nature unclear." 173 | ] 174 | } 175 | ], 176 | "source": [ 177 | "Names.asteroid_or_comet('1I')" 178 | ] 179 | }, 180 | { 181 | "cell_type": "markdown", 182 | "metadata": {}, 183 | "source": [ 184 | "Limitations of the methods\n", 185 | "------------" 186 | ] 187 | }, 188 | { 189 | "cell_type": "markdown", 190 | "metadata": {}, 191 | "source": [ 192 | "Keep in mind that neither of the methods in [sbpy.data.Names](https://sbpy.readthedocs.io/en/latest/api/sbpy.data.Names.html) knows anything about the objects associated with the object identifier; there is no database query being performed. All information the methods have available comes from the provided identifier string. \n", 193 | "\n", 194 | "This lack of information can lead to some ambiguity. In order to minimize the level of ambiguity, the method requires comet names and designations to include the comet type (`P/`, `C/`, etc.)\n", 195 | "\n", 196 | "Consider the following examples:" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": 6, 202 | "metadata": {}, 203 | "outputs": [ 204 | { 205 | "name": "stdout", 206 | "output_type": "stream", 207 | "text": [ 208 | "asteroid\n" 209 | ] 210 | } 211 | ], 212 | "source": [ 213 | "obj = \"2018 ZZ1\"\n", 214 | "print(Names.asteroid_or_comet(obj))" 215 | ] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "metadata": {}, 220 | "source": [ 221 | "`2018 ZZ1` is considered an asteroid due to the lack of a comet type. If we add a comet type, the object will be identified as a comet:" 222 | ] 223 | }, 224 | { 225 | "cell_type": "code", 226 | "execution_count": 7, 227 | "metadata": {}, 228 | "outputs": [ 229 | { 230 | "name": "stdout", 231 | "output_type": "stream", 232 | "text": [ 233 | "comet\n" 234 | ] 235 | } 236 | ], 237 | "source": [ 238 | "obj = \"P/2018 ZZ1\"\n", 239 | "print(Names.asteroid_or_comet(obj))" 240 | ] 241 | }, 242 | { 243 | "cell_type": "markdown", 244 | "metadata": {}, 245 | "source": [ 246 | "# Example: Parsing a heterogeneous target list\n", 247 | "\n", 248 | "We return to the `asteroids` target list and try to extract a somewhat uniform list of identifiers for these targets: instead of the heterogeneous identifiers provided, we only want numbers (if available) or designations, if numbers are not provided. We can use the following script for this task:" 249 | ] 250 | }, 251 | { 252 | "cell_type": "code", 253 | "execution_count": 8, 254 | "metadata": {}, 255 | "outputs": [ 256 | { 257 | "data": { 258 | "text/plain": [ 259 | "[3200, '2018 AA', 433, 1036, '2014 JD']" 260 | ] 261 | }, 262 | "execution_count": 8, 263 | "metadata": {}, 264 | "output_type": "execute_result" 265 | } 266 | ], 267 | "source": [ 268 | "new_ids = []\n", 269 | "for ident in asteroids:\n", 270 | " parsed = Names.parse_asteroid(ident)\n", 271 | " if 'number' in parsed:\n", 272 | " new_ids.append(parsed['number'])\n", 273 | " elif 'desig' in parsed:\n", 274 | " new_ids.append(parsed['desig'])\n", 275 | "new_ids" 276 | ] 277 | } 278 | ], 279 | "metadata": { 280 | "kernelspec": { 281 | "display_name": "Python 3", 282 | "language": "python", 283 | "name": "python3" 284 | }, 285 | "language_info": { 286 | "codemirror_mode": { 287 | "name": "ipython", 288 | "version": 3 289 | }, 290 | "file_extension": ".py", 291 | "mimetype": "text/x-python", 292 | "name": "python", 293 | "nbconvert_exporter": "python", 294 | "pygments_lexer": "ipython3", 295 | "version": "3.6.8" 296 | } 297 | }, 298 | "nbformat": 4, 299 | "nbformat_minor": 2 300 | } 301 | -------------------------------------------------------------------------------- /workshops/LSST_SSSC_Sprint_2022/5-gas.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "92403859-6ff4-4ed7-8207-28bc7925bb3a", 6 | "metadata": {}, 7 | "source": [ 8 | "# Gas" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "c62622fc-8afc-4414-93a6-6ee68e4af358", 14 | "metadata": {}, 15 | "source": [ 16 | "## Haser model\n", 17 | "\n", 18 | "sbpy has the Haser model for gas comae, assuming a 1 dimensional outflow. It is capabable of modeling parent and daughter species (e.g., up to 1 generation of fragmentation):" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": 1, 24 | "id": "1f3a600a-d17a-475d-8d4e-8c34235f59fd", 25 | "metadata": {}, 26 | "outputs": [ 27 | { 28 | "name": "stdout", 29 | "output_type": "stream", 30 | "text": [ 31 | "1.3098195396338546e+32\n", 32 | "\n", 33 | "Sources\n", 34 | " sbpy:\n", 35 | " software: sbpy:\n", 36 | " 2019JOSS....4.1426M\n", 37 | "sbpy.activity.gas.core.photo_lengthscale:\n", 38 | " H2O photodissociation lengthscale:\n", 39 | " 1993Icar..105..235C\n", 40 | "sbpy.activity.gas.core.Haser.__init__:\n", 41 | " model:\n", 42 | " 1957BSRSL..43..740H\n", 43 | "sbpy.activity.gas.core.GasComa.total_number:\n", 44 | " model:\n", 45 | " 1978Icar...35..360N\n", 46 | "\n" 47 | ] 48 | } 49 | ], 50 | "source": [ 51 | "import astropy.units as u\n", 52 | "from sbpy.activity.gas import Haser, photo_lengthscale\n", 53 | "from sbpy import bib\n", 54 | "\n", 55 | "bib.track()\n", 56 | "\n", 57 | "Q = 1e28 / u.s\n", 58 | "v = 800 * u.m / u.s\n", 59 | "parent = photo_lengthscale('H2O')\n", 60 | "coma = Haser(Q, v, parent)\n", 61 | "\n", 62 | "# total number in 10,000 km radius aperture\n", 63 | "rho = 1e4 * u.km\n", 64 | "print(coma.total_number(rho))\n", 65 | "\n", 66 | "bib.stop()\n", 67 | "print(\"\\nSources\\n\", bib.show())" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "id": "504a86db-e6dc-4149-a24e-05326d45630a", 73 | "metadata": {}, 74 | "source": [ 75 | "Other aperture geometries are possible:" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 2, 81 | "id": "5b4951d5-cf9f-4a52-ab2c-a3ca6e28157d", 82 | "metadata": {}, 83 | "outputs": [ 84 | { 85 | "name": "stdout", 86 | "output_type": "stream", 87 | "text": [ 88 | "3.192618906156282e+31\n" 89 | ] 90 | } 91 | ], 92 | "source": [ 93 | "from sbpy.activity import RectangularAperture\n", 94 | "from sbpy.data import Ephem\n", 95 | "\n", 96 | "eph = Ephem.from_mpc('C/2017 K2')\n", 97 | "narrow_slit = RectangularAperture((1, 10) * u.arcsec)\n", 98 | "print(coma.total_number(narrow_slit, eph))" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "id": "f7017d39-d773-4cb7-8f49-0acdd53ae753", 104 | "metadata": {}, 105 | "source": [ 106 | "## Vectorial model\n", 107 | "\n", 108 | "> ⚠️ The version of the Vectorial model in sbpy v0.3 needs testing and is expected to be improved in v0.4." 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": 3, 114 | "id": "8de8c3d9-2dbe-4955-a9d1-e91785d7da2b", 115 | "metadata": {}, 116 | "outputs": [ 117 | { 118 | "name": "stderr", 119 | "output_type": "stream", 120 | "text": [ 121 | "/disks/data0/data/sbpy/tutorial/june2022/.venv/lib/python3.9/site-packages/sbpy/activity/gas/core.py:730: TestingNeeded: Literature tests with the Vectorial model are generally in agreement at the 20% level or better. The cause for the differences with the Festou FORTRAN code are not yet precisely known. Help testing this feature is appreciated.\n", 122 | " warnings.warn(\"Literature tests with the Vectorial model are generally\"\n" 123 | ] 124 | } 125 | ], 126 | "source": [ 127 | "from sbpy.activity.gas import VectorialModel, photo_timescale\n", 128 | "from sbpy.data import Phys\n", 129 | "\n", 130 | "parent = Phys.from_dict({'tau_T': photo_timescale('H2O') * 0.8, # approximate\n", 131 | " 'tau_d': photo_timescale('H2O'),\n", 132 | " 'v_outflow': 0.85 * u.km / u.s,\n", 133 | " 'sigma': 3e-16 * u.cm**2})\n", 134 | "daughter = Phys.from_dict({'tau_T': photo_timescale('OH') * 0.8, # approximate\n", 135 | " 'v_photo': 1.05 * u.km / u.s})\n", 136 | "coma = VectorialModel(Q, parent, daughter)" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "execution_count": 4, 142 | "id": "332140e0-1aff-459a-b1f4-462b4b8815bd", 143 | "metadata": {}, 144 | "outputs": [ 145 | { 146 | "data": { 147 | "image/png": "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\n", 148 | "text/plain": [ 149 | "
" 150 | ] 151 | }, 152 | "metadata": { 153 | "needs_background": "light" 154 | }, 155 | "output_type": "display_data" 156 | } 157 | ], 158 | "source": [ 159 | "import numpy as np\n", 160 | "import matplotlib.pyplot as plt\n", 161 | "\n", 162 | "rho = np.logspace(1, 4) * u.km\n", 163 | "sigma = coma.column_density(rho).to('cm^-2')\n", 164 | "\n", 165 | "ax = plt.gca()\n", 166 | "ax.plot(rho, sigma, label='Vectorial model, OH')\n", 167 | "plt.setp(ax, xlabel='Distance (km)', ylabel='Column density (cm$^{-2}$)', yscale='log', xscale='log')\n", 168 | "plt.legend()\n", 169 | "plt.tight_layout()" 170 | ] 171 | } 172 | ], 173 | "metadata": { 174 | "kernelspec": { 175 | "display_name": "Python 3 (ipykernel)", 176 | "language": "python", 177 | "name": "python3" 178 | }, 179 | "language_info": { 180 | "codemirror_mode": { 181 | "name": "ipython", 182 | "version": 3 183 | }, 184 | "file_extension": ".py", 185 | "mimetype": "text/x-python", 186 | "name": "python", 187 | "nbconvert_exporter": "python", 188 | "pygments_lexer": "ipython3", 189 | "version": "3.9.13" 190 | } 191 | }, 192 | "nbformat": 4, 193 | "nbformat_minor": 5 194 | } 195 | -------------------------------------------------------------------------------- /workshops/LSST_SSSC_Sprint_2022/4-dust.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "6eb6638d-9196-443c-b073-ed89b1e27288", 6 | "metadata": {}, 7 | "source": [ 8 | "# Dust" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "b36fc380-f9d5-400b-b615-8f669422c44d", 14 | "metadata": { 15 | "tags": [] 16 | }, 17 | "source": [ 18 | "Cometary dust comae are presently modeled with the Afρ quantity of A'Hearn et al. (1984), and the thermal emission corollary, εfρ, of Kelley et al. (2013). For photometry of a cometary coma within a circular aperture:\n", 19 | "\n", 20 | "* *A* is the albedo of the dust,\n", 21 | "* *f* is the filling factor of the dust in the aperture,\n", 22 | "* *ρ* is the aperture radius in units of length (at the distance of the comet).\n", 23 | "\n", 24 | "The `Afrho` and `Efrho` classes are derived from astropy's `Quantity`, and have units of length:" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": 1, 30 | "id": "de15095b-19e2-42d9-8fc3-0a72e239cd1f", 31 | "metadata": { 32 | "tags": [] 33 | }, 34 | "outputs": [ 35 | { 36 | "name": "stdout", 37 | "output_type": "stream", 38 | "text": [ 39 | "1000.0 cm\n" 40 | ] 41 | } 42 | ], 43 | "source": [ 44 | "import astropy.units as u\n", 45 | "from sbpy.activity import Afrho, Efrho\n", 46 | "\n", 47 | "afrho = Afrho(1000 * u.cm)\n", 48 | "print(afrho)" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 2, 54 | "id": "5c619387-9cab-43be-ae46-7c9b60ce0a0e", 55 | "metadata": {}, 56 | "outputs": [ 57 | { 58 | "name": "stdout", 59 | "output_type": "stream", 60 | "text": [ 61 | "3500.0 cm\n" 62 | ] 63 | } 64 | ], 65 | "source": [ 66 | "efrho = Efrho(3.5 * afrho)\n", 67 | "print(efrho)" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "id": "851913bf-24f5-4a11-a876-01696945fee5", 73 | "metadata": {}, 74 | "source": [ 75 | "With bandpass or wavelength, aperture radius, helocentric distance, and observer-target distance, we can convert `Afrho` and `Efrho` objects into spectral flux density:" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": 3, 81 | "id": "b7a88d64-6674-4aed-af04-67b4bdf33894", 82 | "metadata": {}, 83 | "outputs": [ 84 | { 85 | "name": "stdout", 86 | "output_type": "stream", 87 | "text": [ 88 | "14.737360509904782 mag(AB)\n" 89 | ] 90 | } 91 | ], 92 | "source": [ 93 | "from sbpy.data import Ephem\n", 94 | "\n", 95 | "eph = Ephem.from_mpc('C/2017 K2')\n", 96 | "aper = 5 * u.arcsec\n", 97 | "m = afrho.to_fluxd('LSST r', aper, eph, unit=u.ABmag)\n", 98 | "print(m)" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": 4, 104 | "id": "965b37ce-1c08-4629-908b-85f9d8e7e526", 105 | "metadata": {}, 106 | "outputs": [ 107 | { 108 | "name": "stdout", 109 | "output_type": "stream", 110 | "text": [ 111 | "14.737360509904782 mag(AB) --> 1000.0 cm\n" 112 | ] 113 | } 114 | ], 115 | "source": [ 116 | "roundtrip = Afrho.from_fluxd('LSST r', m, aper, eph)\n", 117 | "print(f'{m} --> {roundtrip}')" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "id": "03e20162-a943-44f2-acd9-b80273961cba", 123 | "metadata": {}, 124 | "source": [ 125 | "Here, the conversion was done with the bandpass specified by name, using the current solar flux density lookup table in `sbpy.calib.solar_fluxd` (see notebook #2 from this tutorial)." 126 | ] 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "id": "aa883303-5787-401b-8b5b-b092e2296c81", 131 | "metadata": {}, 132 | "source": [ 133 | "---\n", 134 | "\n", 135 | "Plot the spectrum of the comet, from 0.3 to 30 μm:" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": 5, 141 | "id": "cd45c071-ddb4-4c6e-8571-360623a229db", 142 | "metadata": {}, 143 | "outputs": [ 144 | { 145 | "name": "stderr", 146 | "output_type": "stream", 147 | "text": [ 148 | "WARNING: Source spectrum is tapered. [synphot.observation]\n", 149 | "WARNING: Source spectrum is tapered. [synphot.observation]\n" 150 | ] 151 | }, 152 | { 153 | "data": { 154 | "image/png": "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\n", 155 | "text/plain": [ 156 | "
" 157 | ] 158 | }, 159 | "metadata": { 160 | "needs_background": "light" 161 | }, 162 | "output_type": "display_data" 163 | } 164 | ], 165 | "source": [ 166 | "import numpy as np\n", 167 | "import matplotlib.pyplot as plt\n", 168 | "\n", 169 | "wave = np.logspace(-0.5, 1.5) * u.um\n", 170 | "fsca = afrho.to_fluxd(wave, aper, eph)\n", 171 | "ftherm = efrho.to_fluxd(wave, aper, eph)\n", 172 | "\n", 173 | "ax = plt.gca()\n", 174 | "ax.plot(wave, fsca, label='scattered')\n", 175 | "ax.plot(wave, ftherm, label='thermal')\n", 176 | "ax.plot(wave, fsca + ftherm, label='total')\n", 177 | "plt.setp(ax, xscale='log', yscale='log', ylim=(1e-18, 1e-13), xlabel='Wavelength (μm)', ylabel=f'$F_\\lambda$ ({fsca.unit})')\n", 178 | "plt.tight_layout()" 179 | ] 180 | } 181 | ], 182 | "metadata": { 183 | "kernelspec": { 184 | "display_name": "Python 3 (ipykernel)", 185 | "language": "python", 186 | "name": "python3" 187 | }, 188 | "language_info": { 189 | "codemirror_mode": { 190 | "name": "ipython", 191 | "version": 3 192 | }, 193 | "file_extension": ".py", 194 | "mimetype": "text/x-python", 195 | "name": "python", 196 | "nbconvert_exporter": "python", 197 | "pygments_lexer": "ipython3", 198 | "version": "3.8.11" 199 | } 200 | }, 201 | "nbformat": 4, 202 | "nbformat_minor": 5 203 | } 204 | -------------------------------------------------------------------------------- /notebooks/activity/NonLTE_prodrate.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 4, 6 | "metadata": { 7 | "collapsed": true 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "import numpy as np\n", 12 | "import astropy.units as u\n", 13 | "from astropy.time import Time\n", 14 | "from astropy.table import Table\n", 15 | "from sbpy.data import Ephem, Phys\n", 16 | "from sbpy.activity import (Haser, LTE, NonLTE, photo_timescale, einstein_coeff, \n", 17 | "intensity_conversion, beta_factor, total_number, from_Haser)\n", 18 | "import matplotlib.pyplot as plt\n", 19 | "import matplotlib\n", 20 | "import astropy.constants as con" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "Calculating Column Density using the NonLTE iterative code `from_pyradex`\n", 28 | "=======================================\n", 29 | "_____________________________________________________________________________________________\n", 30 | "\n", 31 | "`sbpy.activity` offers an implementation of `pyradex` which is a python wrapper for the NonLTE, iterative fortran code called RADEX. Radex is described in [van der Tak et al. 2013](https://ui.adsabs.harvard.edu/abs/2007A%26A...468..627V/abstract).\n", 32 | "\n", 33 | "This model takes in an initial guess for the column density and compares the data iteratively against RADEX results, finding the best fit column density for the data. More information about the installation and setup of `pyradex` can be found here [here](https://github.com/keflavich/pyradex), as well as more information about the parameters needed for the [RADEX](https://personal.sron.nl/~vdtak/radex/index.shtml) code. `from_pyradex` returns the best fitting column density based on the data provided which can then be used with the Haser model shown in the previous example. \n", 34 | "\n", 35 | "RADEX requires information on collider densities in order to determine collision rates. The collider densities are required to be given in the form of a dictionary. For comets, we expect H2O to be our main collisional partner but RADEX does not contain information on collisional rates for H2O. Therefore, the default value for collider densities in sbpy is a scaled version of the H2 collisional rate to account for H2O. This scaling is prominent in a lot of literature, such as [Walker et al. 2014](https://ui.adsabs.harvard.edu/abs/2014ApJ...790...96W/abstract), [de Val Borro et al. 2017](https://ui.adsabs.harvard.edu/abs/2018MNRAS.474.1099D/abstract), and [Schoier et al. 2004](https://ui.adsabs.harvard.edu/abs/2005A%26A...432..369S/abstract).\n", 36 | "\n", 37 | "In the case of this module we have chosen to follow the Walker et al. scaling for deriving H2O-H2O collision rates from H2-H2O coefficients. Within this scaling, we apply the square root of the ratio of reduced masses:\n", 38 | "\n", 39 | "$$s = (\\frac{m_{H2O}}{m_{H2}})^{0.5}$$ \n", 40 | "\n", 41 | "Where `s` is the scale to multiply the collisional density of H2 against in order to obtain H2O-H2O collision rates.\n", 42 | "\n", 43 | "For the implementation of this code, the user can either define their chosen first guess for column density, or they can calculate it from their data or JPLSpec data `cdensity_Bockelee`. The literature used for this example is the same as in [this notebook](LTE_prodrate_Haser), [Wierzchos et al. 2018](https://ui.adsabs.harvard.edu/abs/2018AJ....156...34W/abstract):\n", 44 | "\n", 45 | "**Important notes:** `pyradex` requires a fortran compiler to be installed in your system. The recommendation is gfortran, which can be installed using [Homebrew](https://brewformulas.org/Gfortran), or any other similar service. \n", 46 | "\n", 47 | "Warnings of a missing file and RunTime error are normal from pyradex, if the user wants to find out more about them, see the [`pyradex` docs](https://github.com/keflavich/pyradex). The file error comes from the fact that `sbpy` uses, like pyradex, `astroquery.Lamda` for the molecular data files instead of searching them locally (despite the Fortran code still forcing the search for a local molecular data file). In the future, a function will be added to `sbpy` in which a user may build their own molecular data files from JPLSpec information. For now, LAMDA catalog is the primary source of the molecular data file for the implementation of RADEX.\n" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 5, 53 | "metadata": { 54 | "collapsed": false 55 | }, 56 | "outputs": [ 57 | { 58 | "name": "stdout", 59 | "output_type": "stream", 60 | "text": [ 61 | "Table:\n", 62 | " U_T Time T_B Q log(Q) Q_error \n", 63 | "------------- ------------------- ---- ------- ----------- --------------------\n", 64 | "2017-12-22.21 2017-12-22 05:02:24 0.26 4.4e+28 28.64345268 0.019305151681574984\n", 65 | "2017-12-23.09 2017-12-23 02:09:36 0.28 4.6e+28 28.66275783 0.03621217433601842\n", 66 | "2017-12-30.14 2017-12-30 03:21:36 0.26 4.6e+28 28.66275783 0.03621217433601842\n", 67 | "2017-12-31.13 2017-12-31 03:07:12 0.27 4.6e+28 28.66275783 0.03621217433601842\n", 68 | "2018-01-16.03 2018-01-16 00:43:12 0.27 4.6e+28 28.66275783 0.03621217433601842\n", 69 | "Column Names:\n", 70 | "\n" 71 | ] 72 | } 73 | ], 74 | "source": [ 75 | "co = Table.read(('data/CO.csv'), format=\"ascii.csv\")\n", 76 | "error = np.array([0.2, 0.4, 0.4, 0.4, 0.4]) * 10.**28 # +/- error from literature\n", 77 | "Q_error = np.array(co['Q']) + np.array(error) # upper error limit\n", 78 | "Q_error = np.log10(np.array(Q_error)) - np.array(co['log(Q)'])\n", 79 | "co['Q_error'] = Q_error\n", 80 | "print(\"Table:\\n{}\\nColumn Names:\\n{}\".format(co, co.columns))" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "Model parameters needed, all values are taken directly from the literature.\n", 88 | "In this example the molecule identifier will be inputted as a regular expression. \n", 89 | "Regular expressions for mol_tag can be used but the user must be careful not to provide\n", 90 | "an ambiguous regular expression. One good thing to remember is that anything between symbols '^' and '\\\\$'\n", 91 | "will be matched exactly, therefore you can avoid an ambiguity error by writing your molecule name as such:\n", 92 | "'^name\\\\$'. A perfect example of this is with the molecule in this example 'CO', simply writing mol_tag = 'CO'\n", 93 | "will produce an ambiguity error because it will match CO, CO2, etc. therefore, it is necessary to \n", 94 | "restrict our molecule name regex to '^CO\\\\$' as presented below." 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 6, 100 | "metadata": { 101 | "collapsed": true 102 | }, 103 | "outputs": [], 104 | "source": [ 105 | "transition_freq = (230.538 * u.GHz).to('MHz')\n", 106 | "\n", 107 | "aper = 10 * u.m # aperture\n", 108 | "\n", 109 | "mol_tag = '^CO$' # regex molecule identifier\n", 110 | "\n", 111 | "temp_estimate = 25. * u.K \n", 112 | "\n", 113 | "vgas = 0.5 * u.km / u.s\n", 114 | "\n", 115 | "target = 'C/2016 R2'\n", 116 | "\n", 117 | "b = 0.74 # intrinsic antenna value" 118 | ] 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "metadata": {}, 123 | "source": [ 124 | "Obtaining molecular data from the JPL Molecular Spectroscopy Catalog using `sbpy.data.phys`. \n", 125 | "See documentation for a detailed breakdown of the resulting object and the values stored in the object." 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": 7, 131 | "metadata": { 132 | "collapsed": true 133 | }, 134 | "outputs": [], 135 | "source": [ 136 | "mol_data = Phys.from_jplspec(temp_estimate, transition_freq, mol_tag) # molecular data from JPLSpec\n", 137 | "\n", 138 | "intl = intensity_conversion(mol_data) # calculate line intensity\n", 139 | "\n", 140 | "mol_data.apply([intl.value] * intl.unit,\n", 141 | " name='Integrated line intensity at desired temp') # store value" 142 | ] 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "metadata": {}, 147 | "source": [ 148 | "Obtaining the Einstein Coefficient. In this example, we will obtain our Einstein Coefficient from\n", 149 | "LAMDA catalog and append it to our molecular data Phys object. In [this notebook](LTE_prodrate_without_photolysis.ipynb) we have been calculating it through sbpy/JPLSpec. It is possible that your transition frequency values may not exactly match the LAMDA catalog to the 4th significant figure, especially if you're using JPLSpec. Therefore, we recommend when using this method\n", 150 | "that you match your transition frequency with the LAMDA value over the JPLSpec value, since `from_jplspec` is\n", 151 | "designed to pick the closest transition frequency within a range of 1 GHz, whereas LAMDA will expect the\n", 152 | "exact value found in their catalog." 153 | ] 154 | }, 155 | { 156 | "cell_type": "code", 157 | "execution_count": 8, 158 | "metadata": { 159 | "collapsed": false 160 | }, 161 | "outputs": [ 162 | { 163 | "name": "stderr", 164 | "output_type": "stream", 165 | "text": [ 166 | "/Users/gianni0603/anaconda/lib/python3.6/site-packages/astroquery/lamda/core.py:145: UserWarning: The first time a LAMDA function is called, it must assemble a list of valid molecules and URLs. This list will be cached so future operations will be faster.\n", 167 | " warnings.warn(\"The first time a LAMDA function is called, it must \"\n" 168 | ] 169 | } 170 | ], 171 | "source": [ 172 | "from astroquery.lamda import Lamda\n", 173 | "\n", 174 | "mol_name = 'CO' # LAMDA molecule name\n", 175 | "\n", 176 | "lam_search = Lamda.query(mol=mol_name.lower()) # LAMDA Query\n", 177 | "\n", 178 | "lam_result = lam_search[1] # outputs CO table\n", 179 | "\n", 180 | "lam_found = lam_result[lam_result['Frequency'] == transition_freq.to('GHz').value] # parse results at frequency\n", 181 | "\n", 182 | "au_cat = lam_found['EinsteinA'] # get Einstein Coefficient\n", 183 | "\n", 184 | "au_cat = au_cat.data[0] # get value of coefficient\n", 185 | "\n", 186 | "au = au_cat / u.s # define the unit\n", 187 | "\n", 188 | "mol_data.apply([au.value] * au.unit, name='eincoeff') # store einstein coefficient" 189 | ] 190 | }, 191 | { 192 | "cell_type": "markdown", 193 | "metadata": {}, 194 | "source": [ 195 | "Initialize the `sbpy.activity.Haser` model in order to perform our production rate calculations. \n", 196 | "`Q_estimate` first guess for the production rate was obtained running `from_Drahus` for the same data set before doing this example" 197 | ] 198 | }, 199 | { 200 | "cell_type": "code", 201 | "execution_count": 9, 202 | "metadata": { 203 | "collapsed": true 204 | }, 205 | "outputs": [], 206 | "source": [ 207 | "Q_estimate = 3.594*10**(28) / u.s \n", 208 | "\n", 209 | "parent = photo_timescale('CO') * vgas # parent photodissociation rate\n", 210 | "\n", 211 | "coma = Haser(Q_estimate, vgas, parent) # initializing the model with an estimate " 212 | ] 213 | }, 214 | { 215 | "cell_type": "markdown", 216 | "metadata": {}, 217 | "source": [ 218 | "Run the `from_pyradex` iterative code on the data to find best fit column densities, and then calculate total number based on telescope geometry. Use Haser model for the calculation of production rates." 219 | ] 220 | }, 221 | { 222 | "cell_type": "markdown", 223 | "metadata": {}, 224 | "source": [ 225 | "You can give a column density first guess either using `sbpy.data.LTE` `cdensity_Bockelee` function, or user-defined into the data class. In this example, we'll use `cdensity_Bockelee`" 226 | ] 227 | }, 228 | { 229 | "cell_type": "markdown", 230 | "metadata": {}, 231 | "source": [ 232 | "Since our data file contains 6 different data points of observation times and integrated flux, we can\n", 233 | "calculate production rates for all of these 6 data points using a python for loop.\n", 234 | "\n", 235 | "**IMPORTANT: Because we are using a for loop, and some of the values that should be appended to the `mol_data`\n", 236 | "phys object are calculated within the loop itself, we must initialize our columns within the phys object\n", 237 | "BEFORE performing the loop. This is because you cannot iteratively redefine the same column of data within a \n", 238 | "phys object, but you CAN change the value of an already defined column as many times as you want.\n", 239 | "Since our `beta`, `cdensity` and `total_number` values vary with every iteration,\n", 240 | "and since our production rate needs these values within the loop, we must simply change the value of our\n", 241 | "already defined columns for beta, column density, and total number everytime we iterate. Keep in mind when you initialize the column you must initialize it with the correct units and correct type (float, int, str). If you get an error saying there are duplicate columns, it is most likely due to what has been mentioned in this note, and you will have to reinitialize your mol_data object before trying to enter more data in**" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": 10, 247 | "metadata": { 248 | "collapsed": false 249 | }, 250 | "outputs": [ 251 | { 252 | "name": "stderr", 253 | "output_type": "stream", 254 | "text": [ 255 | "WARNING: Did not find data file for species co in path /var/folders/77/ly9f_8q55j51s_38_1xd_kh00000gn/T/tmpmaez93gq. Downloading it. [pyradex.base_class]\n", 256 | "/Users/gianni0603/anaconda/lib/python3.6/site-packages/pyradex/core.py:529: UserWarning: Using a default ortho-to-para ratio (which will only affect species for which independent ortho & para collision rates are given)\n", 257 | " warnings.warn(\"Using a default ortho-to-para ratio (which \"\n", 258 | "/Users/gianni0603/anaconda/lib/python3.6/site-packages/pyradex/core.py:910: RuntimeWarning: invalid value encountered in true_divide\n", 259 | " frac_level_diff = level_diff/self.level_population\n", 260 | "/Users/gianni0603/anaconda/lib/python3.6/site-packages/pyradex/core.py:998: RuntimeWarning: overflow encountered in exp\n", 261 | " bnutex = thc*xt/(np.exp(earg)-1.0)\n" 262 | ] 263 | }, 264 | { 265 | "name": "stdout", 266 | "output_type": "stream", 267 | "text": [ 268 | "Closest Integrated Flux:[0.25920121] K km / s\n", 269 | "Given Integrated Flux: 0.26 K km / s\n", 270 | "[2.17657296e+14] 1 / cm2\n" 271 | ] 272 | }, 273 | { 274 | "name": "stderr", 275 | "output_type": "stream", 276 | "text": [ 277 | "WARNING: Did not find data file for species co in path /var/folders/77/ly9f_8q55j51s_38_1xd_kh00000gn/T/tmpb7vmf8ig. Downloading it. [pyradex.base_class]\n" 278 | ] 279 | }, 280 | { 281 | "name": "stdout", 282 | "output_type": "stream", 283 | "text": [ 284 | "Closest Integrated Flux:[0.27889648] K km / s\n", 285 | "Given Integrated Flux: 0.28 K km / s\n", 286 | "[2.34400165e+14] 1 / cm2\n" 287 | ] 288 | }, 289 | { 290 | "name": "stderr", 291 | "output_type": "stream", 292 | "text": [ 293 | "WARNING: Did not find data file for species co in path /var/folders/77/ly9f_8q55j51s_38_1xd_kh00000gn/T/tmphwhwndc4. Downloading it. [pyradex.base_class]\n" 294 | ] 295 | }, 296 | { 297 | "name": "stdout", 298 | "output_type": "stream", 299 | "text": [ 300 | "Closest Integrated Flux:[0.25920121] K km / s\n", 301 | "Given Integrated Flux: 0.26 K km / s\n", 302 | "[2.17657296e+14] 1 / cm2\n" 303 | ] 304 | }, 305 | { 306 | "name": "stderr", 307 | "output_type": "stream", 308 | "text": [ 309 | "WARNING: Did not find data file for species co in path /var/folders/77/ly9f_8q55j51s_38_1xd_kh00000gn/T/tmpsn2mlwlt. Downloading it. [pyradex.base_class]\n" 310 | ] 311 | }, 312 | { 313 | "name": "stdout", 314 | "output_type": "stream", 315 | "text": [ 316 | "Closest Integrated Flux:[0.26905909] K km / s\n", 317 | "Given Integrated Flux: 0.27 K km / s\n", 318 | "[2.26028731e+14] 1 / cm2\n" 319 | ] 320 | }, 321 | { 322 | "name": "stderr", 323 | "output_type": "stream", 324 | "text": [ 325 | "WARNING: Did not find data file for species co in path /var/folders/77/ly9f_8q55j51s_38_1xd_kh00000gn/T/tmp4l8ywq9x. Downloading it. [pyradex.base_class]\n" 326 | ] 327 | }, 328 | { 329 | "name": "stdout", 330 | "output_type": "stream", 331 | "text": [ 332 | "Closest Integrated Flux:[0.26905909] K km / s\n", 333 | "Given Integrated Flux: 0.27 K km / s\n", 334 | "[2.26028731e+14] 1 / cm2\n" 335 | ] 336 | } 337 | ], 338 | "source": [ 339 | "nonlte = NonLTE()\n", 340 | "q_found_pyradex = []\n", 341 | "lte = LTE()\n", 342 | "\n", 343 | "for i in range(0, 5):\n", 344 | "\n", 345 | " time = Time(co['Time'][i], format='iso')\n", 346 | " integrated_flux = co['T_B'][i] * u.K * u.km / u.s\n", 347 | " ephemobj = Ephem.from_horizons(target, epochs=time.jd)\n", 348 | " beta = beta_factor(mol_data, ephemobj)\n", 349 | " mol_data['beta'] = beta\n", 350 | " cdensity_bockelee = lte.cdensity_Bockelee(integrated_flux, mol_data) # col density first guess\n", 351 | " mol_data['cdensity'] = cdensity_bockelee\n", 352 | " cdensity = nonlte.from_pyradex(integrated_flux, mol_data)\n", 353 | " mol_data['cdensity'] = cdensity\n", 354 | " tnum = total_number(mol_data, aper, b) # total number of molecules in aperture\n", 355 | " mol_data['total_number'] = tnum\n", 356 | "\n", 357 | " Q = from_Haser(coma, mol_data, aper=aper) # production rate from Haser model\n", 358 | "\n", 359 | " q_found_pyradex.append(np.log10(Q.value)[0])\n", 360 | "\n", 361 | "q_pred_co = list(co['log(Q)'])" 362 | ] 363 | }, 364 | { 365 | "cell_type": "code", 366 | "execution_count": 11, 367 | "metadata": { 368 | "collapsed": false 369 | }, 370 | "outputs": [ 371 | { 372 | "name": "stdout", 373 | "output_type": "stream", 374 | "text": [ 375 | "The Resulting Production Rates for CO in C/2016 R2 using Haser model are:\n", 376 | " [28.727 28.758 28.716 28.731 28.709]\n", 377 | "Residuals:\n", 378 | "[-0.084 -0.096 -0.053 -0.068 -0.047]\n", 379 | "Literature errors:\n", 380 | "[0.019 0.036 0.036 0.036 0.036]\n" 381 | ] 382 | } 383 | ], 384 | "source": [ 385 | "print(\"The Resulting Production Rates for CO in {} using Haser model are:\\n {}\".format(target, np.round(q_found_pyradex,3)))\n", 386 | "print(\"Residuals:\\n{}\".format(np.round((np.array(q_pred_co)) - (np.array(q_found_pyradex)),3)))\n", 387 | "print(\"Literature errors:\\n{}\".format(np.round(co['Q_error'],3)))" 388 | ] 389 | }, 390 | { 391 | "cell_type": "code", 392 | "execution_count": 13, 393 | "metadata": { 394 | "collapsed": false 395 | }, 396 | "outputs": [ 397 | { 398 | "data": { 399 | "image/png": "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\nl/n973/PnDlzqF+/Plu3bmXLli289NJLTJ06leuuu45vfetbALz00ktcc801XHrppZx44o7fzR95\n5JGypLF69Wr22msvANauzTyPXd++fTnzzDNxd0aPHp1xnXzJW5Na2sRL89x9ZNqiZYRh7wG6Awsq\n2MxZbN+cBvA0YTpZzOxAwjD1VZ3ZMPdWZRmZP1u5SB3UvLhop8rTdejQgUWLFrFhwwbatWvHihUr\nWL16NU2bbpsMdPPmzQwePJjhw4dzxx13ANCsWTMAli5dyh//+EduuummjNtPrde4cWM2bdqEuxMO\nT2BmHHfccQwbNoynn36ahx56qKze5MmT6dq1K7fddhuDBw9m+vTpZckG4KijjuLNN9+kXr16dO7c\nmX/961/stttuZdtObT/V+JJ6Pq1ahR/uN2zYkE2bNnHPPfdw++23c/LJJ7N+/XrcnXr1tj8077//\n/sydO3eH5/bII4+wePFiLrroorLnunr1atasWcOee2aeqfumm27itdde4/XXX+fmm2/OuE6+5PMa\nTjfgp0B3M5sZ/3oS5hK/w8zeAX5PmDQJM2sdhzcn3t8dOAl4stx2HwD2N7PZhMms+uVhoqmqa9Fk\n58pF6qBefVpT1NC2KytqaPTq07pK9Vu1akXLltua3jp27Ljd8quuuopBgwZx+eWX84c//GG7ZYMG\nDaJp06YMHz6cefPm0atXL37xi19wxRVXUFpausNjDRw4kGuvvZaBAwdy1llnMXHixLKmuG9+85tl\n65100km89tpr3HPPPbRu3ZoVK1awfPnysuWNGjVi9erVHHroodSvX5+PP/6Yo48+GoBzzz2XgQMH\ncvXVVzNw4MAKn3unTp248cYbmTBhAgCXXHIJv/vd77jqqqt48803ATj//PPZbbfduPvubVMxzZgx\ngyuuuIIPPviAyy67DIDBgwczaNAgLr30UgYNGgTA1VdfzYwZM7jooovYtGkTZ5xxBhdccAEXXHAB\np5xySoWx5drXYrTokpISz9vQNuWv4QA0rA9nH6ImNalT5s2bx3e+852sy9VLbddX/jU2s2nuXpKr\n7X8txlLLq1RSGT8/NKO1aAK9OirZyNdOl24tlWCkQko4udCljRKMiEglNJaaiIgkQmc4IpIbU5aq\naVkqpIQjIjWXwx9A9+7dm8cff7xG4WzdunWHrsWVefDBBykuLmblypUUFxfzwx/+sEYxyI6UcESk\n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\nQVPAHlmcMAAAAABJRU5ErkJggg==\n", 400 | "text/plain": [ 401 | "" 402 | ] 403 | }, 404 | "metadata": {}, 405 | "output_type": "display_data" 406 | } 407 | ], 408 | "source": [ 409 | "time_co = list(co['Time'])\n", 410 | "time_co = matplotlib.dates.datestr2num(time_co)\n", 411 | "\n", 412 | "plt.plot_date(time_co, q_pred_co, 'o', color='slateblue', label='Wierzchos & Womack 2018')\n", 413 | "plt.plot_date(time_co, q_found_pyradex, 'o', color='hotpink', label='sbpy results')\n", 414 | "plt.xlabel('Time')\n", 415 | "plt.ylabel('Log (Q)')\n", 416 | "plt.legend(loc='best', fontsize='x-small')\n", 417 | "plt.title('Q vs Time Plot for CO in {}'.format(target))\n", 418 | "plt.show()" 419 | ] 420 | }, 421 | { 422 | "cell_type": "markdown", 423 | "metadata": {}, 424 | "source": [ 425 | "It is clear that the implementation of pyradex gives better results than the example in [this notebook](LTE_prodrate_Haser.ipynb) in comparison to the literature, and it is done entirely within `sbpy` functionalities, offering the user a rigorous way to calculate column densities, and from those, production rates using the Haser model within `sbpy`. \n", 426 | "\n", 427 | "Even so, `sbpy` allows for flexibility in terms of data entry. Hardly traceable inconsistencies like are common in cometary studies, since a lot depends on the molecular catalogs that the data is obtained from, or what calculations are used. This is exactly why sbpy offers flexibility in all its functions through the use of `sbpy.data` classes, which allow the user to define their preferrred parameters if they do not happen to be satisfied with the catalog functionalities and derivations of parameters that sbpy offers. Yet we recommend the use of as many sbpy functionalities as possible in order to maintain consistency in your calculations, which may prove to be important when conversations about comet classification arise. " 428 | ] 429 | }, 430 | { 431 | "cell_type": "markdown", 432 | "metadata": {}, 433 | "source": [ 434 | "Helpful Links\n", 435 | "=======\n", 436 | "___________________________________________\n", 437 | "\n", 438 | "Relevant Notebooks\n", 439 | "-----------------\n", 440 | "- [How to calculate LTE production rates without photolysis effects](LTE_prodrate_without_photolysis.ipynb)\n", 441 | "- [How to calculate LTE production rates with Haser model](LTE_prodrate_Haser.ipynb)\n", 442 | "- [How to use Phys data class and `from_jplspec`](../data/Phys.ipynb)\n", 443 | "- [What is `astroquery.jplspec`](../data/jplspec.ipynb)\n", 444 | "\n", 445 | "Relevant Links\n", 446 | "-------------\n", 447 | "- [LAMDA Queries with astroquery](https://astroquery.readthedocs.io/en/latest/lamda/lamda.html)\n", 448 | "- [JPLSpec Queries with astroquery](https://astroquery.readthedocs.io/en/latest/jplspec/jplspec.html)\n", 449 | "- [sbpy Activity Haser Class](https://sbpy.readthedocs.io/en/latest/api/sbpy.activity.Haser.html#sbpy.activity.Haser)\n", 450 | "- [sbpy Ephem data class](https://sbpy.readthedocs.io/en/latest/sbpy/data/index.html#how-to-use-ephem)\n", 451 | "- [sbpy Phys data class](https://sbpy.readthedocs.io/en/latest/sbpy/data/index.html#how-to-use-phys)\n", 452 | "- [sbpy data class alternative field names](https://sbpy.readthedocs.io/en/latest/sbpy/data/fieldnames.html#list-of-alternative-field-names)\n", 453 | "- [pyradex source code](https://github.com/keflavich/pyradex)\n", 454 | "- [RADEX fortran source code](https://personal.sron.nl/~vdtak/radex/)\n", 455 | "- [RADEX homepage](https://personal.sron.nl/~vdtak/radex/index.shtml)\n", 456 | "- [sbpy citation (please cite our work)](http://joss.theoj.org/papers/10.21105/joss.01426)" 457 | ] 458 | }, 459 | { 460 | "cell_type": "code", 461 | "execution_count": null, 462 | "metadata": { 463 | "collapsed": true 464 | }, 465 | "outputs": [], 466 | "source": [] 467 | } 468 | ], 469 | "metadata": { 470 | "kernelspec": { 471 | "display_name": "Python 3", 472 | "language": "python", 473 | "name": "python3" 474 | }, 475 | "language_info": { 476 | "codemirror_mode": { 477 | "name": "ipython", 478 | "version": 3 479 | }, 480 | "file_extension": ".py", 481 | "mimetype": "text/x-python", 482 | "name": "python", 483 | "nbconvert_exporter": "python", 484 | "pygments_lexer": "ipython3", 485 | "version": "3.6.8" 486 | } 487 | }, 488 | "nbformat": 4, 489 | "nbformat_minor": 2 490 | } 491 | -------------------------------------------------------------------------------- /notebooks/spectroscopy/reddened-solar-spectrum.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Reddened solar spectrum\n", 8 | "\n", 9 | "sbpy's `sbpy.spectroscopy.SpectralGradient` can be used to redden a solar spectrum, although this approach may be revised with future sbpy capabilities." 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 1, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import numpy as np\n", 19 | "import matplotlib.pyplot as plt\n", 20 | "import astropy.units as u\n", 21 | "from sbpy.spectroscopy import SpectralGradient\n", 22 | "from sbpy.units import hundred_nm\n", 23 | "from sbpy.calib import Sun" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": 2, 29 | "metadata": {}, 30 | "outputs": [ 31 | { 32 | "name": "stderr", 33 | "output_type": "stream", 34 | "text": [ 35 | "WARNING: Source spectrum is tapered. [synphot.observation]\n", 36 | "WARNING:astropy:Source spectrum is tapered.\n" 37 | ] 38 | }, 39 | { 40 | "name": "stdout", 41 | "output_type": "stream", 42 | "text": [ 43 | "14.0 % / 100 nm\n" 44 | ] 45 | } 46 | ], 47 | "source": [ 48 | "sun = Sun.from_builtin('E490_2014LR')\n", 49 | "wave = np.linspace(0.3, 0.9, 300) * u.um\n", 50 | "fluxd = sun.observe(wave)\n", 51 | "S = SpectralGradient(14 * u.percent / hundred_nm, wave0=0.55 * u.um)\n", 52 | "print(S)" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "`SpectralGradient` works with two-band photometry expressed as magnitudes. To use it for a spectrum, the function `to_color()` must be repeatedly called:" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": 3, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "color_index = u.Quantity([S.to_color((0.55 * u.um, w)) for w in wave])\n", 69 | "# express in linear units (reflectance)\n", 70 | "r = 10**(0.4 * color_index.value)" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": 4, 76 | "metadata": {}, 77 | "outputs": [ 78 | { 79 | "data": { 80 | "image/png": "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v6SkhH/9619MnDix3u1Op5PbbruNb775ho0bN/Luu+/WqGsJUFRUxMqVK1m7di3BwcGsW7eOiooKXnvtNW677bYG7aqoqCAvL4+MjJqRpWHDhvHJJ594Oha42bhxI++99x4bNmxg9uzZ3HrrrTidTr9s7GiMoDUHj4dmQo4GA2hvZ+DAgVx99dUMGzaMzMxMnnzyScaPH8+IESNqtIR55JFHGDBgAMceeyxbtmzxjK9YsYKRI0cycuRIXnjhBc+40+nknnvu8ZzrP//5D6A9qRNOOIGLLrqIQYMGceWVV+IuELFixQqOP/54xo4dy6mnnsr+/fsbvUZtiouLOfPMMxk4cCA333wzLpeLV199tUaXgJdffpnf/va3dY6dNGkS3bp1qzMO8MADD3DfffcRGhpa7/Zly5bRr18/+vTpQ3BwMJdddhmfffZZjX1sNhvV1dUopSgvLycoKIinnnqKO+64g6CgeurMWrh/XrUZPHgwAwcOrDP+2WefcdlllxESEkLv3r3p168fy5Yt88tG0A1c77vvPiZMmMCAAQNYsGABoBe/n3feeZxyyin06tWL559/nqeffprRo0czadIkT/mxlmCSQppDkeWyR6d1rB0GQ31883vdYLY1SR0OpzceWtq2bRtvvPEGkyZNYs6cOWzbto1ly5ahlOKcc87hp59+IiIigvfee4/Vq1fjcDgYM2YMY8eOBeDaa6/l+eefZ+rUqdxzzz2e877yyivExMTwyy+/UFVVxZQpU5g+fToAq1atYsOGDaSlpTFlyhQWLVrExIkTueOOO/jss89ISkri/fff549//COvvvpqg9eozbJly9i4cSM9e/bktNNO45NPPuGSSy7hkUce4cknnyQoKIjXXnvNI67+sHLlSjIzMznzzDN58skn690nOzub7t2961kzMjLqdP6OiorijDPOYPTo0UybNo2YmBiWLl3KAw880Oj1v/nmG8477zy/7c3OzmbSpEk1bMnO1l/mm7LRjcPhYNmyZXz99dc89NBDfPfddwCsX7+eVatWUVlZSb9+/Xj88cdZtWoVv/3tb3nzzTfrtBdqLkbQmkNxNoTF6+adBoMBgJ49e3o+AOfMmcOcOXM81fZLS0vZtm0bJSUlnH/++YSH6/+dc845B4DCwkIKCws9Ya9f/epXniLFc+bMYe3atXz00UeADrlt27aN4OBg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\n", 81 | "text/plain": [ 82 | "
" 83 | ] 84 | }, 85 | "metadata": { 86 | "needs_background": "light" 87 | }, 88 | "output_type": "display_data" 89 | } 90 | ], 91 | "source": [ 92 | "ax = plt.gca()\n", 93 | "ax.plot(wave, fluxd, label='Solar spectrum')\n", 94 | "ax.plot(wave, r * fluxd, label='reddened by {}'.format(S))\n", 95 | "plt.setp(ax, ylabel='Flux density ({})'.format(fluxd.unit),\n", 96 | " xlabel='Wavelength ({})'.format(wave.unit))\n", 97 | "plt.legend()\n", 98 | "plt.show()" 99 | ] 100 | } 101 | ], 102 | "metadata": { 103 | "kernelspec": { 104 | "display_name": "Python 3", 105 | "language": "python", 106 | "name": "python3" 107 | }, 108 | "language_info": { 109 | "codemirror_mode": { 110 | "name": "ipython", 111 | "version": 3 112 | }, 113 | "file_extension": ".py", 114 | "mimetype": "text/x-python", 115 | "name": "python", 116 | "nbconvert_exporter": "python", 117 | "pygments_lexer": "ipython3", 118 | "version": "3.8.6" 119 | } 120 | }, 121 | "nbformat": 4, 122 | "nbformat_minor": 4 123 | } 124 | -------------------------------------------------------------------------------- /workshops/LSST_SSSC_Sprint_2022/1-data-containers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "49100d94", 6 | "metadata": { 7 | "tags": [] 8 | }, 9 | "source": [ 10 | "# Data containers" 11 | ] 12 | }, 13 | { 14 | "cell_type": "markdown", 15 | "id": "d1db1bfb", 16 | "metadata": { 17 | "tags": [] 18 | }, 19 | "source": [ 20 | "## Ephemerides" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 1, 26 | "id": "f6d67675", 27 | "metadata": {}, 28 | "outputs": [ 29 | { 30 | "name": "stdout", 31 | "output_type": "stream", 32 | "text": [ 33 | "\n", 34 | " rh delta phase \n", 35 | " AU AU deg \n", 36 | "float64 float64 float64\n", 37 | "------- ------- -------\n", 38 | " 1.0 1.0 60.0\n" 39 | ] 40 | } 41 | ], 42 | "source": [ 43 | "import astropy.units as u # for physical quantities\n", 44 | "from sbpy.data import Ephem # for ephemerides\n", 45 | "\n", 46 | "eph = Ephem.from_dict({'rh': 1 * u.au, 'delta': 1 * u.au, 'phase': 60 * u.deg})\n", 47 | "print(eph)" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": 2, 53 | "id": "b0efd4c0", 54 | "metadata": {}, 55 | "outputs": [ 56 | { 57 | "name": "stdout", 58 | "output_type": "stream", 59 | "text": [ 60 | "{'start':