From 08b1ae465e555098230bfb748eabd989a4b7d303 Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Sat, 20 Nov 2021 19:48:23 -0500 Subject: [PATCH 01/11] add spectral-cube rperojection --- .../SpectralCubeReprojectExample.ipynb | 640 ++++++++++++++++++ 1 file changed, 640 insertions(+) create mode 100644 tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb diff --git a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb new file mode 100644 index 00000000..d51e6f1b --- /dev/null +++ b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb @@ -0,0 +1,640 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "charged-dollar", + "metadata": {}, + "source": [ + "# Cube Reprojection Tutorial\n", + "\n", + "## Authors\n", + "Adam Ginsburg, Eric Koch\n", + "\n", + "## Learning Goals\n", + "* reproject a cube spectrally\n", + "* smooth it spectrally\n", + "* reproject it spatially\n", + "\n", + "## Keywords\n", + "cube, reprojection\n", + "\n", + "## Summary\n", + "This tutorial shows how to take two spectral cubes observed toward the same part of the sky, but different frequencies, and put them onto the same grid using [spectral-cube](spectral-cube.readthedocs.io)." + ] + }, + { + "cell_type": "markdown", + "id": "random-fusion", + "metadata": {}, + "source": [ + "## Index \n", + "\n", + " * [Step 1: Download](#Step-1:-Download-the-data)\n", + " * [Step 2: Open files, collect metadata](#Step-2:-Load-the-cubes)\n", + " * [Step 3: Convert to velocity](#Step-3:-Convert-cubes-from-frequency-to-velocity)\n", + " * [Step 4: Spectral Interpolation](#Step-4.-Spectral-Interpolation)\n", + " * [Step 5: Spatial Smoothing](#Step-5.-Spatial-Smoothing)\n", + " * [Step 6: Reprojection](#Step-6.-Reprojection)\n", + " \n", + " \n", + "In this example, we do spectral smoothing and interpolation (step 4) before spatial smoothing and interpolation (step 5), but if you have a varying-resolution cube (with a different beam size for each channel), you have to do spatial smoothing first. For more information see the [spectral-cube documentation](spectral-cube.readthedocs.io)." + ] + }, + { + "cell_type": "markdown", + "id": "difficult-vertex", + "metadata": {}, + "source": [ + "## Step 1: Download the data\n", + "\n", + "(you might not have to do this step, since you may already have data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "sexual-grave", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from astropy.utils.data import download_file" + ] + }, + { + "cell_type": "markdown", + "id": "supposed-mileage", + "metadata": {}, + "source": [ + "We download the data cubes (18 MB and 337 MB, respectively) from a permalink on the ALMA archives.\n", + "\n", + "If you have trouble with these downloads, try changing to a different ALMA server (e.g., almascience.nrao.edu->almascience.eso.org) or increase the timeout. See https://docs.astropy.org/en/stable/api/astropy.utils.data.download_file.html." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "rapid-prime", + "metadata": {}, + "outputs": [], + "source": [ + "filename_1 = download_file(\"https://almascience.nrao.edu/dataPortal/member.uid___A001_X1465_X3a33.BrickMaser_sci.spw71.cube.I.manual.image.pbcor.fits\",\n", + " cache=True)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "stuck-thirty", + "metadata": {}, + "outputs": [], + "source": [ + "filename_2 = download_file(\"https://almascience.nrao.edu/dataPortal/member.uid___A001_X87d_X141.a_sma1_sci.spw27.cube.I.pbcor.fits\",\n", + " cache=True)" + ] + }, + { + "cell_type": "markdown", + "id": "hearing-meter", + "metadata": {}, + "source": [ + "## Step 2: Load the cubes" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "brazilian-reward", + "metadata": {}, + "outputs": [], + "source": [ + "from spectral_cube import SpectralCube" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "similar-ideal", + "metadata": {}, + "outputs": [], + "source": [ + "cube1 = SpectralCube.read(filename_1)\n", + "cube1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "integral-costume", + "metadata": {}, + "outputs": [], + "source": [ + "cube2 = SpectralCube.read(filename_2)\n", + "cube2" + ] + }, + { + "cell_type": "markdown", + "id": "wound-remark", + "metadata": {}, + "source": [ + "The cubes are at different frequencies - 139 and 89 GHz.\n", + "\n", + "The first cube covers the H2CS 4(1,3)-3(1,2) line at 139.483699\tGHz.\n", + "\n", + "The second covers SiO v=5-4 at 217.104984 GHz" + ] + }, + { + "cell_type": "markdown", + "id": "forty-terminal", + "metadata": {}, + "source": [ + "We use the `find_lines` tool to query [splatalogue](https://splatalogue.online/) with [astroquery](https://astroquery.readthedocs.io/en/latest/splatalogue/splatalogue.html) over the spectral range covered by the cube. It returns a table of matching lines. Note that some line names will be repeated because Splatalogue includes several different databases and most chemical species are present in all of these." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "proud-flood", + "metadata": {}, + "outputs": [], + "source": [ + "cube1.find_lines(chemical_name=' H2CS ').show_in_notebook()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "victorian-society", + "metadata": {}, + "outputs": [], + "source": [ + "cube2.find_lines(chemical_name='SiO').show_in_notebook()" + ] + }, + { + "cell_type": "markdown", + "id": "proud-engagement", + "metadata": {}, + "source": [ + "## Step 3: Convert cubes from frequency to velocity" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "finite-saying", + "metadata": {}, + "outputs": [], + "source": [ + "from astropy import units as u" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "voluntary-modeling", + "metadata": {}, + "outputs": [], + "source": [ + "cube1vel = cube1.with_spectral_unit(u.km/u.s, velocity_convention='radio', rest_value=139.483699*u.GHz)\n", + "cube1vel" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "arranged-fault", + "metadata": {}, + "outputs": [], + "source": [ + "cube2vel = cube2.with_spectral_unit(u.km/u.s, velocity_convention='radio', rest_value=217.104984*u.GHz)\n", + "cube2vel" + ] + }, + { + "cell_type": "markdown", + "id": "false-rainbow", + "metadata": {}, + "source": [ + "From the shape of the cube, we can see the H2CS cube is narrower in velocity, so we'll use that as the target spectral reprojection. However, the SiO cube is the smaller footprint on the sky." + ] + }, + { + "cell_type": "markdown", + "id": "empty-national", + "metadata": {}, + "source": [ + "### Create spatial maps of the peak intensity to quickly explore the cubes:\n", + " \n", + "One way to quickly explore the structure in the data cubes is to produce a peak intensity map, or the maximum along the spectral axis (`axis=0`)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "rural-action", + "metadata": {}, + "outputs": [], + "source": [ + "mx = cube1.max(axis=0)\n", + "mx.quicklook()" + ] + }, + { + "cell_type": "markdown", + "id": "living-baltimore", + "metadata": {}, + "source": [ + "We can do the same thing all on one line (for the other cube this time):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "forty-permit", + "metadata": {}, + "outputs": [], + "source": [ + "cube2.max(axis=0).quicklook()" + ] + }, + { + "cell_type": "markdown", + "id": "ancient-analyst", + "metadata": {}, + "source": [ + "# Step 4. Spectral Interpolation\n", + "\n", + "We can do the spatial or spectral step first. In this case, we choose the spectral step first because the H$_2$CS cube is narrower in velocity (`cube1vel`) and this will reduce the number of channels we need to spatially interpolate over in the next step.\n", + "\n", + "We need to match resolution to the cube with the largest channel width:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "incorrect-producer", + "metadata": {}, + "outputs": [], + "source": [ + "velocity_res_1 = np.diff(cube1vel.spectral_axis)[0]\n", + "velocity_res_2 = np.diff(cube2vel.spectral_axis)[0]\n", + "velocity_res_1, velocity_res_2" + ] + }, + { + "cell_type": "markdown", + "id": "understood-jason", + "metadata": {}, + "source": [ + "Next, we will reduce `cube2vel` to have the same spectral range as `cube1vel`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "gentle-costume", + "metadata": {}, + "outputs": [], + "source": [ + "cube2vel_cutout = cube2vel.spectral_slab(cube1vel.spectral_axis.min(),\n", + " cube1vel.spectral_axis.max())\n", + "cube1vel, cube2vel_cutout" + ] + }, + { + "cell_type": "markdown", + "id": "other-medicare", + "metadata": {}, + "source": [ + "Note that it is important for the to-be-interpolated cube, in this case `cube2`, to have pixels bounding `cube1`'s spectral axis, but in this case it does not. If the pixel range doesn't overlap perfectly, it may blank out one of the edge pixels. So, to fix this, we add a little buffer:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "driven-smooth", + "metadata": {}, + "outputs": [], + "source": [ + "cube2vel_cutout = cube2vel.spectral_slab(cube1vel.spectral_axis.min() - velocity_res_2,\n", + " cube1vel.spectral_axis.max())\n", + "cube1vel, cube2vel_cutout" + ] + }, + { + "cell_type": "markdown", + "id": "treated-encyclopedia", + "metadata": {}, + "source": [ + "Our H2CS cube (`cube1vel`) has broader channels. We need to first smooth `cube2vel` to the broader channel width before doing the spatial reprojection.\n", + "\n", + "To do this, we will spectrally smooth with a Gaussian with width set such that smoothing `cube2vel` will result in the same width as `cube1vel`. We do this by finding the difference in widths when deconvolving the `cube1vel` channel width from `cube2vel`. For further information see the [documentation on smoothing](https://spectral-cube.readthedocs.io/en/latest/smoothing.html#spectral-smoothing).\n", + "\n", + "Note that if we did not do this smoothing step, we would under-sample the `cube2vel` data in the next downsampling step, reducing our signal-to-noise ratio.\n", + "\n", + "We have adopted a width equal to the channel width; the [line spread function](https://help.almascience.org/kb/articles/what-spectral-resolution-will-i-get-for-a-given-channel-spacing) is actually a Hanning-smoothed tophat. We are making a coarse approximation here." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "affecting-lebanon", + "metadata": {}, + "outputs": [], + "source": [ + "fwhm_gaussian = (velocity_res_1**2 - velocity_res_2**2)**0.5\n", + "fwhm_gaussian" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "temporal-assembly", + "metadata": {}, + "outputs": [], + "source": [ + "from astropy.convolution import Gaussian1DKernel\n", + "fwhm_to_sigma = np.sqrt(8*np.log(2))\n", + "# we want the kernel in pixel units, so we force to km/s and take the value\n", + "spectral_smoothing_kernel = Gaussian1DKernel(stddev=fwhm_gaussian.to(u.km/u.s).value / fwhm_to_sigma)" + ] + }, + { + "cell_type": "markdown", + "id": "competitive-church", + "metadata": {}, + "source": [ + "We then smooth with the kernel. Note that this is doing 420x420 = 176400 smoothing operations on a length-221 spectrum: it will take a little time" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "lined-input", + "metadata": {}, + "outputs": [], + "source": [ + "cube2vel_smooth = cube2vel_cutout.spectral_smooth(spectral_smoothing_kernel)" + ] + }, + { + "cell_type": "markdown", + "id": "steady-spectacular", + "metadata": {}, + "source": [ + "Now that we've done spectral smoothing, we can resample the spectral axis of `cube2vel_smooth` to match `cube1vel` by interpolating `cube2vel_smooth` onto `cube1vel`'s grid:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "pretty-treat", + "metadata": {}, + "outputs": [], + "source": [ + "cube2vel_spectralresample = cube2vel_smooth.spectral_interpolate(cube1vel.spectral_axis,\n", + " suppress_smooth_warning=True)\n", + "cube2vel_spectralresample" + ] + }, + { + "cell_type": "markdown", + "id": "upset-attendance", + "metadata": {}, + "source": [ + "Note that we included the `suppress_smooth_warning=True` argument. That is to hide this warning:\n", + "```\n", + "WARNING: SmoothingWarning: Input grid has too small a spacing. The data should be smoothed prior to resampling. [spectral_cube.spectral_cube]\n", + "```\n", + "which will tell you if the operation will under-sample the original data. The smoothing work we did above is specifically to make sure we are properly sampling, so this warning does not apply." + ] + }, + { + "cell_type": "markdown", + "id": "judicial-making", + "metadata": {}, + "source": [ + "# Step 5. Spatial Smoothing" + ] + }, + { + "cell_type": "markdown", + "id": "active-affiliation", + "metadata": {}, + "source": [ + "Now that we've done spectral smoothing, we also need to follow a similar procedure of smoothing then resampling for the spatial axes. \n", + "\n", + "The `beam` is the resolution element of our cubes:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "military-bangladesh", + "metadata": {}, + "outputs": [], + "source": [ + "cube1vel.beam, cube2vel_spectralresample.beam" + ] + }, + { + "cell_type": "markdown", + "id": "qualified-macintosh", + "metadata": {}, + "source": [ + "`cube1` again hase the larger beam, so we'll smooth `cube2` to its resolution" + ] + }, + { + "cell_type": "markdown", + "id": "breeding-ambassador", + "metadata": {}, + "source": [ + "#### Aside: mixed beams \n", + "\n", + "If cube1 and cube2 had different sized beams, but neither was clearly larger, we would have to convolve _both_ to a [common beam](https://radio-beam.readthedocs.io/en/latest/commonbeam.html#finding-the-smallest-common-beam).\n", + "\n", + "In this case, it's redundant and we could have just used `cube1`'s beam, but this is the more general approach:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "pregnant-account", + "metadata": {}, + "outputs": [], + "source": [ + "import radio_beam\n", + "common_beam = radio_beam.commonbeam.common_2beams(radio_beam.Beams(beams=[cube1vel.beam, cube2vel.beam]))\n", + "common_beam" + ] + }, + { + "cell_type": "markdown", + "id": "different-surface", + "metadata": {}, + "source": [ + "We then convolve:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "returning-moses", + "metadata": {}, + "outputs": [], + "source": [ + "# for v<0.6, we convert to Kelvin to ensure the units are preserved:\n", + "# cube2vel_spatialspectralsmooth = cube2vel_spectralresample.to(u.K).convolve_to(common_beam)\n", + "# in more recent versions, the unit conversion is handled appropriately,\n", + "# so unit conversion isn't needed\n", + "cube2vel_spatialspectralsmooth = cube2vel_spectralresample.convolve_to(common_beam)\n", + "cube2vel_spatialspectralsmooth" + ] + }, + { + "cell_type": "markdown", + "id": "indie-wallpaper", + "metadata": {}, + "source": [ + "# Step 6. Reprojection\n", + "\n", + "Now we can do the spatial resampling as the final step for producing two cubes matched to the same spatial and spectral pixel grid:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "coordinated-nomination", + "metadata": {}, + "outputs": [], + "source": [ + "cube2vel_reproj = cube2vel_spatialspectralsmooth.reproject(cube1vel.header)\n", + "cube2vel_reproj" + ] + }, + { + "cell_type": "markdown", + "id": "minimal-conversion", + "metadata": {}, + "source": [ + "These two cubes are now on an identical grid, and can be directly compared:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "worse-company", + "metadata": {}, + "outputs": [], + "source": [ + "cube2vel_reproj, cube1vel" + ] + }, + { + "cell_type": "markdown", + "id": "liberal-absorption", + "metadata": {}, + "source": [ + "These spectra can now be overplotted as they are in the same unit with the same beam." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "precious-creator", + "metadata": {}, + "outputs": [], + "source": [ + "cube1vel[:,125,125].quicklook()\n", + "cube2vel_reproj[:,125,125].quicklook()" + ] + }, + { + "cell_type": "markdown", + "id": "regional-cooperation", + "metadata": {}, + "source": [ + "# Dask\n", + "\n", + "All of the above can be done using `dask` as the underlying framework to parallelize the operations.\n", + "\n", + "The dask approach can be made more memory-efficient (avoid using too much RAM) by writing intermediate steps to disk. The non-dask approach used above will generally need to read the whole cube into memory. Depending on the situation, either approach may be faster, but `dask` may be needed if the cube is larger than memory." + ] + }, + { + "cell_type": "markdown", + "id": "ambient-audience", + "metadata": {}, + "source": [ + "We repeat all the operations above using dask. We use a `ProgressBar` so you can see how long it takes. We also suppress warnings to make the output look cleaner (we already saw all the important warnings above)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dated-project", + "metadata": {}, + "outputs": [], + "source": [ + "from dask.diagnostics import ProgressBar\n", + "import warnings" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "vertical-breed", + "metadata": {}, + "outputs": [], + "source": [ + "with warnings.catch_warnings():\n", + " warnings.simplefilter('ignore')\n", + " with ProgressBar():\n", + " cube2dask = SpectralCube.read(filename_2, use_dask=True)\n", + " cube2daskvel = cube2dask.with_spectral_unit(u.km/u.s,\n", + " velocity_convention='radio', rest_value=217.104984*u.GHz)\n", + " cube2daskvel_cutout = cube2daskvel.spectral_slab(cube1vel.spectral_axis.min() - velocity_res_2,\n", + " cube1vel.spectral_axis.max())\n", + " cube2daskvel_smooth = cube2daskvel_cutout.spectral_smooth(spectral_smoothing_kernel)\n", + " cube2daskvel_spectralresample = cube2daskvel_smooth.spectral_interpolate(cube1vel.spectral_axis,\n", + " suppress_smooth_warning=True)\n", + " cube2daskvel_spatialspectralsmooth = cube2daskvel_spectralresample.convolve_to(common_beam)\n", + " cube2daskvel_reproj = cube2daskvel_spatialspectralsmooth.reproject(cube1vel.header)\n", + "cube2daskvel_reproj" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "several-saver", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Py 3.9", + "language": "python", + "name": "python39" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From d87a9de33016c5842ce4bdaea5a6bfd9cc1358d7 Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Tue, 14 Dec 2021 12:45:18 -0500 Subject: [PATCH 02/11] change python version --- .../SpectralCubeReprojectExample.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb index d51e6f1b..a23f557e 100644 --- a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb +++ b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb @@ -618,9 +618,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Py 3.9", + "display_name": "Python 3", "language": "python", - "name": "python39" + "name": "python3" }, "language_info": { "codemirror_mode": { From 01472bb446c6b97de9b49ac21305d3fc8b4010e9 Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Wed, 29 Dec 2021 08:35:33 -0500 Subject: [PATCH 03/11] corrections following Kelle's review --- .../SpectralCubeReprojectExample.ipynb | 68 ++----------------- 1 file changed, 6 insertions(+), 62 deletions(-) diff --git a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb index a23f557e..2ce150af 100644 --- a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb +++ b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb @@ -2,7 +2,6 @@ "cells": [ { "cell_type": "markdown", - "id": "charged-dollar", "metadata": {}, "source": [ "# Cube Reprojection Tutorial\n", @@ -16,15 +15,14 @@ "* reproject it spatially\n", "\n", "## Keywords\n", - "cube, reprojection\n", + "spectral cube, radio astronomy, astroquery, units, dask\n", "\n", "## Summary\n", - "This tutorial shows how to take two spectral cubes observed toward the same part of the sky, but different frequencies, and put them onto the same grid using [spectral-cube](spectral-cube.readthedocs.io)." + "This tutorial shows how to take two spectral cubes observed toward the same part of the sky, but different frequencies, and put them onto the same grid using [spectral-cube](spectral-cube.readthedocs.io). It uses [astroquery](https://astroquery.readthedocs.io/) to obtain line frequencies from [splatalogue](https://astroquery.readthedocs.io/en/latest/splatalogue/splatalogue.html). Finally, it shows how to do the reprojection using [dask](https://dask.org) to enable parallelization." ] }, { "cell_type": "markdown", - "id": "random-fusion", "metadata": {}, "source": [ "## Index \n", @@ -42,7 +40,6 @@ }, { "cell_type": "markdown", - "id": "difficult-vertex", "metadata": {}, "source": [ "## Step 1: Download the data\n", @@ -53,7 +50,6 @@ { "cell_type": "code", "execution_count": null, - "id": "sexual-grave", "metadata": {}, "outputs": [], "source": [ @@ -63,18 +59,17 @@ }, { "cell_type": "markdown", - "id": "supposed-mileage", "metadata": {}, "source": [ - "We download the data cubes (18 MB and 337 MB, respectively) from a permalink on the ALMA archives.\n", + "We download two example spectral cubes of a point in the Galactic center from a permalink on the ALMA archives.\n", + "These are moderately large files, with sizes 18 MB and 337 MB.\n", "\n", - "If you have trouble with these downloads, try changing to a different ALMA server (e.g., almascience.nrao.edu->almascience.eso.org) or increase the timeout. See https://docs.astropy.org/en/stable/api/astropy.utils.data.download_file.html." + "If you have trouble with these downloads, try changing to a different ALMA server (e.g., almascience.nrao.edu->almascience.eso.org) or increase the timeout. See the [download_file](https://docs.astropy.org/en/stable/api/astropy.utils.data.download_file.html) documentation." ] }, { "cell_type": "code", "execution_count": null, - "id": "rapid-prime", "metadata": {}, "outputs": [], "source": [ @@ -85,7 +80,6 @@ { "cell_type": "code", "execution_count": null, - "id": "stuck-thirty", "metadata": {}, "outputs": [], "source": [ @@ -95,7 +89,6 @@ }, { "cell_type": "markdown", - "id": "hearing-meter", "metadata": {}, "source": [ "## Step 2: Load the cubes" @@ -104,7 +97,6 @@ { "cell_type": "code", "execution_count": null, - "id": "brazilian-reward", "metadata": {}, "outputs": [], "source": [ @@ -114,7 +106,6 @@ { "cell_type": "code", "execution_count": null, - "id": "similar-ideal", "metadata": {}, "outputs": [], "source": [ @@ -125,7 +116,6 @@ { "cell_type": "code", "execution_count": null, - "id": "integral-costume", "metadata": {}, "outputs": [], "source": [ @@ -135,7 +125,6 @@ }, { "cell_type": "markdown", - "id": "wound-remark", "metadata": {}, "source": [ "The cubes are at different frequencies - 139 and 89 GHz.\n", @@ -147,7 +136,6 @@ }, { "cell_type": "markdown", - "id": "forty-terminal", "metadata": {}, "source": [ "We use the `find_lines` tool to query [splatalogue](https://splatalogue.online/) with [astroquery](https://astroquery.readthedocs.io/en/latest/splatalogue/splatalogue.html) over the spectral range covered by the cube. It returns a table of matching lines. Note that some line names will be repeated because Splatalogue includes several different databases and most chemical species are present in all of these." @@ -156,7 +144,6 @@ { "cell_type": "code", "execution_count": null, - "id": "proud-flood", "metadata": {}, "outputs": [], "source": [ @@ -166,7 +153,6 @@ { "cell_type": "code", "execution_count": null, - "id": "victorian-society", "metadata": {}, "outputs": [], "source": [ @@ -175,7 +161,6 @@ }, { "cell_type": "markdown", - "id": "proud-engagement", "metadata": {}, "source": [ "## Step 3: Convert cubes from frequency to velocity" @@ -184,7 +169,6 @@ { "cell_type": "code", "execution_count": null, - "id": "finite-saying", "metadata": {}, "outputs": [], "source": [ @@ -194,7 +178,6 @@ { "cell_type": "code", "execution_count": null, - "id": "voluntary-modeling", "metadata": {}, "outputs": [], "source": [ @@ -205,7 +188,6 @@ { "cell_type": "code", "execution_count": null, - "id": "arranged-fault", "metadata": {}, "outputs": [], "source": [ @@ -215,7 +197,6 @@ }, { "cell_type": "markdown", - "id": "false-rainbow", "metadata": {}, "source": [ "From the shape of the cube, we can see the H2CS cube is narrower in velocity, so we'll use that as the target spectral reprojection. However, the SiO cube is the smaller footprint on the sky." @@ -223,7 +204,6 @@ }, { "cell_type": "markdown", - "id": "empty-national", "metadata": {}, "source": [ "### Create spatial maps of the peak intensity to quickly explore the cubes:\n", @@ -234,7 +214,6 @@ { "cell_type": "code", "execution_count": null, - "id": "rural-action", "metadata": {}, "outputs": [], "source": [ @@ -244,7 +223,6 @@ }, { "cell_type": "markdown", - "id": "living-baltimore", "metadata": {}, "source": [ "We can do the same thing all on one line (for the other cube this time):" @@ -253,7 +231,6 @@ { "cell_type": "code", "execution_count": null, - "id": "forty-permit", "metadata": {}, "outputs": [], "source": [ @@ -262,7 +239,6 @@ }, { "cell_type": "markdown", - "id": "ancient-analyst", "metadata": {}, "source": [ "# Step 4. Spectral Interpolation\n", @@ -275,7 +251,6 @@ { "cell_type": "code", "execution_count": null, - "id": "incorrect-producer", "metadata": {}, "outputs": [], "source": [ @@ -286,7 +261,6 @@ }, { "cell_type": "markdown", - "id": "understood-jason", "metadata": {}, "source": [ "Next, we will reduce `cube2vel` to have the same spectral range as `cube1vel`:" @@ -295,7 +269,6 @@ { "cell_type": "code", "execution_count": null, - "id": "gentle-costume", "metadata": {}, "outputs": [], "source": [ @@ -306,7 +279,6 @@ }, { "cell_type": "markdown", - "id": "other-medicare", "metadata": {}, "source": [ "Note that it is important for the to-be-interpolated cube, in this case `cube2`, to have pixels bounding `cube1`'s spectral axis, but in this case it does not. If the pixel range doesn't overlap perfectly, it may blank out one of the edge pixels. So, to fix this, we add a little buffer:" @@ -315,7 +287,6 @@ { "cell_type": "code", "execution_count": null, - "id": "driven-smooth", "metadata": {}, "outputs": [], "source": [ @@ -326,7 +297,6 @@ }, { "cell_type": "markdown", - "id": "treated-encyclopedia", "metadata": {}, "source": [ "Our H2CS cube (`cube1vel`) has broader channels. We need to first smooth `cube2vel` to the broader channel width before doing the spatial reprojection.\n", @@ -341,7 +311,6 @@ { "cell_type": "code", "execution_count": null, - "id": "affecting-lebanon", "metadata": {}, "outputs": [], "source": [ @@ -352,7 +321,6 @@ { "cell_type": "code", "execution_count": null, - "id": "temporal-assembly", "metadata": {}, "outputs": [], "source": [ @@ -364,7 +332,6 @@ }, { "cell_type": "markdown", - "id": "competitive-church", "metadata": {}, "source": [ "We then smooth with the kernel. Note that this is doing 420x420 = 176400 smoothing operations on a length-221 spectrum: it will take a little time" @@ -373,7 +340,6 @@ { "cell_type": "code", "execution_count": null, - "id": "lined-input", "metadata": {}, "outputs": [], "source": [ @@ -382,7 +348,6 @@ }, { "cell_type": "markdown", - "id": "steady-spectacular", "metadata": {}, "source": [ "Now that we've done spectral smoothing, we can resample the spectral axis of `cube2vel_smooth` to match `cube1vel` by interpolating `cube2vel_smooth` onto `cube1vel`'s grid:" @@ -391,7 +356,6 @@ { "cell_type": "code", "execution_count": null, - "id": "pretty-treat", "metadata": {}, "outputs": [], "source": [ @@ -402,7 +366,6 @@ }, { "cell_type": "markdown", - "id": "upset-attendance", "metadata": {}, "source": [ "Note that we included the `suppress_smooth_warning=True` argument. That is to hide this warning:\n", @@ -414,7 +377,6 @@ }, { "cell_type": "markdown", - "id": "judicial-making", "metadata": {}, "source": [ "# Step 5. Spatial Smoothing" @@ -422,7 +384,6 @@ }, { "cell_type": "markdown", - "id": "active-affiliation", "metadata": {}, "source": [ "Now that we've done spectral smoothing, we also need to follow a similar procedure of smoothing then resampling for the spatial axes. \n", @@ -433,7 +394,6 @@ { "cell_type": "code", "execution_count": null, - "id": "military-bangladesh", "metadata": {}, "outputs": [], "source": [ @@ -442,7 +402,6 @@ }, { "cell_type": "markdown", - "id": "qualified-macintosh", "metadata": {}, "source": [ "`cube1` again hase the larger beam, so we'll smooth `cube2` to its resolution" @@ -450,7 +409,6 @@ }, { "cell_type": "markdown", - "id": "breeding-ambassador", "metadata": {}, "source": [ "#### Aside: mixed beams \n", @@ -463,7 +421,6 @@ { "cell_type": "code", "execution_count": null, - "id": "pregnant-account", "metadata": {}, "outputs": [], "source": [ @@ -474,7 +431,6 @@ }, { "cell_type": "markdown", - "id": "different-surface", "metadata": {}, "source": [ "We then convolve:" @@ -483,7 +439,6 @@ { "cell_type": "code", "execution_count": null, - "id": "returning-moses", "metadata": {}, "outputs": [], "source": [ @@ -497,7 +452,6 @@ }, { "cell_type": "markdown", - "id": "indie-wallpaper", "metadata": {}, "source": [ "# Step 6. Reprojection\n", @@ -508,7 +462,6 @@ { "cell_type": "code", "execution_count": null, - "id": "coordinated-nomination", "metadata": {}, "outputs": [], "source": [ @@ -518,7 +471,6 @@ }, { "cell_type": "markdown", - "id": "minimal-conversion", "metadata": {}, "source": [ "These two cubes are now on an identical grid, and can be directly compared:" @@ -527,7 +479,6 @@ { "cell_type": "code", "execution_count": null, - "id": "worse-company", "metadata": {}, "outputs": [], "source": [ @@ -536,7 +487,6 @@ }, { "cell_type": "markdown", - "id": "liberal-absorption", "metadata": {}, "source": [ "These spectra can now be overplotted as they are in the same unit with the same beam." @@ -545,7 +495,6 @@ { "cell_type": "code", "execution_count": null, - "id": "precious-creator", "metadata": {}, "outputs": [], "source": [ @@ -555,7 +504,6 @@ }, { "cell_type": "markdown", - "id": "regional-cooperation", "metadata": {}, "source": [ "# Dask\n", @@ -567,7 +515,6 @@ }, { "cell_type": "markdown", - "id": "ambient-audience", "metadata": {}, "source": [ "We repeat all the operations above using dask. We use a `ProgressBar` so you can see how long it takes. We also suppress warnings to make the output look cleaner (we already saw all the important warnings above)." @@ -576,7 +523,6 @@ { "cell_type": "code", "execution_count": null, - "id": "dated-project", "metadata": {}, "outputs": [], "source": [ @@ -587,7 +533,6 @@ { "cell_type": "code", "execution_count": null, - "id": "vertical-breed", "metadata": {}, "outputs": [], "source": [ @@ -610,7 +555,6 @@ { "cell_type": "code", "execution_count": null, - "id": "several-saver", "metadata": {}, "outputs": [], "source": [] @@ -632,7 +576,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.2" + "version": "3.7.3" } }, "nbformat": 4, From 1d3b16976ba8f74cfb4c65915958b63666e490bc Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Wed, 29 Dec 2021 19:09:45 -0500 Subject: [PATCH 04/11] correct frequency --- .../SpectralCubeReprojectExample.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb index 2ce150af..9c99d7f6 100644 --- a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb +++ b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb @@ -127,7 +127,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The cubes are at different frequencies - 139 and 89 GHz.\n", + "The cubes are at different frequencies - 139 and 217 GHz.\n", "\n", "The first cube covers the H2CS 4(1,3)-3(1,2) line at 139.483699\tGHz.\n", "\n", From 4ac02da7f72ff16df976d12e48e5d0bfbf9957dc Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Tue, 18 Jan 2022 09:04:08 -0500 Subject: [PATCH 05/11] remove kernel spec --- .../SpectralCubeReprojectExample.ipynb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb index 9c99d7f6..fc256a69 100644 --- a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb +++ b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb @@ -561,11 +561,6 @@ } ], "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, "language_info": { "codemirror_mode": { "name": "ipython", From bb6dc8b15c7a526210a898769e1282f35658d113 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 20 Jan 2022 15:55:28 +0000 Subject: [PATCH 06/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../SpectralCubeReprojectExample.ipynb | 60 ++++++++++++++++++- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb index fc256a69..ee8c452d 100644 --- a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb +++ b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb @@ -2,6 +2,7 @@ "cells": [ { "cell_type": "markdown", + "id": "b6372d7e", "metadata": {}, "source": [ "# Cube Reprojection Tutorial\n", @@ -23,6 +24,7 @@ }, { "cell_type": "markdown", + "id": "70381c49", "metadata": {}, "source": [ "## Index \n", @@ -40,6 +42,7 @@ }, { "cell_type": "markdown", + "id": "48448b34", "metadata": {}, "source": [ "## Step 1: Download the data\n", @@ -50,6 +53,7 @@ { "cell_type": "code", "execution_count": null, + "id": "32902371", "metadata": {}, "outputs": [], "source": [ @@ -59,6 +63,7 @@ }, { "cell_type": "markdown", + "id": "4dec821a", "metadata": {}, "source": [ "We download two example spectral cubes of a point in the Galactic center from a permalink on the ALMA archives.\n", @@ -70,6 +75,7 @@ { "cell_type": "code", "execution_count": null, + "id": "9719f71a", "metadata": {}, "outputs": [], "source": [ @@ -80,6 +86,7 @@ { "cell_type": "code", "execution_count": null, + "id": "2a1d4dc7", "metadata": {}, "outputs": [], "source": [ @@ -89,6 +96,7 @@ }, { "cell_type": "markdown", + "id": "d801b283", "metadata": {}, "source": [ "## Step 2: Load the cubes" @@ -97,6 +105,7 @@ { "cell_type": "code", "execution_count": null, + "id": "fe4ead93", "metadata": {}, "outputs": [], "source": [ @@ -106,6 +115,7 @@ { "cell_type": "code", "execution_count": null, + "id": "833abd53", "metadata": {}, "outputs": [], "source": [ @@ -116,6 +126,7 @@ { "cell_type": "code", "execution_count": null, + "id": "04b8ddcd", "metadata": {}, "outputs": [], "source": [ @@ -125,6 +136,7 @@ }, { "cell_type": "markdown", + "id": "19595c31", "metadata": {}, "source": [ "The cubes are at different frequencies - 139 and 217 GHz.\n", @@ -136,6 +148,7 @@ }, { "cell_type": "markdown", + "id": "ccc5334f", "metadata": {}, "source": [ "We use the `find_lines` tool to query [splatalogue](https://splatalogue.online/) with [astroquery](https://astroquery.readthedocs.io/en/latest/splatalogue/splatalogue.html) over the spectral range covered by the cube. It returns a table of matching lines. Note that some line names will be repeated because Splatalogue includes several different databases and most chemical species are present in all of these." @@ -144,6 +157,7 @@ { "cell_type": "code", "execution_count": null, + "id": "fdf8959f", "metadata": {}, "outputs": [], "source": [ @@ -153,6 +167,7 @@ { "cell_type": "code", "execution_count": null, + "id": "ba4fbb6a", "metadata": {}, "outputs": [], "source": [ @@ -161,6 +176,7 @@ }, { "cell_type": "markdown", + "id": "8c7234cb", "metadata": {}, "source": [ "## Step 3: Convert cubes from frequency to velocity" @@ -169,6 +185,7 @@ { "cell_type": "code", "execution_count": null, + "id": "9b59615f", "metadata": {}, "outputs": [], "source": [ @@ -178,6 +195,7 @@ { "cell_type": "code", "execution_count": null, + "id": "86aa822b", "metadata": {}, "outputs": [], "source": [ @@ -188,6 +206,7 @@ { "cell_type": "code", "execution_count": null, + "id": "a1544293", "metadata": {}, "outputs": [], "source": [ @@ -197,6 +216,7 @@ }, { "cell_type": "markdown", + "id": "11e7873f", "metadata": {}, "source": [ "From the shape of the cube, we can see the H2CS cube is narrower in velocity, so we'll use that as the target spectral reprojection. However, the SiO cube is the smaller footprint on the sky." @@ -204,6 +224,7 @@ }, { "cell_type": "markdown", + "id": "cc6f783c", "metadata": {}, "source": [ "### Create spatial maps of the peak intensity to quickly explore the cubes:\n", @@ -214,6 +235,7 @@ { "cell_type": "code", "execution_count": null, + "id": "bb078eb0", "metadata": {}, "outputs": [], "source": [ @@ -223,6 +245,7 @@ }, { "cell_type": "markdown", + "id": "b8e96d66", "metadata": {}, "source": [ "We can do the same thing all on one line (for the other cube this time):" @@ -231,6 +254,7 @@ { "cell_type": "code", "execution_count": null, + "id": "8b035a79", "metadata": {}, "outputs": [], "source": [ @@ -239,6 +263,7 @@ }, { "cell_type": "markdown", + "id": "98ecf111", "metadata": {}, "source": [ "# Step 4. Spectral Interpolation\n", @@ -251,6 +276,7 @@ { "cell_type": "code", "execution_count": null, + "id": "e19188f0", "metadata": {}, "outputs": [], "source": [ @@ -261,6 +287,7 @@ }, { "cell_type": "markdown", + "id": "007fac49", "metadata": {}, "source": [ "Next, we will reduce `cube2vel` to have the same spectral range as `cube1vel`:" @@ -269,6 +296,7 @@ { "cell_type": "code", "execution_count": null, + "id": "cee190fc", "metadata": {}, "outputs": [], "source": [ @@ -279,6 +307,7 @@ }, { "cell_type": "markdown", + "id": "385b7042", "metadata": {}, "source": [ "Note that it is important for the to-be-interpolated cube, in this case `cube2`, to have pixels bounding `cube1`'s spectral axis, but in this case it does not. If the pixel range doesn't overlap perfectly, it may blank out one of the edge pixels. So, to fix this, we add a little buffer:" @@ -287,6 +316,7 @@ { "cell_type": "code", "execution_count": null, + "id": "653d7199", "metadata": {}, "outputs": [], "source": [ @@ -297,6 +327,7 @@ }, { "cell_type": "markdown", + "id": "c5a0e750", "metadata": {}, "source": [ "Our H2CS cube (`cube1vel`) has broader channels. We need to first smooth `cube2vel` to the broader channel width before doing the spatial reprojection.\n", @@ -311,6 +342,7 @@ { "cell_type": "code", "execution_count": null, + "id": "c86d7716", "metadata": {}, "outputs": [], "source": [ @@ -321,6 +353,7 @@ { "cell_type": "code", "execution_count": null, + "id": "35acafb7", "metadata": {}, "outputs": [], "source": [ @@ -332,6 +365,7 @@ }, { "cell_type": "markdown", + "id": "ffdd178a", "metadata": {}, "source": [ "We then smooth with the kernel. Note that this is doing 420x420 = 176400 smoothing operations on a length-221 spectrum: it will take a little time" @@ -340,6 +374,7 @@ { "cell_type": "code", "execution_count": null, + "id": "86ada2d7", "metadata": {}, "outputs": [], "source": [ @@ -348,6 +383,7 @@ }, { "cell_type": "markdown", + "id": "00f6d313", "metadata": {}, "source": [ "Now that we've done spectral smoothing, we can resample the spectral axis of `cube2vel_smooth` to match `cube1vel` by interpolating `cube2vel_smooth` onto `cube1vel`'s grid:" @@ -356,6 +392,7 @@ { "cell_type": "code", "execution_count": null, + "id": "7655a346", "metadata": {}, "outputs": [], "source": [ @@ -366,6 +403,7 @@ }, { "cell_type": "markdown", + "id": "2eda47cf", "metadata": {}, "source": [ "Note that we included the `suppress_smooth_warning=True` argument. That is to hide this warning:\n", @@ -377,6 +415,7 @@ }, { "cell_type": "markdown", + "id": "00926359", "metadata": {}, "source": [ "# Step 5. Spatial Smoothing" @@ -384,6 +423,7 @@ }, { "cell_type": "markdown", + "id": "14e99bbb", "metadata": {}, "source": [ "Now that we've done spectral smoothing, we also need to follow a similar procedure of smoothing then resampling for the spatial axes. \n", @@ -394,6 +434,7 @@ { "cell_type": "code", "execution_count": null, + "id": "4f0512f4", "metadata": {}, "outputs": [], "source": [ @@ -402,6 +443,7 @@ }, { "cell_type": "markdown", + "id": "c93654ca", "metadata": {}, "source": [ "`cube1` again hase the larger beam, so we'll smooth `cube2` to its resolution" @@ -409,6 +451,7 @@ }, { "cell_type": "markdown", + "id": "e6c4d626", "metadata": {}, "source": [ "#### Aside: mixed beams \n", @@ -421,6 +464,7 @@ { "cell_type": "code", "execution_count": null, + "id": "b3cd31a7", "metadata": {}, "outputs": [], "source": [ @@ -431,6 +475,7 @@ }, { "cell_type": "markdown", + "id": "74ff5976", "metadata": {}, "source": [ "We then convolve:" @@ -439,6 +484,7 @@ { "cell_type": "code", "execution_count": null, + "id": "eaa9f644", "metadata": {}, "outputs": [], "source": [ @@ -452,6 +498,7 @@ }, { "cell_type": "markdown", + "id": "cdc73378", "metadata": {}, "source": [ "# Step 6. Reprojection\n", @@ -462,6 +509,7 @@ { "cell_type": "code", "execution_count": null, + "id": "de8b8a48", "metadata": {}, "outputs": [], "source": [ @@ -471,6 +519,7 @@ }, { "cell_type": "markdown", + "id": "69d8a90b", "metadata": {}, "source": [ "These two cubes are now on an identical grid, and can be directly compared:" @@ -479,6 +528,7 @@ { "cell_type": "code", "execution_count": null, + "id": "5bd3de8d", "metadata": {}, "outputs": [], "source": [ @@ -487,6 +537,7 @@ }, { "cell_type": "markdown", + "id": "8cf176f3", "metadata": {}, "source": [ "These spectra can now be overplotted as they are in the same unit with the same beam." @@ -495,6 +546,7 @@ { "cell_type": "code", "execution_count": null, + "id": "a196eb8b", "metadata": {}, "outputs": [], "source": [ @@ -504,6 +556,7 @@ }, { "cell_type": "markdown", + "id": "13afd6f7", "metadata": {}, "source": [ "# Dask\n", @@ -515,6 +568,7 @@ }, { "cell_type": "markdown", + "id": "0934aa4b", "metadata": {}, "source": [ "We repeat all the operations above using dask. We use a `ProgressBar` so you can see how long it takes. We also suppress warnings to make the output look cleaner (we already saw all the important warnings above)." @@ -523,6 +577,7 @@ { "cell_type": "code", "execution_count": null, + "id": "03e1a267", "metadata": {}, "outputs": [], "source": [ @@ -533,6 +588,7 @@ { "cell_type": "code", "execution_count": null, + "id": "14d47820", "metadata": {}, "outputs": [], "source": [ @@ -555,6 +611,7 @@ { "cell_type": "code", "execution_count": null, + "id": "4af66ead", "metadata": {}, "outputs": [], "source": [] @@ -570,8 +627,7 @@ "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" + "pygments_lexer": "ipython3" } }, "nbformat": 4, From 94371c4ca8a4fdbcdf8d606ba206e9a4b4c99188 Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Thu, 27 Jan 2022 10:44:19 -0500 Subject: [PATCH 07/11] add more descriptive text --- .../SpectralCubeReprojectExample.ipynb | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb index ee8c452d..8742d7dd 100644 --- a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb +++ b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb @@ -19,7 +19,14 @@ "spectral cube, radio astronomy, astroquery, units, dask\n", "\n", "## Summary\n", - "This tutorial shows how to take two spectral cubes observed toward the same part of the sky, but different frequencies, and put them onto the same grid using [spectral-cube](spectral-cube.readthedocs.io). It uses [astroquery](https://astroquery.readthedocs.io/) to obtain line frequencies from [splatalogue](https://astroquery.readthedocs.io/en/latest/splatalogue/splatalogue.html). Finally, it shows how to do the reprojection using [dask](https://dask.org) to enable parallelization." + "Spectroscopic cube observations taken at different wavelength can trace the motion of gas or stars using spectral lines, but often lines at different wavelengths give different information.\n", + "For example, one might observe a galaxy in the 21cm line of HI and the 115 GHz line of CO, or a protoplanetary disk in a line of N2H+ and a line of CO, or a galactic disk in the H-alpha and H-beta lines (in absorption or emission).\n", + "In order to compare these data sets pixel-by-pixel, they must be placed onto a common grid with common resolution.\n", + "\n", + "This tutorial shows how to take two spectral cubes observed toward the same part of the sky, but different frequencies, and put them onto the same grid using [spectral-cube](spectral-cube.readthedocs.io).\n", + "\n", + "It uses [astroquery](https://astroquery.readthedocs.io/) to obtain line frequencies from [splatalogue](https://astroquery.readthedocs.io/en/latest/splatalogue/splatalogue.html); this example uses radio-wavelength data for which Splatalogue's molecular line lists are appropriate.\n", + "Finally, it shows how to do the reprojection using [dask](https://dask.org) to enable parallelization." ] }, { @@ -179,7 +186,9 @@ "id": "8c7234cb", "metadata": {}, "source": [ - "## Step 3: Convert cubes from frequency to velocity" + "## Step 3: Convert cubes from frequency to velocity\n", + "\n", + "To compare the kinematic structure of the target, we need to convert from the observed frequency (which must be in a common reference frame; in this case, it already is) to the doppler velocity." ] }, { @@ -268,7 +277,8 @@ "source": [ "# Step 4. Spectral Interpolation\n", "\n", - "We can do the spatial or spectral step first. In this case, we choose the spectral step first because the H$_2$CS cube is narrower in velocity (`cube1vel`) and this will reduce the number of channels we need to spatially interpolate over in the next step.\n", + "We can choose to do either the spatial or spectral step first. \n", + "In this case, we choose the spectral step first because the H$_2$CS cube is narrower in velocity (`cube1vel`) and this will reduce the number of channels we need to spatially interpolate over in the next step.\n", "\n", "We need to match resolution to the cube with the largest channel width:" ] @@ -562,6 +572,7 @@ "# Dask\n", "\n", "All of the above can be done using `dask` as the underlying framework to parallelize the operations.\n", + "See [the spectral-cube documentation on dask integration](https://spectral-cube.readthedocs.io/en/latest/dask.html) or the [dask documentation](https://dask.org/) for further details.\n", "\n", "The dask approach can be made more memory-efficient (avoid using too much RAM) by writing intermediate steps to disk. The non-dask approach used above will generally need to read the whole cube into memory. Depending on the situation, either approach may be faster, but `dask` may be needed if the cube is larger than memory." ] @@ -618,6 +629,11 @@ } ], "metadata": { + "kernelspec": { + "display_name": "Py 3.9", + "language": "python", + "name": "python39" + }, "language_info": { "codemirror_mode": { "name": "ipython", @@ -627,7 +643,8 @@ "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3" + "pygments_lexer": "ipython3", + "version": "3.9.7" } }, "nbformat": 4, From 6287f1df88a75a780457ea8b2a3ac25cf9846db1 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 27 Jan 2022 15:44:41 +0000 Subject: [PATCH 08/11] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../SpectralCubeReprojectExample.ipynb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb index 8742d7dd..5bb0b40d 100644 --- a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb +++ b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb @@ -643,8 +643,7 @@ "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" + "pygments_lexer": "ipython3" } }, "nbformat": 4, From 753578c105952cd81912b14f9841606a763b5a5e Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Thu, 31 Mar 2022 10:18:41 -0400 Subject: [PATCH 09/11] stripped kernelspec --- .../SpectralCubeReprojectExample.ipynb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb index 5bb0b40d..e45da2b5 100644 --- a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb +++ b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb @@ -629,11 +629,6 @@ } ], "metadata": { - "kernelspec": { - "display_name": "Py 3.9", - "language": "python", - "name": "python39" - }, "language_info": { "codemirror_mode": { "name": "ipython", From b7209da33147349cfad3e7eac25e08b776ae24de Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Thu, 31 Mar 2022 11:07:57 -0400 Subject: [PATCH 10/11] change default server to eso --- .../SpectralCubeReprojectExample.ipynb | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb index e45da2b5..38a3dd15 100644 --- a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb +++ b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb @@ -76,7 +76,7 @@ "We download two example spectral cubes of a point in the Galactic center from a permalink on the ALMA archives.\n", "These are moderately large files, with sizes 18 MB and 337 MB.\n", "\n", - "If you have trouble with these downloads, try changing to a different ALMA server (e.g., almascience.nrao.edu->almascience.eso.org) or increase the timeout. See the [download_file](https://docs.astropy.org/en/stable/api/astropy.utils.data.download_file.html) documentation." + "If you have trouble with these downloads, try changing to a different ALMA server (e.g., almascience.eso.org->almascience.nrao.edu) or increase the timeout. See the [download_file](https://docs.astropy.org/en/stable/api/astropy.utils.data.download_file.html) documentation." ] }, { @@ -86,7 +86,7 @@ "metadata": {}, "outputs": [], "source": [ - "filename_1 = download_file(\"https://almascience.nrao.edu/dataPortal/member.uid___A001_X1465_X3a33.BrickMaser_sci.spw71.cube.I.manual.image.pbcor.fits\",\n", + "filename_1 = download_file(\"https://almascience.eso.org/dataPortal/member.uid___A001_X1465_X3a33.BrickMaser_sci.spw71.cube.I.manual.image.pbcor.fits\",\n", " cache=True)" ] }, @@ -97,7 +97,7 @@ "metadata": {}, "outputs": [], "source": [ - "filename_2 = download_file(\"https://almascience.nrao.edu/dataPortal/member.uid___A001_X87d_X141.a_sma1_sci.spw27.cube.I.pbcor.fits\",\n", + "filename_2 = download_file(\"https://almascience.eso.org/dataPortal/member.uid___A001_X87d_X141.a_sma1_sci.spw27.cube.I.pbcor.fits\",\n", " cache=True)" ] }, @@ -629,6 +629,11 @@ } ], "metadata": { + "kernelspec": { + "display_name": "Py 3.9", + "language": "python", + "name": "python39" + }, "language_info": { "codemirror_mode": { "name": "ipython", @@ -638,7 +643,8 @@ "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3" + "pygments_lexer": "ipython3", + "version": "3.9.7" } }, "nbformat": 4, From ed453fa9e06e698dce5b7cb32d38175662daa801 Mon Sep 17 00:00:00 2001 From: "Adam Ginsburg (keflavich)" Date: Thu, 31 Mar 2022 11:08:30 -0400 Subject: [PATCH 11/11] strip kernelspec again --- .../SpectralCubeReprojectExample.ipynb | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb index 38a3dd15..8def15ee 100644 --- a/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb +++ b/tutorials/spectral-cube-reprojection/SpectralCubeReprojectExample.ipynb @@ -629,11 +629,6 @@ } ], "metadata": { - "kernelspec": { - "display_name": "Py 3.9", - "language": "python", - "name": "python39" - }, "language_info": { "codemirror_mode": { "name": "ipython", @@ -643,8 +638,7 @@ "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.7" + "pygments_lexer": "ipython3" } }, "nbformat": 4,