Skip to content

Commit

Permalink
EXP: Load large 4D cube
Browse files Browse the repository at this point in the history
  • Loading branch information
pllim committed Feb 6, 2020
1 parent 6045353 commit c068922
Showing 1 changed file with 260 additions and 0 deletions.
260 changes: 260 additions & 0 deletions example_notebooks/cube_4d.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Reading a 4D Data Cube with Astrowidgets\n",
"\n",
"This is an example of reading a four dimensional data cube using Astrowidgets."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from astropy.nddata import NDData\n",
"from astropy.wcs import WCS\n",
"from ginga.misc.log import get_logger\n",
"from matplotlib import pyplot as plt\n",
"\n",
"import ipywidgets as ipyw\n",
"from IPython.display import display, clear_output\n",
"\n",
"from astrowidgets import ImageWidget\n",
"\n",
"%matplotlib inline\n",
"\n",
"# To prevent automatic figure display when execution of the cell ends\n",
"# https://github.com/jupyter-widgets/ipywidgets/issues/1940\n",
"%config InlineBackend.close_figures=False \n",
"\n",
"plt.ioff()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Subclass `ImageWidget` to implement cube-specific behavior."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class CubeWidget(ImageWidget):\n",
" def __init__(self, *args, **kwargs):\n",
" super().__init__(*args, **kwargs)\n",
" self._4d_idx = 0 # Lock 4th dim to this for now\n",
" self.line_out = ipyw.Output()\n",
" self.line_plot = None\n",
"\n",
" def load_nddata(self, nddata, naxispath=None):\n",
" from ginga.AstroImage import AstroImage\n",
" image = AstroImage()\n",
" image.load_nddata(nddata, naxispath=[0, self._4d_idx])\n",
" self._viewer.set_image(image)\n",
" \n",
" def _mouse_click_cb(self, viewer, event, data_x, data_y):\n",
" super()._mouse_click_cb(viewer, event, data_x, data_y)\n",
" \n",
" # Plot line profile\n",
" image = self._viewer.get_image()\n",
" if image is not None and self.line_plot is not None:\n",
" mddata = image.get_mddata()\n",
" ix = int(round(data_x))\n",
" iy = int(round(data_y))\n",
" with self.line_out:\n",
" self.line_plot.clear()\n",
" self.line_plot.plot(mddata[self._4d_idx, :, iy, ix])\n",
" clear_output(wait=True)\n",
" display(self.line_plot.figure)\n",
"\n",
" def show_slice(self, n):\n",
" image = self._viewer.get_image()\n",
" image.set_naxispath([n, self._4d_idx])\n",
" self._viewer.redraw(whence=0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"logger = get_logger('my viewer', log_stderr=True, log_file=None, level=30)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"w = CubeWidget(logger=logger)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Generate a fake 4D data cube."
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"import numpy as np\n",
"\n",
"pf = None # Not using FITS file pointer\n",
"cube4d = np.random.random((2, 5, 100, 200))\n",
"n_3d = cube4d.shape[1]\n",
"\n",
"# Convert to NDData.\n",
"im = NDData(cube4d, wcs=WCS(naxis=4))\n",
"\n",
"# Loading a fake WCS into widget sometimes gives error. Try reload before giving up.\n",
"w.load_nddata(im)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**--- OR ---**\n",
"\n",
"Load an existing data cube."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import dask.array as da\n",
"from astropy.io import fits\n",
"\n",
"# This is a larger-than-memory cube that is 43GB.\n",
"filename = '/redkeep/dungeons/tess_big_cubes/tess-s0001-1-1-cube.fits'\n",
"pf = fits.open(filename, memmap=True)\n",
"im = da.from_array(pf[1].data, name='mytesscube')\n",
"im = im.T # TESS cube is transposed by ASB\n",
"# Shape now is (2, 1282, 2136, 2078)\n",
"n_3d = im.shape[1]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# This needs https://github.com/ejeschke/ginga/pull/805\n",
"# TODO: Why is it taking so long?\n",
"w.load_array(im)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Create a slider for third dimension."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def show_slice(n):\n",
" w.show_slice(n - 1)\n",
"\n",
"slider = ipyw.interactive(\n",
" show_slice,\n",
" n=ipyw.IntSlider(min=1, max=n_3d, step=1, value=0, continuous_update=False))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Set up the plot and hook to widget."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Semicolon to avoid plot showing here.\n",
"# If plot shows, rerun cell to hide it.\n",
"ax = plt.gca();\n",
"\n",
"w.line_plot = ax"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Display the widgets."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"display(ipyw.HBox([ipyw.VBox([slider, w]), w.line_out]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Close the file pointer, if open."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"if pf is not None:\n",
" pf.close()"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit c068922

Please sign in to comment.