diff --git a/tutorials/stellar_streams.ipynb b/tutorials/stellar_streams.ipynb index a383ef4..95aab14 100644 --- a/tutorials/stellar_streams.ipynb +++ b/tutorials/stellar_streams.ipynb @@ -6,12 +6,12 @@ "source": [ "\\*\\* *(under construction. If you're using Binder, please note that this tutorial is only fully functional in Firefox at the moment.)* \\*\\*\n", "\n", - "Adapted from [a notebook](https://nbviewer.jupyter.org/github/marksubbarao/pyWWT_AAS225/blob/master/SgrStream.ipynb) by Mark SubbaRao that uses files from [here](http://www.astro.virginia.edu/~srm4n/Sgr/data.html) and visualizes the tidal disruption of the Sagittarius Dwarf Galaxy described in [Law & Majewski 2010](https://iopscience.iop.org/article/10.1088/0004-637X/714/1/229)." + "Adapted from [two](https://nbviewer.jupyter.org/github/marksubbarao/pyWWT_AAS225/blob/master/SgrStream.ipynb) [notebooks](https://nbviewer.jupyter.org/github/marksubbarao/pyWWT_AAS225/blob/master/CosmicFlows.ipynb) by Mark SubbaRao that use files from [here](http://faculty.virginia.edu/srm4n/Sgr/data.html) and visualize the tidal disruption of the Sagittarius Dwarf Galaxy by the Milky Way as described in [Law & Majewski 2010](https://iopscience.iop.org/article/10.1088/0004-637X/714/1/229)." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -24,50 +24,220 @@ "\n", "import numpy as np\n", "\n", - "from astroquery.vizier import Vizier\n", - "from astroquery.nasa_exoplanet_archive import NasaExoplanetArchive\n", - "\n", "from pywwt.jupyter import WWTJupyterWidget" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "wwt = WWTJupyterWidget()\n", - "#wwt" + "wwt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "*WWT works under HTTP, while Binder uses HTTPS. As such, in order to access all features of pywwt, Binder users will need to:*\n", + "*WWT works under HTTP, while Binder uses HTTPS. As such, in order to access all features of pywwt, Binder users will need to disable HTTPS for this session. Firefox users can do this with the following steps:*\n", "- *Click the lock icon to the left of the address bar,*\n", "- *Select the arrow next to “Connection,”*\n", "- *Then, press the “Disable protection for now” button. (Protection is disabled for this page and only during this session, not for your whole browser. We are working on upgrading WWT so this step is no longer necessary.)*" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Simulating a galaxy merger and plotting stellar streams" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "(In this example, we a) simulate the position of the center of a dwarf galaxy during its near-merger with the Milky Way, and b) plot the positions of a snapshot of the resulting debris near the present day.)\n", + "\n", + "**First, we retrieve a table with time and position data for the Sagittarius Dwarf Galaxy from a `pywwt`-affiliated GitHub repository. Then, we cut it down to only the columns needed for this example and assign them their proper units.**" + ] + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "orbit = Table.read('https://raw.githubusercontent.com/WorldWideTelescope/pywwt-notebooks/master/tutorials/data/SgrTriax_orbit.dat',\n", + " format='ascii.basic')\n", + "#orbit = Table.read('SgrTriax_orbit.dat', format='ascii.basic')" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "orbit.keep_columns(['time', 'ra', 'dec', 'dist'])\n", + "orbit['ra'].unit = u.deg\n", + "orbit['dec'].unit = u.deg\n", + "orbit['time'].unit = u.Gyr\n", + "orbit['dist'] *= 1000\n", + "orbit['dist'].unit = u.pc" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**We'll also need to create a new column -- based on the original time column -- that converts and compresses our current gigayear times, which are too large for `pywwt` to simulate.** \n", + "\n", + "Instead, we'll convert them to Julian dates (which *are* readable by `pywwt`) and compress them so the action happens in a matter of seconds." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# translate times from gigayears, which are too large for pywwt, ...\n", + "# to days -- so 1 day in the viewer translates to 1 gigayear real-time\n", + "\n", + "# T0-D0: find proper factor so that 1 gyr to translates to 10 seconds\n", + "base = Time('2019-01-01', format='iso').jd\n", + "orbit['wwt_times'] = base\n", + "orbit['wwt_times'] += orbit['time']" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "Table length=4266\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
timeradecdistwwt_times
Gyrdegdegpc
float64float64float64float64float64
-7.996129.7451-8.5173252743.62458476.5039
-7.988928.869-8.9259853198.12458476.5111
-7.981727.9937-9.3326253632.82458476.5183
-7.974427.1194-9.7370954049.62458476.5256
-7.967226.2453-10.139254446.92458476.5328
-7.9625.37-10.540354826.7999999999962458476.54
-7.952724.4935-10.939555188.02458476.5473
-7.945523.6163-11.336355531.52458476.5545
-7.938322.7355-11.732655857.7000000000042458476.5617
...............
7.8936266.154-27.509365477.82458492.3936
7.9054265.448-26.965465230.72458492.4054
7.9166264.78-26.447164920.72458492.4166
7.9278264.111-25.92364534.8999999999942458492.4278
7.9389263.438-25.391564073.499999999992458492.4389
7.9501262.759-24.851363536.52458492.4501
7.9606262.113-24.333262960.92458492.4606
7.9711261.457-23.804262316.72458492.4711
7.9817260.791-23.262861603.2999999999962458492.4817
7.9915260.155-22.742260871.2999999999962458492.4915
" + ], + "text/plain": [ + "\n", + " time ra dec dist wwt_times \n", + " Gyr deg deg pc \n", + "float64 float64 float64 float64 float64 \n", + "------- ------- -------- ------------------ ------------\n", + "-7.9961 29.7451 -8.51732 52743.6 2458476.5039\n", + "-7.9889 28.869 -8.92598 53198.1 2458476.5111\n", + "-7.9817 27.9937 -9.33262 53632.8 2458476.5183\n", + "-7.9744 27.1194 -9.73709 54049.6 2458476.5256\n", + "-7.9672 26.2453 -10.1392 54446.9 2458476.5328\n", + " -7.96 25.37 -10.5403 54826.799999999996 2458476.54\n", + "-7.9527 24.4935 -10.9395 55188.0 2458476.5473\n", + "-7.9455 23.6163 -11.3363 55531.5 2458476.5545\n", + "-7.9383 22.7355 -11.7326 55857.700000000004 2458476.5617\n", + " ... ... ... ... ...\n", + " 7.8936 266.154 -27.5093 65477.8 2458492.3936\n", + " 7.9054 265.448 -26.9654 65230.7 2458492.4054\n", + " 7.9166 264.78 -26.4471 64920.7 2458492.4166\n", + " 7.9278 264.111 -25.923 64534.899999999994 2458492.4278\n", + " 7.9389 263.438 -25.3915 64073.49999999999 2458492.4389\n", + " 7.9501 262.759 -24.8513 63536.5 2458492.4501\n", + " 7.9606 262.113 -24.3332 62960.9 2458492.4606\n", + " 7.9711 261.457 -23.8042 62316.7 2458492.4711\n", + " 7.9817 260.791 -23.2628 61603.299999999996 2458492.4817\n", + " 7.9915 260.155 -22.7422 60871.299999999996 2458492.4915" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "orbit" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*(You can see how our table looks now by typing `orbit` in a new cell above this one and running it.)*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Now, we can begin building the stellar streams table. The process is similar to the one for `orbit` -- importing the table, slim it down to the necessary columns, and give units to columns that need them.**" + ] + }, + { + "cell_type": "code", + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# import and manipulate a table with stellar stream data\n", - "stars = Table.read('https://raw.githubusercontent.com/WorldWideTelescope/pywwt-notebooks/137d6a398b4ba0b6de332cd4603e8e40c74bedcf/tutorials/data/SgrTriax_DYN.dat',\n", + "stars = Table.read('https://raw.githubusercontent.com/WorldWideTelescope/pywwt-notebooks/master/tutorials/data/SgrTriax_DYN.dat',\n", " format='ascii.basic')\n", - "#stars = Table.read('SgrTriax_DYN.dat', format='ascii.basic')\n", - "stars.keep_columns([\"ra\",\"dec\",\"dist\",\"Pcol\"])\n", + "#stars = Table.read('data/SgrTriax_DYN.dat', format='ascii.basic')" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "stars.keep_columns([\"ra\", \"dec\", \"dist\", \"Pcol\"])\n", "stars['ra'].unit = u.deg\n", "stars['dec'].unit = u.deg\n", "stars['dist'] *= 1000\n", - "stars['dist'].unit = u.pc\n", - "#stars.rename_column('dist','distance')\n", + "stars['dist'].unit = u.pc" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Next, we add a colormap column for pywwt to read in creating the data layer.** \n", "\n", - "# add a column of colors for each point for pywwt to read\n", + "In Law & Majewski 2010, the authors color the tidal debris based on how many rotations it took before that patch of debris was stripped from its parent galaxy. We follow the same system, with the specific colors listed as comments below." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ "stars['colormap'] = '#000000'\n", "for i, val in enumerate(stars['Pcol']):\n", " if val == -1:\n", @@ -83,12 +253,10 @@ ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "stars" + "**Let's transition back to `pywwt` now that we have the tables we need for our data layers. Move the viewer down here and switch to the 3-D solar system view.**" ] }, { @@ -97,13 +265,16 @@ "metadata": {}, "outputs": [], "source": [ - "# display the stellar streams in the viewer\n", - "star_ly = wwt.layers.add_data_layer(table=stars, frame='Sky',\n", - " lon_att='ra', lat_att='dec',\n", - " alt_att='dist', alt_type='distance',\n", - " cmap_att='colormap', size_scale=40)\n", + "wwt.set_view('solar system')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**As indicated in this tutorial's title, we have two visualizations to make. First, we'll plot the center of mass of the Sagittarius Dwarf Galaxy in order to simulate its tidal disruption by the Milky Way.**\n", "\n", - "star_ly.far_side_visible = True" + "\\*\\* *(still under development, as we need working time series first)* \\*\\*" ] }, { @@ -112,30 +283,19 @@ "metadata": {}, "outputs": [], "source": [ - "# import and manipulate a table containing Sgr Dwarf's orbital data\n", - "orbit = Table.read('https://raw.githubusercontent.com/WorldWideTelescope/pywwt-notebooks/137d6a398b4ba0b6de332cd4603e8e40c74bedcf/tutorials/data/SgrTriax_orbit.dat',\n", - " format='ascii.basic')\n", - "#orbit = Table.read('SgrTriax_orbit.dat', format='ascii.basic')\n", - "orbit.keep_columns(['time', 'ra', 'dec', 'dist'])\n", - "orbit['ra'].unit = u.deg\n", - "orbit['dec'].unit = u.deg\n", - "orbit['time'].unit = u.Gyr\n", - "orbit['dist'] *= 1000\n", - "orbit['dist'].unit = u.pc\n", - "#orbit.rename_column('dist', 'distance')" + "orb_ly = wwt.layers.add_data_layer(table=orbit, frame='Sky',\n", + " lon_att='ra', lat_att='dec',\n", + " alt_att='dist', alt_type='distance',\n", + " size_scale=20)\n", + "\n", + "#wwt.play_time(...) # T0-D0: find proper rate at which to play time" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "# translate times from gigayears, which are too large for pywwt, ...\n", - "# to days -- so 1 day in the viewer translates to 1 gigayear real-time\n", - "base = Time('2019-01-01', format='iso').jd\n", - "orbit['wwt_times'] = base\n", - "orbit['wwt_times'] += orbit['time']" + "Once the simulation has concluded, delete this layer and pause the passage of time to make way for the next visualization." ] }, { @@ -144,24 +304,20 @@ "metadata": {}, "outputs": [], "source": [ - "orbit" + "wwt.pause_time()\n", + "orb_ly.remove()\n", + "# wwt.play_time(1) # ??" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "# display Sgr Dwarf in the viewer\n", - "# (we only plot a slice of orbit to ensure your system can handle it...\n", - "# ...if so, replace 'orbit[:300]' with 'orbit')\n", - "orb_ly = wwt.layers.add_data_layer(table=orbit[:300], frame='Sky',\n", - " lon_att='ra', lat_att='dec',\n", - " alt_att='dist', alt_type='distance',\n", - " size_scale=20)\n", + "**In the second visualization, we plot a color-coded, present-day snapshot of the Sagittarius Dwarf's stellar streams.**\n", "\n", - "orb_ly.far_side_visible = True" + "Again, we link attributes to the proper columns, equip the proper distance setting, and choose our desired point size. (Each attribute is also editable after the layer is created.)\n", + "\n", + "For this one, we also set `far_side_visible` to `True` so we can see the debris even when it lies behind the Milky Way." ] }, { @@ -170,7 +326,10 @@ "metadata": {}, "outputs": [], "source": [ - "wwt.set_view('solar system')" + "dbr_ly = wwt.layers.add_data_layer(table=stars, frame='Sky',\n", + " lon_att='ra', lat_att='dec',\n", + " alt_att='dist', alt_type='distance',\n", + " size_scale=40, far_side_visible=True)" ] } ],